From 1fbb4c3095dd2345a34888cf082370f2f874bd89 Mon Sep 17 00:00:00 2001 From: Aman Khalid Date: Thu, 14 Apr 2022 13:18:52 -0400 Subject: Close #134566: Added settings for terminal tab default color/icon --- src/vs/platform/terminal/common/terminal.ts | 2 ++ .../browser/terminalProfileResolverService.ts | 12 ++++++++++-- .../terminal/common/terminalConfiguration.ts | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 32247de9d60..de83dc8e4ae 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -39,6 +39,8 @@ export const enum TerminalSettingId { DefaultProfileMacOs = 'terminal.integrated.defaultProfile.osx', DefaultProfileWindows = 'terminal.integrated.defaultProfile.windows', UseWslProfiles = 'terminal.integrated.useWslProfiles', + TabsDefaultColor = 'terminal.integrated.tabs.defaultColor', + TabsDefaultIcon = 'terminal.integrated.tabs.defaultIcon', TabsEnabled = 'terminal.integrated.tabs.enabled', TabsEnableAnimation = 'terminal.integrated.tabs.enableAnimation', TabsHideCondition = 'terminal.integrated.tabs.hideCondition', diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts index 0849f6676b2..1554d580f33 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts @@ -16,6 +16,7 @@ import { IShellLaunchConfig, ITerminalProfile, ITerminalProfileObject, TerminalI import { IShellLaunchConfigResolveOptions, ITerminalProfileResolverService, ITerminalProfileService } from 'vs/workbench/contrib/terminal/common/terminal'; import * as path from 'vs/base/common/path'; import { Codicon } from 'vs/base/common/codicons'; +import { getIconRegistry, IIconRegistry } from 'vs/platform/theme/common/iconRegistry'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { debounce } from 'vs/base/common/decorators'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; @@ -51,6 +52,8 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro private _primaryBackendOs: OperatingSystem | undefined; + private readonly _iconRegistry: IIconRegistry = getIconRegistry(); + private _defaultProfileName: string | undefined; get defaultProfileName(): string | undefined { return this._defaultProfileName; } @@ -135,7 +138,10 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro // Verify the icon is valid, and fallback correctly to the generic terminal id if there is // an issue - shellLaunchConfig.icon = this._getCustomIcon(shellLaunchConfig.icon) || this._getCustomIcon(resolvedProfile.icon) || Codicon.terminal; + shellLaunchConfig.icon = this._getCustomIcon(shellLaunchConfig.icon) + || this._getCustomIcon(resolvedProfile.icon) + || this._iconRegistry.getIcon(this._configurationService.getValue(TerminalSettingId.TabsDefaultIcon)) + || Codicon.terminal; // Override the name if specified if (resolvedProfile.overrideName) { @@ -143,7 +149,9 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro } // Apply the color - shellLaunchConfig.color = shellLaunchConfig.color || resolvedProfile.color; + shellLaunchConfig.color = shellLaunchConfig.color + || resolvedProfile.color + || this._configurationService.getValue(TerminalSettingId.TabsDefaultColor); // Resolve useShellEnvironment based on the setting if it's not set if (shellLaunchConfig.useShellEnvironment === undefined) { diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index 4020b3e6fa0..27f5698ddb8 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -9,6 +9,7 @@ import { DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, TerminalCursorStyle, DEFAU import { TerminalLocationString, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; import { isMacintosh, isWindows } from 'vs/base/common/platform'; import { Registry } from 'vs/platform/registry/common/platform'; +import { Codicon } from 'vs/base/common/codicons'; const terminalDescriptors = '\n- ' + [ '`\${cwd}`: ' + localize("cwd", "the terminal's current working directory"), @@ -38,6 +39,27 @@ const terminalConfiguration: IConfigurationNode = { type: 'boolean', default: false }, + [TerminalSettingId.TabsDefaultColor]: { + description: localize('terminal.integrated.tabs.defaultColor', "Controls the terminal tab icon's default color."), + type: 'string', + enum: [ + 'terminal.ansiBlack', + 'terminal.ansiRed', + 'terminal.ansiGreen', + 'terminal.ansiYellow', + 'terminal.ansiBlue', + 'terminal.ansiMagenta', + 'terminal.ansiCyan', + 'terminal.ansiWhite' + ], + default: undefined, + }, + [TerminalSettingId.TabsDefaultIcon]: { + description: localize('terminal.integrated.tabs.defaultIcon', "Controls the terminal tab's default icon."), + type: 'string', + enum: Codicon.getAll().map(icon => icon.id), + default: undefined, + }, [TerminalSettingId.TabsEnabled]: { description: localize('terminal.integrated.tabs.enabled', 'Controls whether terminal tabs display as a list to the side of the terminal. When this is disabled a dropdown will display instead.'), type: 'boolean', -- cgit v1.2.3 From 9a844116484a2427511d6f58b690226e1903239b Mon Sep 17 00:00:00 2001 From: Jerome Lelong Date: Fri, 3 Jun 2022 16:40:11 +0200 Subject: Add word boundary to bracket pair starting or ending with letters --- .../bracketPairsTextModelPart/bracketPairsTree/brackets.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/vs') diff --git a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/brackets.ts b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/brackets.ts index 2673aeacb66..db90a64334e 100644 --- a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/brackets.ts +++ b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/brackets.ts @@ -98,10 +98,16 @@ export class BracketTokens { } function prepareBracketForRegExp(str: string): string { - const escaped = escapeRegExpCharacters(str); - // This bracket pair uses letters like e.g. "begin" - "end" (see https://github.com/microsoft/vscode/issues/132162) - const needsWordBoundaries = (/^[\w ]+$/.test(str)); - return (needsWordBoundaries ? `\\b${escaped}\\b` : escaped); + let escaped = escapeRegExpCharacters(str); + // These bracket pair delimiters start or end with letters + // see https://github.com/microsoft/vscode/issues/132162 https://github.com/microsoft/vscode/issues/150440 + if (/^[\w ]+/.test(str)) { + escaped = `\\b${escaped}`; + } + if (/[\w ]+$/.test(str)) { + escaped = `${escaped}\\b`; + } + return escaped; } export class LanguageAgnosticBracketTokens { -- cgit v1.2.3 From 71c15eac23c7cf2e32b3ed8222c6ac4d35c614ba Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Sat, 11 Jun 2022 20:57:05 -0400 Subject: Fix terminals in editor area not reloading - Closes #140429 - This isn't perfect because it just reopens then without setting the original location, but at least it reloads them. --- src/vs/platform/terminal/common/terminal.ts | 5 ++++ src/vs/platform/terminal/common/terminalProcess.ts | 3 +- src/vs/platform/terminal/node/ptyService.ts | 26 ++++++++++++++-- .../contrib/terminal/browser/terminalService.ts | 35 ++++++++++++++++++++-- .../terminal/common/remoteTerminalChannel.ts | 3 +- .../electron-sandbox/localTerminalBackend.ts | 3 +- 6 files changed, 67 insertions(+), 8 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 91b3244bd3f..a368b53f6c7 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -133,6 +133,9 @@ export interface IRawTerminalInstanceLayoutInfo { relativeSize: number; terminal: T; } +export interface IRawTerminalEditorInstanceLayoutInfo { + terminal: T; +} export type ITerminalInstanceLayoutInfoById = IRawTerminalInstanceLayoutInfo; export type ITerminalInstanceLayoutInfo = IRawTerminalInstanceLayoutInfo; @@ -143,9 +146,11 @@ export interface IRawTerminalTabLayoutInfo { } export type ITerminalTabLayoutInfoById = IRawTerminalTabLayoutInfo; +export type ITerminalEditorInstanceLayoutInfoById = IRawTerminalEditorInstanceLayoutInfo; export interface IRawTerminalsLayoutInfo { tabs: IRawTerminalTabLayoutInfo[]; + editorTerminals: IRawTerminalEditorInstanceLayoutInfo[]; } export interface IPtyHostAttachTarget { diff --git a/src/vs/platform/terminal/common/terminalProcess.ts b/src/vs/platform/terminal/common/terminalProcess.ts index dea87c461a1..d949d919061 100644 --- a/src/vs/platform/terminal/common/terminalProcess.ts +++ b/src/vs/platform/terminal/common/terminalProcess.ts @@ -5,7 +5,7 @@ import { UriComponents } from 'vs/base/common/uri'; import { ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; -import { IFixedTerminalDimensions, IRawTerminalTabLayoutInfo, ITerminalEnvironment, ITerminalTabLayoutInfoById, TerminalIcon, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { IFixedTerminalDimensions, IRawTerminalTabLayoutInfo, ITerminalEnvironment, ITerminalTabLayoutInfoById, ITerminalEditorInstanceLayoutInfoById, TerminalIcon, TitleEventSource } from 'vs/platform/terminal/common/terminal'; export interface ISingleTerminalConfiguration { userValue: T | undefined; @@ -41,6 +41,7 @@ export interface IWorkspaceFolderData { export interface ISetTerminalLayoutInfoArgs { workspaceId: string; tabs: ITerminalTabLayoutInfoById[]; + editorTerminals: ITerminalEditorInstanceLayoutInfoById[]; } export interface IGetTerminalLayoutInfoArgs { diff --git a/src/vs/platform/terminal/node/ptyService.ts b/src/vs/platform/terminal/node/ptyService.ts index 397fee9a493..250c44a2838 100644 --- a/src/vs/platform/terminal/node/ptyService.ts +++ b/src/vs/platform/terminal/node/ptyService.ts @@ -12,7 +12,7 @@ import { URI } from 'vs/base/common/uri'; import { getSystemShell } from 'vs/base/node/shell'; import { ILogService } from 'vs/platform/log/common/log'; import { RequestStore } from 'vs/platform/terminal/common/requestStore'; -import { IProcessDataEvent, IProcessReadyEvent, IPtyService, IRawTerminalInstanceLayoutInfo, IReconnectConstants, IRequestResolveVariablesEvent, IShellLaunchConfig, ITerminalInstanceLayoutInfoById, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalTabLayoutInfoById, TerminalIcon, IProcessProperty, TitleEventSource, ProcessPropertyType, IProcessPropertyMap, IFixedTerminalDimensions, IPersistentTerminalProcessLaunchConfig, ICrossVersionSerializedTerminalState, ISerializedTerminalState, ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal'; +import { IProcessDataEvent, IProcessReadyEvent, IPtyService, IRawTerminalInstanceLayoutInfo, IReconnectConstants, IRequestResolveVariablesEvent, IShellLaunchConfig, ITerminalInstanceLayoutInfoById, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalTabLayoutInfoById, TerminalIcon, IProcessProperty, TitleEventSource, ProcessPropertyType, IProcessPropertyMap, IFixedTerminalDimensions, IPersistentTerminalProcessLaunchConfig, ICrossVersionSerializedTerminalState, ISerializedTerminalState, ITerminalProcessOptions, ITerminalEditorInstanceLayoutInfoById, IRawTerminalEditorInstanceLayoutInfo } from 'vs/platform/terminal/common/terminal'; import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering'; import { escapeNonWindowsPath } from 'vs/platform/terminal/common/terminalEnvironment'; import { Terminal as XtermTerminal } from 'xterm-headless'; @@ -343,8 +343,12 @@ export class PtyService extends Disposable implements IPtyService { if (layout) { const expandedTabs = await Promise.all(layout.tabs.map(async tab => this._expandTerminalTab(tab))); const tabs = expandedTabs.filter(t => t.terminals.length > 0); + const expandedEditors = await Promise.all(layout.editorTerminals.map(async editorTerminal => this._expandTerminalEditorInstance(editorTerminal))); this._logService.trace('ptyService#returnLayoutInfo', tabs); - return { tabs }; + return { + tabs, + editorTerminals: expandedEditors + }; } return undefined; } @@ -379,6 +383,24 @@ export class PtyService extends Disposable implements IPtyService { } } + private async _expandTerminalEditorInstance(t: ITerminalEditorInstanceLayoutInfoById): Promise> { + try { + const revivedPtyId = this._revivedPtyIdMap.get(t.terminal)?.newId; + const persistentProcessId = revivedPtyId ?? t.terminal; + const persistentProcess = this._throwIfNoPty(persistentProcessId); + const processDetails = persistentProcess && await this._buildProcessDetails(t.terminal, persistentProcess, revivedPtyId !== undefined); + return { + terminal: { ...processDetails, id: persistentProcessId } ?? null + }; + } catch (e) { + this._logService.trace(`Couldn't get layout info, a terminal was probably disconnected`, e.message); + // this will be filtered out and not reconnected + return { + terminal: null + }; + } + } + private async _buildProcessDetails(id: number, persistentProcess: PersistentTerminalProcess, wasRevived: boolean = false): Promise { // If the process was just revived, don't do the orphan check as it will // take some time diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 62d52e82cc9..4bb83addb42 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -403,8 +403,18 @@ export class TerminalService implements ITerminalService { return; } const layoutInfo = await localBackend.getTerminalLayoutInfo(); - if (layoutInfo && layoutInfo.tabs.length > 0) { - await this._recreateTerminalGroups(layoutInfo); + if (layoutInfo) { + if (layoutInfo.tabs.length > 0) { + await this._recreateTerminalGroups(layoutInfo); + } + if (layoutInfo.editorTerminals && layoutInfo.editorTerminals.length > 0) { + for (const editorTerminal of layoutInfo.editorTerminals) { + await this.createTerminal({ + config: { attachPersistentProcess: editorTerminal.terminal! }, + location: TerminalLocation.Editor + }); + } + } } // now that terminals have been restored, // attach listeners to update local state when terminals are changed @@ -642,7 +652,26 @@ export class TerminalService implements ITerminalService { return; } const tabs = this._terminalGroupService.groups.map(g => g.getLayoutInfo(g === this._terminalGroupService.activeGroup)); - const state: ITerminalsLayoutInfoById = { tabs }; + + // Save terminals in editors too + const seenPersistentProcessIds: number[] = []; + for (const t of tabs) { + for (const term of t.terminals) { + seenPersistentProcessIds.push(term.terminal); + } + } + const otherInstances = this.instances.filter(instance => typeof instance.persistentProcessId === 'number' && instance.shouldPersist && seenPersistentProcessIds.indexOf(instance.persistentProcessId) === -1); + const editorTerminals = otherInstances.map((instance) => { + instance. + return { + terminal: instance.persistentProcessId || 0 + }; + }); + + const state: ITerminalsLayoutInfoById = { + tabs, + editorTerminals + }; this._primaryBackend?.setTerminalLayoutInfo(state); } diff --git a/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts b/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts index e8c7da68932..a41a5f89716 100644 --- a/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts +++ b/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts @@ -266,7 +266,8 @@ export class RemoteTerminalChannelClient implements IPtyHostController { const workspace = this._workspaceContextService.getWorkspace(); const args: ISetTerminalLayoutInfoArgs = { workspaceId: workspace.id, - tabs: layout ? layout.tabs : [] + tabs: layout ? layout.tabs : [], + editorTerminals: layout ? layout.editorTerminals : [] }; return this._channel.call('$setTerminalLayoutInfo', args); } diff --git a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts index b2f01c3e853..e423da8a59f 100644 --- a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts @@ -199,7 +199,8 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke async setTerminalLayoutInfo(layoutInfo?: ITerminalsLayoutInfoById): Promise { const args: ISetTerminalLayoutInfoArgs = { workspaceId: this._getWorkspaceId(), - tabs: layoutInfo ? layoutInfo.tabs : [] + tabs: layoutInfo ? layoutInfo.tabs : [], + editorTerminals: layoutInfo ? layoutInfo.editorTerminals : [] }; await this._localPtyService.setTerminalLayoutInfo(args); // Store in the storage service as well to be used when reviving processes as normally this -- cgit v1.2.3 From f33aeb876f2acd410693ccd241b667ce4173fd09 Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Sat, 11 Jun 2022 21:07:33 -0400 Subject: Fix accidental line of code --- src/vs/workbench/contrib/terminal/browser/terminalService.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 4bb83addb42..e8b200aa2f1 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -662,8 +662,7 @@ export class TerminalService implements ITerminalService { } const otherInstances = this.instances.filter(instance => typeof instance.persistentProcessId === 'number' && instance.shouldPersist && seenPersistentProcessIds.indexOf(instance.persistentProcessId) === -1); const editorTerminals = otherInstances.map((instance) => { - instance. - return { + return { terminal: instance.persistentProcessId || 0 }; }); -- cgit v1.2.3 From dda67a9626ebc385dd2f9ff6a649d2dd6d3df299 Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Mon, 13 Jun 2022 23:17:05 -0400 Subject: Fix suggestion widget hanging. Closes #152010 --- src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts b/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts index fc4a44920ed..bfea6618d0d 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts @@ -173,7 +173,7 @@ export class SuggestDetailsWidget { const renderedContents = this._markdownRenderer.render(documentation); this._docs.appendChild(renderedContents.element); this._renderDisposeable.add(renderedContents); - this._renderDisposeable.add(this._markdownRenderer.onDidRenderAsync(() => { + this._renderDisposeable.add(Event.debounce(this._markdownRenderer.onDidRenderAsync, () => (last: Event, event: Event) => event, 50)(() => { this.layout(this._size.width, this._type.clientHeight + this._docs.clientHeight); this._onDidChangeContents.fire(this); })); -- cgit v1.2.3 From f1008c80bbcc9a170f0686c12eaa8da9c4d91504 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 14 Jun 2022 21:54:33 -0700 Subject: fix imports --- src/vs/platform/terminal/common/terminalProcess.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminalProcess.ts b/src/vs/platform/terminal/common/terminalProcess.ts index 09ae38589cf..980c345a6bd 100644 --- a/src/vs/platform/terminal/common/terminalProcess.ts +++ b/src/vs/platform/terminal/common/terminalProcess.ts @@ -5,9 +5,7 @@ import { UriComponents } from 'vs/base/common/uri'; import { ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; -import { IFixedTerminalDimensions, IRawTerminalTabLayoutInfo, ITerminalEnvironment, ITerminalTabLayoutInfoById, ITerminalEditorInstanceLayoutInfoById, TerminalIcon, TitleEventSource } from 'vs/platform/terminal/common/terminal'; -import { ISerializableEnvironmentVariableCollection, ISerializableEnvironmentVariableCollections } from 'vs/platform/terminal/common/environmentVariable'; -import { IFixedTerminalDimensions, IRawTerminalTabLayoutInfo, ITerminalEnvironment, ITerminalTabLayoutInfoById, TerminalIcon, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { IFixedTerminalDimensions, IRawTerminalTabLayoutInfo, ITerminalEditorInstanceLayoutInfoById, ITerminalEnvironment, ITerminalTabLayoutInfoById, TerminalIcon, TitleEventSource } from 'vs/platform/terminal/common/terminal'; export interface ISingleTerminalConfiguration { userValue: T | undefined; @@ -62,7 +60,7 @@ export interface IProcessDetails { icon: TerminalIcon | undefined; color: string | undefined; fixedDimensions: IFixedTerminalDimensions | undefined; - environmentVariableCollections: ISerializableEnvironmentVariableCollections | undefined; + environmentVariableCollections: ISerializableEnvironmentVariableCollection | undefined; } export type ITerminalTabLayoutInfoDto = IRawTerminalTabLayoutInfo; -- cgit v1.2.3 From a084f63f4d3e5477efbcd8851008e8d996a45681 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 15 Jun 2022 10:17:53 -0700 Subject: fix issues --- src/vs/platform/terminal/common/terminalProcess.ts | 4 ++-- src/vs/workbench/contrib/terminal/browser/terminalService.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminalProcess.ts b/src/vs/platform/terminal/common/terminalProcess.ts index 980c345a6bd..fa7e3252db1 100644 --- a/src/vs/platform/terminal/common/terminalProcess.ts +++ b/src/vs/platform/terminal/common/terminalProcess.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { UriComponents } from 'vs/base/common/uri'; -import { ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; +import { ISerializableEnvironmentVariableCollection, ISerializableEnvironmentVariableCollections } from 'vs/platform/terminal/common/environmentVariable'; import { IFixedTerminalDimensions, IRawTerminalTabLayoutInfo, ITerminalEditorInstanceLayoutInfoById, ITerminalEnvironment, ITerminalTabLayoutInfoById, TerminalIcon, TitleEventSource } from 'vs/platform/terminal/common/terminal'; export interface ISingleTerminalConfiguration { @@ -60,7 +60,7 @@ export interface IProcessDetails { icon: TerminalIcon | undefined; color: string | undefined; fixedDimensions: IFixedTerminalDimensions | undefined; - environmentVariableCollections: ISerializableEnvironmentVariableCollection | undefined; + environmentVariableCollections: ISerializableEnvironmentVariableCollections | undefined; } export type ITerminalTabLayoutInfoDto = IRawTerminalTabLayoutInfo; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index f9ba263232c..02072ae283c 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -21,6 +21,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { ILogService } from 'vs/platform/log/common/log'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { ICreateContributedTerminalProfileOptions, IShellLaunchConfig, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalLocation, TerminalLocationString, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { formatMessageForTerminal } from 'vs/platform/terminal/common/terminalStrings'; import { iconForeground } from 'vs/platform/theme/common/colorRegistry'; import { getIconRegistry } from 'vs/platform/theme/common/iconRegistry'; import { ColorScheme } from 'vs/platform/theme/common/theme'; @@ -38,7 +39,6 @@ import { getInstanceFromResource, getTerminalUri, parseTerminalUri } from 'vs/wo import { TerminalViewPane } from 'vs/workbench/contrib/terminal/browser/terminalView'; import { IRemoteTerminalAttachTarget, IStartExtensionTerminalRequest, ITerminalBackend, ITerminalConfigHelper, ITerminalProcessExtHostProxy, ITerminalProfileService, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; -import { formatMessageForTerminal } from 'vs/platform/terminal/common/terminalStrings'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { ACTIVE_GROUP, IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; -- cgit v1.2.3 From 399a12432e975960ed528cb89ea6a8ef87b1fd79 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 16 Jun 2022 08:40:21 -0700 Subject: Remove [Unsupported] annotation from title bar We now rely on Help > About and issue reporter to call out unsupported builds, the title bar is just a nuisance to users now. Fixes #151104 --- src/vs/workbench/browser/parts/titlebar/windowTitle.ts | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/browser/parts/titlebar/windowTitle.ts b/src/vs/workbench/browser/parts/titlebar/windowTitle.ts index 5f5e16ead26..9e9922b840a 100644 --- a/src/vs/workbench/browser/parts/titlebar/windowTitle.ts +++ b/src/vs/workbench/browser/parts/titlebar/windowTitle.ts @@ -27,7 +27,6 @@ import { getVirtualWorkspaceLocation } from 'vs/platform/workspace/common/virtua export class WindowTitle extends Disposable { - private static readonly NLS_UNSUPPORTED = localize('patchedWindowTitle', "[Unsupported]"); private static readonly NLS_USER_IS_ADMIN = isWindows ? localize('userIsAdmin', "[Administrator]") : localize('userIsSudo', "[Superuser]"); private static readonly NLS_EXTENSION_HOST = localize('devExtensionWindowTitlePrefix', "[Extension Development Host]"); private static readonly TITLE_DIRTY = '\u25cf '; @@ -137,11 +136,6 @@ export class WindowTitle extends Disposable { if (this.properties.isAdmin) { suffix = WindowTitle.NLS_USER_IS_ADMIN; } - if (!this.properties.isPure) { - suffix = !suffix - ? WindowTitle.NLS_UNSUPPORTED - : `${suffix} ${WindowTitle.NLS_UNSUPPORTED}`; - } return { prefix, suffix }; } -- cgit v1.2.3 From bc7344685d7213a16a1a0c43d8287d824692c4ae Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 17 Jun 2022 08:51:28 -0700 Subject: check length of editor terminals --- .../contrib/terminal/browser/terminalEditorService.ts | 2 ++ .../contrib/terminal/browser/terminalService.ts | 16 ++++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts index aec68ee5d91..5a501adebd2 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts @@ -93,6 +93,7 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor // Remove the terminal from the managed instances when the editor closes. This fires when // dragging and dropping to another editor or closing the editor via cmd/ctrl+w. this._register(this._editorService.onDidCloseEditor(e => { + console.log('closed editor'); const instance = e.editor instanceof TerminalEditorInput ? e.editor.terminalInstance : undefined; if (instance) { const instanceIndex = this.instances.findIndex(e => e === instance); @@ -100,6 +101,7 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor this.instances.splice(instanceIndex, 1); } } + console.log(this.instances); })); this._register(this._editorService.onDidActiveEditorChange(() => { const instance = this._editorService.activeEditor instanceof TerminalEditorInput ? this._editorService.activeEditor : undefined; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 02072ae283c..4d1220d4375 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -407,12 +407,16 @@ export class TerminalService implements ITerminalService { if (layoutInfo.tabs.length > 0) { await this._recreateTerminalGroups(layoutInfo); } - if (layoutInfo.editorTerminals && layoutInfo.editorTerminals.length > 0) { - for (const editorTerminal of layoutInfo.editorTerminals) { - await this.createTerminal({ - config: { attachPersistentProcess: editorTerminal.terminal! }, - location: TerminalLocation.Editor - }); + if (this._terminalEditorService.instances.length === 0) { + // only do this for restart because editor terminals are already restored + // on reload + if (layoutInfo.editorTerminals && layoutInfo.editorTerminals.length > 0) { + for (const editorTerminal of layoutInfo.editorTerminals) { + await this.createTerminal({ + config: { attachPersistentProcess: editorTerminal.terminal! }, + location: TerminalLocation.Editor + }); + } } } } -- cgit v1.2.3 From 7aa326e2d7a802cb8622842309e10196ce228b53 Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Sat, 18 Jun 2022 15:26:59 -0400 Subject: Get info from terminal editor - The issue is `_onWillShutdown` is called before `TerminalInputSerializer` serializes, so I added `shutdownPersistentProcessId`. - When restoring the editor, it was using the wrong ID, so I added `getRevivedPtyNewId`. --- src/vs/platform/terminal/common/terminal.ts | 8 ++--- src/vs/platform/terminal/common/terminalProcess.ts | 3 +- src/vs/platform/terminal/node/ptyHostService.ts | 4 +++ src/vs/platform/terminal/node/ptyService.ts | 34 ++++++------------ src/vs/server/node/remoteTerminalChannel.ts | 1 + .../terminal/browser/remoteTerminalBackend.ts | 17 +++++++++ .../workbench/contrib/terminal/browser/terminal.ts | 5 +++ .../terminal/browser/terminalEditorService.ts | 3 +- .../contrib/terminal/browser/terminalInstance.ts | 8 +++-- .../terminal/browser/terminalProcessManager.ts | 2 +- .../contrib/terminal/browser/terminalService.ts | 41 +++++----------------- .../terminal/common/remoteTerminalChannel.ts | 7 ++-- .../workbench/contrib/terminal/common/terminal.ts | 1 + .../electron-sandbox/localTerminalBackend.ts | 16 +++++++-- 14 files changed, 78 insertions(+), 72 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index fefc6dfe936..4bd9644b0b1 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -134,9 +134,6 @@ export interface IRawTerminalInstanceLayoutInfo { relativeSize: number; terminal: T; } -export interface IRawTerminalEditorInstanceLayoutInfo { - terminal: T; -} export type ITerminalInstanceLayoutInfoById = IRawTerminalInstanceLayoutInfo; export type ITerminalInstanceLayoutInfo = IRawTerminalInstanceLayoutInfo; @@ -147,11 +144,9 @@ export interface IRawTerminalTabLayoutInfo { } export type ITerminalTabLayoutInfoById = IRawTerminalTabLayoutInfo; -export type ITerminalEditorInstanceLayoutInfoById = IRawTerminalEditorInstanceLayoutInfo; export interface IRawTerminalsLayoutInfo { tabs: IRawTerminalTabLayoutInfo[]; - editorTerminals: IRawTerminalEditorInstanceLayoutInfo[]; } export interface IPtyHostAttachTarget { @@ -317,6 +312,7 @@ export interface IPtyService extends IPtyHostController { getProfiles?(workspaceId: string, profiles: unknown, defaultProfile: unknown, includeDetectedProfiles?: boolean): Promise; getEnvironment(): Promise; getWslPath(original: string): Promise; + getRevivedPtyNewId(id: number): Promise; setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): Promise; getTerminalLayoutInfo(args: IGetTerminalLayoutInfoArgs): Promise; reduceConnectionGraceTime(): Promise; @@ -463,7 +459,7 @@ export interface IShellLaunchConfig { /** * This is a terminal that attaches to an already running terminal. */ - attachPersistentProcess?: { id: number; pid: number; title: string; titleSource: TitleEventSource; cwd: string; icon?: TerminalIcon; color?: string; hasChildProcesses?: boolean; fixedDimensions?: IFixedTerminalDimensions; environmentVariableCollections?: ISerializableEnvironmentVariableCollections }; + attachPersistentProcess?: { id: number; findRevivedId?: boolean; pid: number; title: string; titleSource: TitleEventSource; cwd: string; icon?: TerminalIcon; color?: string; hasChildProcesses?: boolean; fixedDimensions?: IFixedTerminalDimensions; environmentVariableCollections?: ISerializableEnvironmentVariableCollections }; /** * Whether the terminal process environment should be exactly as provided in diff --git a/src/vs/platform/terminal/common/terminalProcess.ts b/src/vs/platform/terminal/common/terminalProcess.ts index fa7e3252db1..f89a48394a5 100644 --- a/src/vs/platform/terminal/common/terminalProcess.ts +++ b/src/vs/platform/terminal/common/terminalProcess.ts @@ -5,7 +5,7 @@ import { UriComponents } from 'vs/base/common/uri'; import { ISerializableEnvironmentVariableCollection, ISerializableEnvironmentVariableCollections } from 'vs/platform/terminal/common/environmentVariable'; -import { IFixedTerminalDimensions, IRawTerminalTabLayoutInfo, ITerminalEditorInstanceLayoutInfoById, ITerminalEnvironment, ITerminalTabLayoutInfoById, TerminalIcon, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { IFixedTerminalDimensions, IRawTerminalTabLayoutInfo, ITerminalEnvironment, ITerminalTabLayoutInfoById, TerminalIcon, TitleEventSource } from 'vs/platform/terminal/common/terminal'; export interface ISingleTerminalConfiguration { userValue: T | undefined; @@ -41,7 +41,6 @@ export interface IWorkspaceFolderData { export interface ISetTerminalLayoutInfoArgs { workspaceId: string; tabs: ITerminalTabLayoutInfoById[]; - editorTerminals: ITerminalEditorInstanceLayoutInfoById[]; } export interface IGetTerminalLayoutInfoArgs { diff --git a/src/vs/platform/terminal/node/ptyHostService.ts b/src/vs/platform/terminal/node/ptyHostService.ts index b7679d75f90..2f4371ddcef 100644 --- a/src/vs/platform/terminal/node/ptyHostService.ts +++ b/src/vs/platform/terminal/node/ptyHostService.ts @@ -296,6 +296,10 @@ export class PtyHostService extends Disposable implements IPtyService { return this._proxy.getWslPath(original); } + getRevivedPtyNewId(id: number): Promise { + return this._proxy.getRevivedPtyNewId(id); + } + setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): Promise { return this._proxy.setTerminalLayoutInfo(args); } diff --git a/src/vs/platform/terminal/node/ptyService.ts b/src/vs/platform/terminal/node/ptyService.ts index 09341482551..659a2f7f500 100644 --- a/src/vs/platform/terminal/node/ptyService.ts +++ b/src/vs/platform/terminal/node/ptyService.ts @@ -12,7 +12,7 @@ import { URI } from 'vs/base/common/uri'; import { getSystemShell } from 'vs/base/node/shell'; import { ILogService } from 'vs/platform/log/common/log'; import { RequestStore } from 'vs/platform/terminal/common/requestStore'; -import { IProcessDataEvent, IProcessReadyEvent, IPtyService, IRawTerminalInstanceLayoutInfo, IReconnectConstants, IRequestResolveVariablesEvent, IShellLaunchConfig, ITerminalInstanceLayoutInfoById, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalTabLayoutInfoById, TerminalIcon, IProcessProperty, TitleEventSource, ProcessPropertyType, IProcessPropertyMap, IFixedTerminalDimensions, IPersistentTerminalProcessLaunchConfig, ICrossVersionSerializedTerminalState, ISerializedTerminalState, ITerminalProcessOptions, ITerminalEditorInstanceLayoutInfoById, IRawTerminalEditorInstanceLayoutInfo } from 'vs/platform/terminal/common/terminal'; +import { IProcessDataEvent, IProcessReadyEvent, IPtyService, IRawTerminalInstanceLayoutInfo, IReconnectConstants, IRequestResolveVariablesEvent, IShellLaunchConfig, ITerminalInstanceLayoutInfoById, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalTabLayoutInfoById, TerminalIcon, IProcessProperty, TitleEventSource, ProcessPropertyType, IProcessPropertyMap, IFixedTerminalDimensions, IPersistentTerminalProcessLaunchConfig, ICrossVersionSerializedTerminalState, ISerializedTerminalState, ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal'; import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering'; import { escapeNonWindowsPath } from 'vs/platform/terminal/common/terminalEnvironment'; import { Terminal as XtermTerminal } from 'xterm-headless'; @@ -334,21 +334,27 @@ export class PtyService extends Disposable implements IPtyService { }); } + async getRevivedPtyNewId(id: number): Promise { + try { + return this._revivedPtyIdMap.get(id)?.newId; + } catch (e) { + this._logService.trace(`Couldn't find terminal ID ${id}`, e.message); + } + return undefined; + } + async setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): Promise { this._workspaceLayoutInfos.set(args.workspaceId, args); } async getTerminalLayoutInfo(args: IGetTerminalLayoutInfoArgs): Promise { const layout = this._workspaceLayoutInfos.get(args.workspaceId); - this._logService.trace('ptyService#getLayoutInfo', args); if (layout) { const expandedTabs = await Promise.all(layout.tabs.map(async tab => this._expandTerminalTab(tab))); const tabs = expandedTabs.filter(t => t.terminals.length > 0); - const expandedEditors = await Promise.all(layout.editorTerminals.map(async editorTerminal => this._expandTerminalEditorInstance(editorTerminal))); this._logService.trace('ptyService#returnLayoutInfo', tabs); return { - tabs, - editorTerminals: expandedEditors + tabs }; } return undefined; @@ -384,24 +390,6 @@ export class PtyService extends Disposable implements IPtyService { } } - private async _expandTerminalEditorInstance(t: ITerminalEditorInstanceLayoutInfoById): Promise> { - try { - const revivedPtyId = this._revivedPtyIdMap.get(t.terminal)?.newId; - const persistentProcessId = revivedPtyId ?? t.terminal; - const persistentProcess = this._throwIfNoPty(persistentProcessId); - const processDetails = persistentProcess && await this._buildProcessDetails(t.terminal, persistentProcess, revivedPtyId !== undefined); - return { - terminal: { ...processDetails, id: persistentProcessId } ?? null - }; - } catch (e) { - this._logService.trace(`Couldn't get layout info, a terminal was probably disconnected`, e.message); - // this will be filtered out and not reconnected - return { - terminal: null - }; - } - } - private async _buildProcessDetails(id: number, persistentProcess: PersistentTerminalProcess, wasRevived: boolean = false): Promise { // If the process was just revived, don't do the orphan check as it will // take some time diff --git a/src/vs/server/node/remoteTerminalChannel.ts b/src/vs/server/node/remoteTerminalChannel.ts index 5c14bf3006c..96241c74e8c 100644 --- a/src/vs/server/node/remoteTerminalChannel.ts +++ b/src/vs/server/node/remoteTerminalChannel.ts @@ -138,6 +138,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel< case '$setTerminalLayoutInfo': return this._ptyService.setTerminalLayoutInfo(args); case '$serializeTerminalState': return this._ptyService.serializeTerminalState.apply(this._ptyService, args); case '$reviveTerminalProcesses': return this._ptyService.reviveTerminalProcesses.apply(this._ptyService, args); + case '$getRevivedPtyNewId': return this._ptyService.getRevivedPtyNewId.apply(this._ptyService, args); case '$setUnicodeVersion': return this._ptyService.setUnicodeVersion.apply(this._ptyService, args); case '$reduceConnectionGraceTime': return this._reduceConnectionGraceTime(); case '$updateIcon': return this._ptyService.updateIcon.apply(this._ptyService, args); diff --git a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts index dbbcea77cf9..6b304681efd 100644 --- a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts @@ -239,6 +239,23 @@ class RemoteTerminalBackend extends BaseTerminalBackend implements ITerminalBack return undefined; } + async attachToRevivedProcess(id: number): Promise { + if (!this._remoteTerminalChannel) { + throw new Error(`Cannot create remote terminal when there is no remote!`); + } + + try { + const newId = await this._remoteTerminalChannel.getRevivedPtyNewId(id); + if (newId === undefined) { + return undefined; + } + return await this.attachToProcess(newId); + } catch (e) { + this._logService.trace(`Couldn't attach to process ${e.message}`); + } + return undefined; + } + async listProcesses(): Promise { const terms = this._remoteTerminalChannel ? await this._remoteTerminalChannel.listProcesses() : []; return terms.map(termDto => { diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index d11e3359e8a..ecff6314eec 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -470,6 +470,11 @@ export interface ITerminalInstance { */ readonly persistentProcessId: number | undefined; + /** + * The id of a persistent process during the shutdown process + */ + shutdownPersistentProcessId: number | undefined; + /** * Whether the process should be persisted across reloads. */ diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts index 5a501adebd2..5ed91cd6c12 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts @@ -281,7 +281,8 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor const inputKey = resource.path; if ('pid' in deserializedInput) { - const instance = this._terminalInstanceService.createInstance({ attachPersistentProcess: deserializedInput }, TerminalLocation.Editor); + const newDeserializedInput = { ...deserializedInput, findRevivedId: true }; + const instance = this._terminalInstanceService.createInstance({ attachPersistentProcess: newDeserializedInput }, TerminalLocation.Editor); instance.target = TerminalLocation.Editor; const input = this._instantiationService.createInstance(TerminalEditorInput, resource, instance); this._registerInstance(inputKey, input, instance); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 7f9589e2ca3..119ef061d0a 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -150,6 +150,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { private readonly _processManager: ITerminalProcessManager; private readonly _resource: URI; + private _shutdownPersistentProcessId: number | undefined; // Enables disposal of the xterm onKey // event when the CwdDetection capability @@ -654,8 +655,11 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { return TerminalInstance._lastKnownCanvasDimensions; } - get persistentProcessId(): number | undefined { return this._processManager.persistentProcessId; } - get shouldPersist(): boolean { return this._processManager.shouldPersist && !this.shellLaunchConfig.isTransient; } + set shutdownPersistentProcessId(shutdownPersistentProcessId: number | undefined) { + this._shutdownPersistentProcessId = shutdownPersistentProcessId; + } + get persistentProcessId(): number | undefined { return this._processManager.persistentProcessId ?? this._shutdownPersistentProcessId; } + get shouldPersist(): boolean { return (this._processManager.shouldPersist || this._shutdownPersistentProcessId !== undefined) && !this.shellLaunchConfig.isTransient; } /** * Create xterm.js instance and attach data listeners. diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index bba89cdbcee..db29d770391 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -290,7 +290,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce } } else { if (shellLaunchConfig.attachPersistentProcess) { - const result = await backend.attachToProcess(shellLaunchConfig.attachPersistentProcess.id); + const result = shellLaunchConfig.attachPersistentProcess.findRevivedId ? await backend.attachToRevivedProcess(shellLaunchConfig.attachPersistentProcess.id) : await backend.attachToProcess(shellLaunchConfig.attachPersistentProcess.id); if (result) { newProcess = result; } else { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 4d1220d4375..69ec76c20d0 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -403,22 +403,8 @@ export class TerminalService implements ITerminalService { return; } const layoutInfo = await localBackend.getTerminalLayoutInfo(); - if (layoutInfo) { - if (layoutInfo.tabs.length > 0) { - await this._recreateTerminalGroups(layoutInfo); - } - if (this._terminalEditorService.instances.length === 0) { - // only do this for restart because editor terminals are already restored - // on reload - if (layoutInfo.editorTerminals && layoutInfo.editorTerminals.length > 0) { - for (const editorTerminal of layoutInfo.editorTerminals) { - await this.createTerminal({ - config: { attachPersistentProcess: editorTerminal.terminal! }, - location: TerminalLocation.Editor - }); - } - } - } + if (layoutInfo && layoutInfo.tabs.length > 0) { + await this._recreateTerminalGroups(layoutInfo); } // now that terminals have been restored, // attach listeners to update local state when terminals are changed @@ -634,8 +620,13 @@ export class TerminalService implements ITerminalService { return; } + // Force dispose of all terminal instances + const shouldPersistTerminalsForEvent = this._shouldReviveProcesses(e.reason); for (const instance of this.instances) { + if (shouldPersistTerminalsForEvent) { + instance.shutdownPersistentProcessId = instance.persistentProcessId; + } instance.dispose(); } @@ -659,24 +650,8 @@ export class TerminalService implements ITerminalService { return; } const tabs = this._terminalGroupService.groups.map(g => g.getLayoutInfo(g === this._terminalGroupService.activeGroup)); - - // Save terminals in editors too - const seenPersistentProcessIds: number[] = []; - for (const t of tabs) { - for (const term of t.terminals) { - seenPersistentProcessIds.push(term.terminal); - } - } - const otherInstances = this.instances.filter(instance => typeof instance.persistentProcessId === 'number' && instance.shouldPersist && seenPersistentProcessIds.indexOf(instance.persistentProcessId) === -1); - const editorTerminals = otherInstances.map((instance) => { - return { - terminal: instance.persistentProcessId || 0 - }; - }); - const state: ITerminalsLayoutInfoById = { - tabs, - editorTerminals + tabs }; this._primaryBackend?.setTerminalLayoutInfo(state); } diff --git a/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts b/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts index a41a5f89716..1b62d1e9cb3 100644 --- a/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts +++ b/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts @@ -266,8 +266,7 @@ export class RemoteTerminalChannelClient implements IPtyHostController { const workspace = this._workspaceContextService.getWorkspace(); const args: ISetTerminalLayoutInfoArgs = { workspaceId: workspace.id, - tabs: layout ? layout.tabs : [], - editorTerminals: layout ? layout.editorTerminals : [] + tabs: layout ? layout.tabs : [] }; return this._channel.call('$setTerminalLayoutInfo', args); } @@ -300,6 +299,10 @@ export class RemoteTerminalChannelClient implements IPtyHostController { return this._channel.call('$reviveTerminalProcesses', [state, dateTimeFormatLocate]); } + getRevivedPtyNewId(id: number): Promise { + return this._channel.call('$getRevivedPtyNewId', [id]); + } + serializeTerminalState(ids: number[]): Promise { return this._channel.call('$serializeTerminalState', [ids]); } diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 1d3a1aa85db..04b98030a41 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -116,6 +116,7 @@ export interface ITerminalBackend { onDidRequestDetach: Event<{ requestId: number; workspaceId: string; instanceId: number }>; attachToProcess(id: number): Promise; + attachToRevivedProcess(id: number): Promise; listProcesses(): Promise; getDefaultSystemShell(osOverride?: OperatingSystem): Promise; getProfiles(profiles: unknown, defaultProfile: unknown, includeDetectedProfiles?: boolean): Promise; diff --git a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts index e423da8a59f..8b9802f0abc 100644 --- a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts @@ -168,6 +168,19 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke return undefined; } + async attachToRevivedProcess(id: number): Promise { + try { + const newId = await this._localPtyService.getRevivedPtyNewId(id); + if (newId === undefined) { + return undefined; + } + return await this.attachToProcess(newId); + } catch (e) { + this._logService.trace(`Couldn't attach to process ${e.message}`); + } + return undefined; + } + async listProcesses(): Promise { return this._localPtyService.listProcesses(); } @@ -199,8 +212,7 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke async setTerminalLayoutInfo(layoutInfo?: ITerminalsLayoutInfoById): Promise { const args: ISetTerminalLayoutInfoArgs = { workspaceId: this._getWorkspaceId(), - tabs: layoutInfo ? layoutInfo.tabs : [], - editorTerminals: layoutInfo ? layoutInfo.editorTerminals : [] + tabs: layoutInfo ? layoutInfo.tabs : [] }; await this._localPtyService.setTerminalLayoutInfo(args); // Store in the storage service as well to be used when reviving processes as normally this -- cgit v1.2.3 From 1f37af91f0533162174ce784e023af03b6c0d7ed Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Sat, 18 Jun 2022 15:30:19 -0400 Subject: Self review cleanup --- src/vs/platform/terminal/node/ptyService.ts | 5 ++--- src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts | 2 -- src/vs/workbench/contrib/terminal/browser/terminalService.ts | 4 +--- 3 files changed, 3 insertions(+), 8 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/node/ptyService.ts b/src/vs/platform/terminal/node/ptyService.ts index 659a2f7f500..02494098900 100644 --- a/src/vs/platform/terminal/node/ptyService.ts +++ b/src/vs/platform/terminal/node/ptyService.ts @@ -349,13 +349,12 @@ export class PtyService extends Disposable implements IPtyService { async getTerminalLayoutInfo(args: IGetTerminalLayoutInfoArgs): Promise { const layout = this._workspaceLayoutInfos.get(args.workspaceId); + this._logService.trace('ptyService#getLayoutInfo', args); if (layout) { const expandedTabs = await Promise.all(layout.tabs.map(async tab => this._expandTerminalTab(tab))); const tabs = expandedTabs.filter(t => t.terminals.length > 0); this._logService.trace('ptyService#returnLayoutInfo', tabs); - return { - tabs - }; + return { tabs }; } return undefined; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts index 5ed91cd6c12..74b83274dca 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts @@ -93,7 +93,6 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor // Remove the terminal from the managed instances when the editor closes. This fires when // dragging and dropping to another editor or closing the editor via cmd/ctrl+w. this._register(this._editorService.onDidCloseEditor(e => { - console.log('closed editor'); const instance = e.editor instanceof TerminalEditorInput ? e.editor.terminalInstance : undefined; if (instance) { const instanceIndex = this.instances.findIndex(e => e === instance); @@ -101,7 +100,6 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor this.instances.splice(instanceIndex, 1); } } - console.log(this.instances); })); this._register(this._editorService.onDidActiveEditorChange(() => { const instance = this._editorService.activeEditor instanceof TerminalEditorInput ? this._editorService.activeEditor : undefined; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 69ec76c20d0..11e980b5f71 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -650,9 +650,7 @@ export class TerminalService implements ITerminalService { return; } const tabs = this._terminalGroupService.groups.map(g => g.getLayoutInfo(g === this._terminalGroupService.activeGroup)); - const state: ITerminalsLayoutInfoById = { - tabs - }; + const state: ITerminalsLayoutInfoById = { tabs }; this._primaryBackend?.setTerminalLayoutInfo(state); } -- cgit v1.2.3 From 9dcdfa421e249c14cceb2c8bcd8e9f407e738457 Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Mon, 20 Jun 2022 20:41:14 -0400 Subject: Use same ID for reload to reconnect --- src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts | 5 +---- .../contrib/terminal/electron-sandbox/localTerminalBackend.ts | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts index 6b304681efd..35454bcae4e 100644 --- a/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts @@ -245,10 +245,7 @@ class RemoteTerminalBackend extends BaseTerminalBackend implements ITerminalBack } try { - const newId = await this._remoteTerminalChannel.getRevivedPtyNewId(id); - if (newId === undefined) { - return undefined; - } + const newId = await this._remoteTerminalChannel.getRevivedPtyNewId(id) ?? id; return await this.attachToProcess(newId); } catch (e) { this._logService.trace(`Couldn't attach to process ${e.message}`); diff --git a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts index 8b9802f0abc..d61acd4c4a4 100644 --- a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts @@ -170,10 +170,7 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke async attachToRevivedProcess(id: number): Promise { try { - const newId = await this._localPtyService.getRevivedPtyNewId(id); - if (newId === undefined) { - return undefined; - } + const newId = await this._localPtyService.getRevivedPtyNewId(id) ?? id; return await this.attachToProcess(newId); } catch (e) { this._logService.trace(`Couldn't attach to process ${e.message}`); -- cgit v1.2.3 From 757c5f54c90bfde5406d0436df3229cb8e5d12bc Mon Sep 17 00:00:00 2001 From: jeanp413 Date: Wed, 22 Jun 2022 00:51:33 -0500 Subject: Proposal TerminalExitStatus --- src/vs/platform/terminal/common/terminal.ts | 5 +++++ src/vs/workbench/api/browser/mainThreadTerminalService.ts | 2 +- src/vs/workbench/api/common/extHost.api.impl.ts | 1 + src/vs/workbench/api/common/extHost.protocol.ts | 4 ++-- src/vs/workbench/api/common/extHostTerminalService.ts | 10 +++++----- src/vs/workbench/api/common/extHostTypes.ts | 5 +++++ src/vs/workbench/contrib/terminal/browser/terminal.ts | 11 +++++------ src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 10 ++++++---- .../workbench/contrib/terminal/browser/terminalQuickAccess.ts | 5 +++-- src/vs/workbench/contrib/terminal/browser/terminalService.ts | 2 +- .../services/extensions/common/extensionsApiProposals.ts | 1 + 11 files changed, 35 insertions(+), 21 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index fd5f4734492..e3e5042e131 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -790,3 +790,8 @@ export interface IShellIntegration { capabilities: ITerminalCapabilityStore; deserialize(serialized: ISerializedCommandDetectionCapability): void; } + +export enum TerminalExitReason { + Unknown = 0, + Shutdown = 1 +} diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index b280f677abe..f6421747044 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -253,7 +253,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } private _onTerminalDisposed(terminalInstance: ITerminalInstance): void { - this._proxy.$acceptTerminalClosed(terminalInstance.instanceId, terminalInstance.exitCode); + this._proxy.$acceptTerminalClosed(terminalInstance.instanceId, terminalInstance.exitCode, terminalInstance.exitReason); } private _onTerminalOpened(terminalInstance: ITerminalInstance): void { diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index b438fb90ead..93c514d238f 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1273,6 +1273,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I TaskPanelKind: extHostTypes.TaskPanelKind, TaskRevealKind: extHostTypes.TaskRevealKind, TaskScope: extHostTypes.TaskScope, + TerminalExitReason: extHostTypes.TerminalExitReason, TerminalLink: extHostTypes.TerminalLink, TerminalLocation: extHostTypes.TerminalLocation, TerminalProfile: extHostTypes.TerminalProfile, diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 5af7bb15f92..6b6fd263b04 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -40,7 +40,7 @@ import * as quickInput from 'vs/platform/quickinput/common/quickInput'; import { IRemoteConnectionData, TunnelDescription } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; -import { ICreateContributedTerminalProfileOptions, IProcessProperty, IShellLaunchConfigDto, ITerminalEnvironment, ITerminalLaunchError, ITerminalProfile, TerminalLocation } from 'vs/platform/terminal/common/terminal'; +import { ICreateContributedTerminalProfileOptions, IProcessProperty, IShellLaunchConfigDto, ITerminalEnvironment, ITerminalLaunchError, ITerminalProfile, TerminalExitReason, TerminalLocation } from 'vs/platform/terminal/common/terminal'; import { ThemeColor, ThemeIcon } from 'vs/platform/theme/common/themeService'; import { ProvidedPortAttributes, TunnelCreationOptions, TunnelOptions, TunnelPrivacyId, TunnelProviderFeatures } from 'vs/platform/tunnel/common/tunnel'; import { WorkspaceTrustRequestOptions } from 'vs/platform/workspace/common/workspaceTrust'; @@ -1817,7 +1817,7 @@ export interface ITerminalDimensionsDto { } export interface ExtHostTerminalServiceShape { - $acceptTerminalClosed(id: number, exitCode: number | undefined): void; + $acceptTerminalClosed(id: number, exitCode: number | undefined, exitReason: TerminalExitReason | undefined): void; $acceptTerminalOpened(id: number, extHostTerminalId: string | undefined, name: string, shellLaunchConfig: IShellLaunchConfigDto): void; $acceptActiveTerminalChanged(id: number | null): void; $acceptTerminalProcessId(id: number, processId: number): void; diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index f27f16dca52..05631f9eaef 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -10,7 +10,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { URI } from 'vs/base/common/uri'; import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { IDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle'; -import { Disposable as VSCodeDisposable, EnvironmentVariableMutatorType } from './extHostTypes'; +import { Disposable as VSCodeDisposable, EnvironmentVariableMutatorType, TerminalExitReason } from './extHostTypes'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { localize } from 'vs/nls'; import { NotSupportedError } from 'vs/base/common/errors'; @@ -203,8 +203,8 @@ export class ExtHostTerminal { this._name = name; } - public setExitCode(code: number | undefined) { - this._exitStatus = Object.freeze({ code }); + public setExitCode(code: number | undefined, reason: TerminalExitReason | undefined) { + this._exitStatus = Object.freeze({ code, reason }); } public setDimensions(cols: number, rows: number): boolean { @@ -500,11 +500,11 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I } } - public async $acceptTerminalClosed(id: number, exitCode: number | undefined): Promise { + public async $acceptTerminalClosed(id: number, exitCode: number | undefined, exitReason: TerminalExitReason | undefined): Promise { const index = this._getTerminalObjectIndexById(this._terminals, id); if (index !== null) { const terminal = this._terminals.splice(index, 1)[0]; - terminal.setExitCode(exitCode); + terminal.setExitCode(exitCode, exitReason); this._onDidCloseTerminal.fire(terminal.value); } } diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index ce30f68d26e..745e7761ceb 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -1854,6 +1854,11 @@ export enum SourceControlInputBoxValidationType { Information = 2 } +export enum TerminalExitReason { + Unknown = 0, + Shutdown = 1 +} + export class TerminalLink implements vscode.TerminalLink { constructor( public startIndex: number, diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index ddaf6f211db..ea2e9200ecc 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -11,7 +11,7 @@ import { FindReplaceState } from 'vs/editor/contrib/find/browser/findState'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IKeyMods } from 'vs/platform/quickinput/common/quickInput'; import { ITerminalCapabilityStore, ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities'; -import { IExtensionTerminalProfile, IProcessPropertyMap, IShellIntegration, IShellLaunchConfig, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, ProcessPropertyType, TerminalIcon, TerminalLocation, TerminalShellType, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { IExtensionTerminalProfile, IProcessPropertyMap, IShellIntegration, IShellLaunchConfig, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, ProcessPropertyType, TerminalExitReason, TerminalIcon, TerminalLocation, TerminalShellType, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { IGenericMarkProperties } from 'vs/platform/terminal/common/terminalProcess'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; @@ -567,6 +567,8 @@ export interface ITerminalInstance { readonly exitCode: number | undefined; + readonly exitReason: TerminalExitReason | undefined; + readonly areLinksReady: boolean; /** @@ -651,12 +653,9 @@ export interface ITerminalInstance { /** * Dispose the terminal instance, removing it from the panel/service and freeing up resources. * - * @param immediate Whether the kill should be immediate or not. Immediate should only be used - * when VS Code is shutting down or in cases where the terminal dispose was user initiated. - * The immediate===false exists to cover an edge case where the final output of the terminal can - * get cut off. If immediate kill any terminal processes immediately. + * @param isShutdown Whether the kill was triggered by lifecycle shutdown */ - dispose(immediate?: boolean): void; + dispose(isShutdown?: boolean): void; /** * Inform the process that the terminal is now detached. diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 4401c00feeb..1d6005c587e 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -46,7 +46,7 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITerminalCommand, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; import { TerminalCapabilityStoreMultiplexer } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore'; -import { IProcessDataEvent, IProcessPropertyMap, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, PosixShellType, ProcessPropertyType, TerminalIcon, TerminalLocation, TerminalSettingId, TerminalShellType, TitleEventSource, WindowsShellType } from 'vs/platform/terminal/common/terminal'; +import { IProcessDataEvent, IProcessPropertyMap, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, PosixShellType, ProcessPropertyType, TerminalExitReason, TerminalIcon, TerminalLocation, TerminalSettingId, TerminalShellType, TitleEventSource, WindowsShellType } from 'vs/platform/terminal/common/terminal'; import { escapeNonWindowsPath } from 'vs/platform/terminal/common/terminalEnvironment'; import { activeContrastBorder, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground } from 'vs/platform/theme/common/colorRegistry'; import { IColorTheme, ICssStyleCollector, IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService'; @@ -170,6 +170,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { private _isVisible: boolean; private _isDisposed: boolean; private _exitCode: number | undefined; + private _exitReason: TerminalExitReason | undefined; private _skipTerminalCommands: string[]; private _shellType: TerminalShellType; private _title: string = ''; @@ -275,6 +276,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { get areLinksReady(): boolean { return this._areLinksReady; } get initialDataEvents(): string[] | undefined { return this._initialDataEvents; } get exitCode(): number | undefined { return this._exitCode; } + get exitReason(): TerminalExitReason | undefined { return this._exitReason; } get hadFocusOnExit(): boolean { return this._hadFocusOnExit; } get isTitleSetByProcess(): boolean { return !!this._messageTitleDisposable; } get shellLaunchConfig(): IShellLaunchConfig { return this._shellLaunchConfig; } @@ -1305,8 +1307,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { return confirmation.confirmed; } - - override dispose(immediate?: boolean): void { + override dispose(isShutdown?: boolean): void { if (this._isDisposed) { return; } @@ -1345,7 +1346,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._pressAnyKeyToCloseListener = undefined; } - this._processManager.dispose(immediate); + this._exitReason = isShutdown ? TerminalExitReason.Shutdown : TerminalExitReason.Unknown; + this._processManager.dispose(); // Process manager dispose/shutdown doesn't fire process exit, trigger with undefined if it // hasn't happened yet this._onProcessExit(undefined); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalQuickAccess.ts b/src/vs/workbench/contrib/terminal/browser/terminalQuickAccess.ts index af7953a3268..11af476412f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalQuickAccess.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalQuickAccess.ts @@ -7,7 +7,7 @@ import { localize } from 'vs/nls'; import { IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { IPickerQuickAccessItem, PickerQuickAccessProvider, TriggerAction } from 'vs/platform/quickinput/browser/pickerQuickAccess'; import { matchesFuzzy } from 'vs/base/common/filters'; -import { ITerminalEditorService, ITerminalGroupService, ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { ITerminalEditorService, ITerminalGroupService, ITerminalInstance, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; import { IThemeService, ThemeIcon } from 'vs/platform/theme/common/themeService'; @@ -24,6 +24,7 @@ export class TerminalQuickAccessProvider extends PickerQuickAccessProvider Date: Sat, 25 Jun 2022 14:10:00 -0500 Subject: More granular TerminalExitReason --- src/vs/platform/terminal/common/terminal.ts | 5 ++++- src/vs/workbench/api/browser/mainThreadTerminalService.ts | 4 ++-- src/vs/workbench/api/common/extHost.api.impl.ts | 4 ++-- src/vs/workbench/api/common/extHostTypes.ts | 5 ++++- src/vs/workbench/contrib/terminal/browser/terminal.ts | 11 +++++++---- src/vs/workbench/contrib/terminal/browser/terminalActions.ts | 4 ++-- .../contrib/terminal/browser/terminalEditorInput.ts | 6 ++++-- .../workbench/contrib/terminal/browser/terminalInstance.ts | 12 ++++++------ src/vs/workbench/contrib/terminal/browser/terminalService.ts | 10 +++++----- 9 files changed, 36 insertions(+), 25 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index e3e5042e131..d77dce7ecc6 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -793,5 +793,8 @@ export interface IShellIntegration { export enum TerminalExitReason { Unknown = 0, - Shutdown = 1 + Shutdown = 1, + Process = 2, + User = 3, + Extension = 4, } diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index f6421747044..b96d10e4131 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -10,7 +10,7 @@ import { URI } from 'vs/base/common/uri'; import { StopWatch } from 'vs/base/common/stopwatch'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; -import { IProcessProperty, IShellLaunchConfig, IShellLaunchConfigDto, ProcessPropertyType, TerminalLocation, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { IProcessProperty, IShellLaunchConfig, IShellLaunchConfigDto, ProcessPropertyType, TerminalExitReason, TerminalLocation, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering'; import { ITerminalEditorService, ITerminalExternalLinkProvider, ITerminalGroupService, ITerminalInstance, ITerminalInstanceService, ITerminalLink, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/browser/terminalProcessExtHostProxy'; @@ -183,7 +183,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } public async $dispose(id: ExtHostTerminalIdentifier): Promise { - (await this._getTerminalInstance(id))?.dispose(); + (await this._getTerminalInstance(id))?.dispose(TerminalExitReason.Extension); } public async $sendText(id: ExtHostTerminalIdentifier, text: string, addNewLine: boolean): Promise { diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 93c514d238f..d2240a26fbd 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1273,7 +1273,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I TaskPanelKind: extHostTypes.TaskPanelKind, TaskRevealKind: extHostTypes.TaskRevealKind, TaskScope: extHostTypes.TaskScope, - TerminalExitReason: extHostTypes.TerminalExitReason, TerminalLink: extHostTypes.TerminalLink, TerminalLocation: extHostTypes.TerminalLocation, TerminalProfile: extHostTypes.TerminalProfile, @@ -1342,7 +1341,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I TabInputNotebook: extHostTypes.NotebookEditorTabInput, TabInputNotebookDiff: extHostTypes.NotebookDiffEditorTabInput, TabInputWebview: extHostTypes.WebviewEditorTabInput, - TabInputTerminal: extHostTypes.TerminalEditorTabInput + TabInputTerminal: extHostTypes.TerminalEditorTabInput, + TerminalExitReason: extHostTypes.TerminalExitReason }; }; } diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 745e7761ceb..aac7633b6f0 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -1856,7 +1856,10 @@ export enum SourceControlInputBoxValidationType { export enum TerminalExitReason { Unknown = 0, - Shutdown = 1 + Shutdown = 1, + Process = 2, + User = 3, + Extension = 4 } export class TerminalLink implements vscode.TerminalLink { diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index ea2e9200ecc..baefdbf7a67 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -653,14 +653,17 @@ export interface ITerminalInstance { /** * Dispose the terminal instance, removing it from the panel/service and freeing up resources. * - * @param isShutdown Whether the kill was triggered by lifecycle shutdown + * @param reason The reason why the terminal is being disposed */ - dispose(isShutdown?: boolean): void; + dispose(reason?: TerminalExitReason): void; /** - * Inform the process that the terminal is now detached. + * Informs the process that the terminal is now detached and + * then disposes the terminal. + * + * @param reason The reason why the terminal is being disposed */ - detachFromProcess(): Promise; + detachProcessAndDispose(reason: TerminalExitReason): Promise; /** * Check if anything is selected in terminal. diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index ed78d4a79e8..7bc8ca063a0 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -28,7 +28,7 @@ import { IListService } from 'vs/platform/list/browser/listService'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IPickOptions, IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; -import { ITerminalProfile, TerminalLocation, TerminalSettingId, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { ITerminalProfile, TerminalExitReason, TerminalLocation, TerminalSettingId, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { PICK_WORKSPACE_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands'; import { CLOSE_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands'; @@ -1062,7 +1062,7 @@ export function registerTerminalActions() { } async run(accessor: ServicesAccessor) { const terminalService = accessor.get(ITerminalService); - await terminalService.activeInstance?.detachFromProcess(); + await terminalService.activeInstance?.detachProcessAndDispose(TerminalExitReason.User); } }); registerAction2(class extends Action2 { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts index b80d8fae41c..839209a2cca 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts @@ -13,7 +13,7 @@ import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { ITerminalInstance, ITerminalInstanceService, terminalEditorId } from 'vs/workbench/contrib/terminal/browser/terminal'; import { getColorClass, getUriClasses } from 'vs/workbench/contrib/terminal/browser/terminalIcon'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IShellLaunchConfig, TerminalLocation, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; +import { IShellLaunchConfig, TerminalExitReason, TerminalLocation, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { ConfirmOnKill } from 'vs/workbench/contrib/terminal/common/terminal'; @@ -167,7 +167,9 @@ export class TerminalEditorInput extends EditorInput { this._register(toDisposable(() => { if (!this._isDetached && !this._isShuttingDown) { - instance.dispose(); + // Will be ignored if triggered by onExit or onDisposed terminal events + // as disposed was already called + instance.dispose(TerminalExitReason.User); } })); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 1d6005c587e..695a359ef0e 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1307,7 +1307,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { return confirmation.confirmed; } - override dispose(isShutdown?: boolean): void { + override dispose(reason?: TerminalExitReason): void { if (this._isDisposed) { return; } @@ -1346,7 +1346,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._pressAnyKeyToCloseListener = undefined; } - this._exitReason = isShutdown ? TerminalExitReason.Shutdown : TerminalExitReason.Unknown; + this._exitReason = reason || TerminalExitReason.Unknown; this._processManager.dispose(); // Process manager dispose/shutdown doesn't fire process exit, trigger with undefined if it // hasn't happened yet @@ -1357,11 +1357,11 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { super.dispose(); } - async detachFromProcess(): Promise { + async detachProcessAndDispose(reason: TerminalExitReason): Promise { // Detach the process and dispose the instance, without the instance dispose the terminal // won't go away await this._processManager.detachFromProcess(); - this.dispose(); + this.dispose(reason); } focus(force?: boolean): void { @@ -1697,7 +1697,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } }); } else { - this.dispose(); + this.dispose(TerminalExitReason.Process); if (exitMessage) { const failedDuringLaunch = this._processManager.processState === ProcessState.KilledDuringLaunch; if (failedDuringLaunch || this._configHelper.config.showExitAlert) { @@ -1767,7 +1767,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { if (this._pressAnyKeyToCloseListener) { this._pressAnyKeyToCloseListener.dispose(); this._pressAnyKeyToCloseListener = undefined; - this.dispose(); + this.dispose(TerminalExitReason.Process); event.preventDefault(); } }); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 23d34d8018d..0a17ca0fc8f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -20,7 +20,7 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { ICreateContributedTerminalProfileOptions, IShellLaunchConfig, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalLocation, TerminalLocationString, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { ICreateContributedTerminalProfileOptions, IShellLaunchConfig, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalExitReason, TerminalLocation, TerminalLocationString, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { iconForeground } from 'vs/platform/theme/common/colorRegistry'; import { getIconRegistry } from 'vs/platform/theme/common/iconRegistry'; import { ColorScheme } from 'vs/platform/theme/common/theme'; @@ -282,7 +282,7 @@ export class TerminalService implements ITerminalService { } else { this._terminalGroupService.getGroupForInstance(instanceToDetach)?.removeInstance(instanceToDetach); } - await instanceToDetach.detachFromProcess(); + await instanceToDetach.detachProcessAndDispose(TerminalExitReason.User); await this._primaryBackend?.acceptDetachInstanceReply(e.requestId, persistentProcessId); } else { // will get rejected without a persistentProcessId to attach to @@ -371,7 +371,7 @@ export class TerminalService implements ITerminalService { } return new Promise(r => { instance.onExit(() => r()); - instance.dispose(); + instance.dispose(TerminalExitReason.User); }); } @@ -615,14 +615,14 @@ export class TerminalService implements ITerminalService { const shouldPersistTerminals = this._configHelper.config.enablePersistentSessions && e.reason === ShutdownReason.RELOAD; if (shouldPersistTerminals) { for (const instance of this.instances) { - instance.detachFromProcess(); + instance.detachProcessAndDispose(TerminalExitReason.Shutdown); } return; } // Force dispose of all terminal instances for (const instance of this.instances) { - instance.dispose(true); + instance.dispose(TerminalExitReason.Shutdown); } // Clear terminal layout info only when not persisting -- cgit v1.2.3 From 05d2534e663a327f37c812c51884aa543dea104b Mon Sep 17 00:00:00 2001 From: Qingpeng Li Date: Fri, 1 Jul 2022 01:34:07 +0800 Subject: remove es5ClassCompat --- src/vs/workbench/api/common/extHostTypes.ts | 82 ----------------------------- 1 file changed, 82 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index ce30f68d26e..79ff066609d 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -19,16 +19,6 @@ import { IRelativePatternDto } from 'vs/workbench/api/common/extHost.protocol'; import { CellEditType, ICellPartialMetadataEdit, IDocumentMetadataEdit } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import type * as vscode from 'vscode'; -function es5ClassCompat(target: Function): any { - ///@ts-expect-error - function _() { return Reflect.construct(target, arguments, this.constructor); } - Object.defineProperty(_, 'name', Object.getOwnPropertyDescriptor(target, 'name')!); - Object.setPrototypeOf(_, target); - Object.setPrototypeOf(_.prototype, target.prototype); - return _; -} - -@es5ClassCompat export class Disposable { static from(...inDisposables: { dispose(): any }[]): Disposable { @@ -59,7 +49,6 @@ export class Disposable { } } -@es5ClassCompat export class Position { static Min(...positions: Position[]): Position { @@ -240,7 +229,6 @@ export class Position { } } -@es5ClassCompat export class Range { static isRange(thing: any): thing is vscode.Range { @@ -386,7 +374,6 @@ export class Range { } } -@es5ClassCompat export class Selection extends Range { static isSelection(thing: any): thing is Selection { @@ -515,7 +502,6 @@ export enum EnvironmentVariableMutatorType { Prepend = 3 } -@es5ClassCompat export class TextEdit { static isTextEdit(thing: any): thing is TextEdit { @@ -599,7 +585,6 @@ export class TextEdit { } } -@es5ClassCompat export class NotebookEdit implements vscode.NotebookEdit { static isNotebookCellEdit(thing: any): thing is NotebookEdit { @@ -697,7 +682,6 @@ export interface ICellEdit { type WorkspaceEditEntry = IFileOperation | IFileTextEdit | IFileCellEdit | ICellEdit; -@es5ClassCompat export class WorkspaceEdit implements vscode.WorkspaceEdit { private readonly _edits: WorkspaceEditEntry[] = []; @@ -844,7 +828,6 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit { } } -@es5ClassCompat export class SnippetString { static isSnippetString(thing: any): thing is SnippetString { @@ -951,7 +934,6 @@ export enum DiagnosticSeverity { Error = 0 } -@es5ClassCompat export class Location { static isLocation(thing: any): thing is vscode.Location { @@ -990,7 +972,6 @@ export class Location { } } -@es5ClassCompat export class DiagnosticRelatedInformation { static is(thing: any): thing is DiagnosticRelatedInformation { @@ -1024,7 +1005,6 @@ export class DiagnosticRelatedInformation { } } -@es5ClassCompat export class Diagnostic { range: Range; @@ -1075,7 +1055,6 @@ export class Diagnostic { } } -@es5ClassCompat export class Hover { public contents: (vscode.MarkdownString | vscode.MarkedString)[]; @@ -1103,7 +1082,6 @@ export enum DocumentHighlightKind { Write = 2 } -@es5ClassCompat export class DocumentHighlight { range: Range; @@ -1155,7 +1133,6 @@ export enum SymbolTag { Deprecated = 1, } -@es5ClassCompat export class SymbolInformation { static validate(candidate: SymbolInformation): void { @@ -1200,7 +1177,6 @@ export class SymbolInformation { } } -@es5ClassCompat export class DocumentSymbol { static validate(candidate: DocumentSymbol): void { @@ -1239,7 +1215,6 @@ export enum CodeActionTriggerKind { Automatic = 2, } -@es5ClassCompat export class CodeAction { title: string; @@ -1260,7 +1235,6 @@ export class CodeAction { } -@es5ClassCompat export class CodeActionKind { private static readonly sep = '.'; @@ -1300,7 +1274,6 @@ CodeActionKind.Source = CodeActionKind.Empty.append('source'); CodeActionKind.SourceOrganizeImports = CodeActionKind.Source.append('organizeImports'); CodeActionKind.SourceFixAll = CodeActionKind.Source.append('fixAll'); -@es5ClassCompat export class SelectionRange { range: Range; @@ -1367,7 +1340,6 @@ export enum LanguageStatusSeverity { } -@es5ClassCompat export class CodeLens { range: Range; @@ -1384,7 +1356,6 @@ export class CodeLens { } } -@es5ClassCompat export class MarkdownString implements vscode.MarkdownString { readonly #delegate: BaseMarkdownString; @@ -1455,7 +1426,6 @@ export class MarkdownString implements vscode.MarkdownString { } } -@es5ClassCompat export class ParameterInformation { label: string | [number, number]; @@ -1467,7 +1437,6 @@ export class ParameterInformation { } } -@es5ClassCompat export class SignatureInformation { label: string; @@ -1482,7 +1451,6 @@ export class SignatureInformation { } } -@es5ClassCompat export class SignatureHelp { signatures: SignatureInformation[]; @@ -1506,7 +1474,6 @@ export enum InlayHintKind { Parameter = 2, } -@es5ClassCompat export class InlayHintLabelPart { value: string; @@ -1519,7 +1486,6 @@ export class InlayHintLabelPart { } } -@es5ClassCompat export class InlayHint implements vscode.InlayHint { label: string | InlayHintLabelPart[]; @@ -1588,7 +1554,6 @@ export interface CompletionItemLabel { description?: string; } -@es5ClassCompat export class CompletionItem implements vscode.CompletionItem { label: string | CompletionItemLabel; @@ -1627,7 +1592,6 @@ export class CompletionItem implements vscode.CompletionItem { } } -@es5ClassCompat export class CompletionList { isIncomplete?: boolean; @@ -1639,7 +1603,6 @@ export class CompletionList { } } -@es5ClassCompat export class InlineSuggestion implements vscode.InlineCompletionItem { filterText?: string; @@ -1654,7 +1617,6 @@ export class InlineSuggestion implements vscode.InlineCompletionItem { } } -@es5ClassCompat export class InlineSuggestionList implements vscode.InlineCompletionList { items: vscode.InlineCompletionItemNew[]; @@ -1665,7 +1627,6 @@ export class InlineSuggestionList implements vscode.InlineCompletionList { } } -@es5ClassCompat export class InlineSuggestionNew implements vscode.InlineCompletionItemNew { insertText: string; range?: Range; @@ -1678,7 +1639,6 @@ export class InlineSuggestionNew implements vscode.InlineCompletionItemNew { } } -@es5ClassCompat export class InlineSuggestionsNew implements vscode.InlineCompletionListNew { items: vscode.InlineCompletionItemNew[]; @@ -1772,7 +1732,6 @@ export namespace TextEditorSelectionChangeKind { } } -@es5ClassCompat export class DocumentLink { range: Range; @@ -1793,7 +1752,6 @@ export class DocumentLink { } } -@es5ClassCompat export class Color { readonly red: number; readonly green: number; @@ -1810,7 +1768,6 @@ export class Color { export type IColorFormat = string | { opaque: string; transparent: string }; -@es5ClassCompat export class ColorInformation { range: Range; @@ -1828,7 +1785,6 @@ export class ColorInformation { } } -@es5ClassCompat export class ColorPresentation { label: string; textEdit?: TextEdit; @@ -1903,7 +1859,6 @@ export enum TaskPanelKind { New = 3 } -@es5ClassCompat export class TaskGroup implements vscode.TaskGroup { isDefault: boolean | undefined; @@ -1955,7 +1910,6 @@ function computeTaskExecutionId(values: string[]): string { return id; } -@es5ClassCompat export class ProcessExecution implements vscode.ProcessExecution { private _process: string; @@ -2026,7 +1980,6 @@ export class ProcessExecution implements vscode.ProcessExecution { } } -@es5ClassCompat export class ShellExecution implements vscode.ShellExecution { private _commandLine: string | undefined; @@ -2141,7 +2094,6 @@ export class CustomExecution implements vscode.CustomExecution { } } -@es5ClassCompat export class Task implements vscode.Task { private static ExtensionCallbackType: string = 'customExecution'; @@ -2398,7 +2350,6 @@ export enum ProgressLocation { Notification = 15 } -@es5ClassCompat export class TreeItem { label?: string | vscode.TreeItemLabel; @@ -2426,7 +2377,6 @@ export enum TreeItemCollapsibleState { Expanded = 2 } -@es5ClassCompat export class DataTransferItem { async asString(): Promise { @@ -2440,7 +2390,6 @@ export class DataTransferItem { constructor(public readonly value: any) { } } -@es5ClassCompat export class DataTransfer implements vscode.DataTransfer { #items = new Map(); @@ -2482,7 +2431,6 @@ export class DataTransfer implements vscode.DataTransfer { } } -@es5ClassCompat export class DocumentDropEdit { insertText: string | SnippetString; @@ -2493,7 +2441,6 @@ export class DocumentDropEdit { } } -@es5ClassCompat export class DocumentPasteEdit { insertText: string | SnippetString; @@ -2504,7 +2451,6 @@ export class DocumentPasteEdit { } } -@es5ClassCompat export class ThemeIcon { static File: ThemeIcon; @@ -2522,7 +2468,6 @@ ThemeIcon.File = new ThemeIcon('file'); ThemeIcon.Folder = new ThemeIcon('folder'); -@es5ClassCompat export class ThemeColor { id: string; constructor(id: string) { @@ -2538,7 +2483,6 @@ export enum ConfigurationTarget { WorkspaceFolder = 3 } -@es5ClassCompat export class RelativePattern implements IRelativePattern { pattern: string; @@ -2592,7 +2536,6 @@ export class RelativePattern implements IRelativePattern { } } -@es5ClassCompat export class Breakpoint { private _id: string | undefined; @@ -2623,7 +2566,6 @@ export class Breakpoint { } } -@es5ClassCompat export class SourceBreakpoint extends Breakpoint { readonly location: Location; @@ -2636,7 +2578,6 @@ export class SourceBreakpoint extends Breakpoint { } } -@es5ClassCompat export class FunctionBreakpoint extends Breakpoint { readonly functionName: string; @@ -2646,7 +2587,6 @@ export class FunctionBreakpoint extends Breakpoint { } } -@es5ClassCompat export class DataBreakpoint extends Breakpoint { readonly label: string; readonly dataId: string; @@ -2664,7 +2604,6 @@ export class DataBreakpoint extends Breakpoint { } -@es5ClassCompat export class DebugAdapterExecutable implements vscode.DebugAdapterExecutable { readonly command: string; readonly args: string[]; @@ -2677,7 +2616,6 @@ export class DebugAdapterExecutable implements vscode.DebugAdapterExecutable { } } -@es5ClassCompat export class DebugAdapterServer implements vscode.DebugAdapterServer { readonly port: number; readonly host?: string; @@ -2688,13 +2626,11 @@ export class DebugAdapterServer implements vscode.DebugAdapterServer { } } -@es5ClassCompat export class DebugAdapterNamedPipeServer implements vscode.DebugAdapterNamedPipeServer { constructor(public readonly path: string) { } } -@es5ClassCompat export class DebugAdapterInlineImplementation implements vscode.DebugAdapterInlineImplementation { readonly implementation: vscode.DebugAdapter; @@ -2703,7 +2639,6 @@ export class DebugAdapterInlineImplementation implements vscode.DebugAdapterInli } } -@es5ClassCompat export class EvaluatableExpression implements vscode.EvaluatableExpression { readonly range: vscode.Range; readonly expression?: string; @@ -2724,7 +2659,6 @@ export enum InlineCompletionTriggerKindNew { Automatic = 1, } -@es5ClassCompat export class InlineValueText implements vscode.InlineValueText { readonly range: Range; readonly text: string; @@ -2735,7 +2669,6 @@ export class InlineValueText implements vscode.InlineValueText { } } -@es5ClassCompat export class InlineValueVariableLookup implements vscode.InlineValueVariableLookup { readonly range: Range; readonly variableName?: string; @@ -2748,7 +2681,6 @@ export class InlineValueVariableLookup implements vscode.InlineValueVariableLook } } -@es5ClassCompat export class InlineValueEvaluatableExpression implements vscode.InlineValueEvaluatableExpression { readonly range: Range; readonly expression?: string; @@ -2759,7 +2691,6 @@ export class InlineValueEvaluatableExpression implements vscode.InlineValueEvalu } } -@es5ClassCompat export class InlineValueContext implements vscode.InlineValueContext { readonly frameId: number; @@ -2779,7 +2710,6 @@ export enum FileChangeType { Deleted = 3, } -@es5ClassCompat export class FileSystemError extends Error { static FileExists(messageOrUri?: string | URI): FileSystemError { @@ -2829,7 +2759,6 @@ export class FileSystemError extends Error { //#region folding api -@es5ClassCompat export class FoldingRange { start: number; @@ -3119,7 +3048,6 @@ export enum DebugConsoleMode { //#endregion -@es5ClassCompat export class QuickInputButtons { static readonly Back: vscode.QuickInputButton = { iconPath: new ThemeIcon('arrow-left') }; @@ -3175,7 +3103,6 @@ export class FileDecoration { //#region Theming -@es5ClassCompat export class ColorTheme implements vscode.ColorTheme { constructor(public readonly kind: ColorThemeKind) { } @@ -3470,7 +3397,6 @@ export class NotebookRendererScript { //#region Timeline -@es5ClassCompat export class TimelineItem implements vscode.TimelineItem { constructor(public label: string, public timestamp: number) { } } @@ -3560,7 +3486,6 @@ export enum TestRunProfileKind { Coverage = 3, } -@es5ClassCompat export class TestRunRequest implements vscode.TestRunRequest { constructor( public readonly include: vscode.TestItem[] | undefined = undefined, @@ -3569,7 +3494,6 @@ export class TestRunRequest implements vscode.TestRunRequest { ) { } } -@es5ClassCompat export class TestMessage implements vscode.TestMessage { public expectedOutput?: string; public actualOutput?: string; @@ -3585,7 +3509,6 @@ export class TestMessage implements vscode.TestMessage { constructor(public message: string | vscode.MarkdownString) { } } -@es5ClassCompat export class TestTag implements vscode.TestTag { constructor(public readonly id: string) { } } @@ -3593,12 +3516,10 @@ export class TestTag implements vscode.TestTag { //#endregion //#region Test Coverage -@es5ClassCompat export class CoveredCount implements vscode.CoveredCount { constructor(public covered: number, public total: number) { } } -@es5ClassCompat export class FileCoverage implements vscode.FileCoverage { public static fromDetails(uri: vscode.Uri, details: vscode.DetailedCoverage[]): vscode.FileCoverage { const statements = new CoveredCount(0, 0); @@ -3642,7 +3563,6 @@ export class FileCoverage implements vscode.FileCoverage { ) { } } -@es5ClassCompat export class StatementCoverage implements vscode.StatementCoverage { constructor( public executionCount: number, @@ -3651,7 +3571,6 @@ export class StatementCoverage implements vscode.StatementCoverage { ) { } } -@es5ClassCompat export class BranchCoverage implements vscode.BranchCoverage { constructor( public executionCount: number, @@ -3659,7 +3578,6 @@ export class BranchCoverage implements vscode.BranchCoverage { ) { } } -@es5ClassCompat export class FunctionCoverage implements vscode.FunctionCoverage { constructor( public executionCount: number, -- cgit v1.2.3 From 2d13e2222e370d7deb3692445452027602bb24e6 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 1 Jul 2022 16:12:18 +0200 Subject: Improve layout modes and workbench layout implement MergeEditor#onDidChangeSizeConstraints and minimumWidth so that layout changes reflect better in the workbench, fixes https://github.com/microsoft/vscode/issues/151866 --- .../contrib/mergeEditor/browser/view/mergeEditor.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts index ae2fcbcd7f1..74629320cd2 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts @@ -10,6 +10,7 @@ import { IAction } from 'vs/base/common/actions'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Color } from 'vs/base/common/color'; import { BugIndicatingError } from 'vs/base/common/errors'; +import { Emitter, Event } from 'vs/base/common/event'; import { DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; import { isEqual } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; @@ -85,8 +86,6 @@ export class MergeEditor extends AbstractTextEditor { private readonly _sessionDisposables = new DisposableStore(); private _grid!: Grid; - - private readonly input1View = this._register(this.instantiation.createInstance(InputCodeEditorView, 1)); private readonly input2View = this._register(this.instantiation.createInstance(InputCodeEditorView, 2)); private readonly inputResultView = this._register(this.instantiation.createInstance(ResultCodeEditorView)); @@ -209,6 +208,19 @@ export class MergeEditor extends AbstractTextEditor { super.dispose(); } + // --- layout constraints + + private readonly _onDidChangeSizeConstraints = new Emitter(); + override readonly onDidChangeSizeConstraints: Event = this._onDidChangeSizeConstraints.event; + + override get minimumWidth() { + return this._layoutMode.value === 'mixed' + ? this.input1View.view.minimumWidth + this.input1View.view.minimumWidth + : this.input1View.view.minimumWidth + this.input1View.view.minimumWidth + this.inputResultView.view.minimumWidth; + } + + // --- + override getTitle(): string { if (this.input) { return this.input.getName(); @@ -454,6 +466,7 @@ export class MergeEditor extends AbstractTextEditor { } this._layoutMode.value = newValue; this._ctxUsesColumnLayout.set(newValue); + this._onDidChangeSizeConstraints.fire(); } private _applyViewState(state: IMergeEditorViewState | undefined) { -- cgit v1.2.3 From b9d702a2e2287fdf880e3edcf35d67486e40913a Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 1 Jul 2022 16:37:41 +0200 Subject: add an option to discard merge changes When opening a merge editor we take a snapshot of the result model. We use that snapshort to discard all merge changes so that you also restore the init state - independent of intermediate saves, https://github.com/microsoft/vscode/issues/152841#issuecomment-1167473537 --- .../mergeEditor/browser/mergeEditorInput.ts | 31 +++++++++++++++++++--- .../mergeEditor/browser/model/mergeEditorModel.ts | 5 +++- 2 files changed, 32 insertions(+), 4 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts index 87aa4ac9b0c..137f5a9b992 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts @@ -22,6 +22,7 @@ import { MergeEditorModel } from 'vs/workbench/contrib/mergeEditor/browser/model import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { ILanguageSupport, ITextFileEditorModel, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; +import { assertType } from 'vs/base/common/types'; export class MergeEditorInputData { constructor( @@ -190,13 +191,15 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements // manual-save: FYI and discard actions.push( localize('unhandledConflicts.manualSaveIgnore', "Save and Continue with Conflicts"), // 0 - localize('unhandledConflicts.manualSaveNoSave', "Don't Save") // 1 + localize('unhandledConflicts.discard', "Discard Merge Changes"), // 1 + localize('unhandledConflicts.manualSaveNoSave', "Don't Save"), // 2 ); } else { // auto-save: only FYI actions.push( localize('unhandledConflicts.ignore', "Continue with Conflicts"), // 0 + localize('unhandledConflicts.discard', "Discard Merge Changes"), // 1 ); } @@ -224,10 +227,32 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements if (choice === 0) { // conflicts: continue with remaining conflicts return ConfirmResult.SAVE; + + } else if (choice === 1) { + // discard: undo all changes and save original (pre-merge) state + for (const input of inputs) { + input._discardMergeChanges(); + } + return ConfirmResult.SAVE; + + } else { + // don't save + return ConfirmResult.DONT_SAVE; } + } + + private _discardMergeChanges(): void { + assertType(this._model !== undefined); - // don't save - return ConfirmResult.DONT_SAVE; + const chunks: string[] = []; + while (true) { + const chunk = this._model.resultSnapshot.read(); + if (chunk === null) { + break; + } + chunks.push(chunk); + } + this._model.result.setValue(chunks.join()); } setLanguageId(languageId: string, _setExplicitly?: boolean): void { diff --git a/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts b/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts index d9f61d89baf..b15973884a5 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts @@ -6,7 +6,7 @@ import { CompareResult, equals } from 'vs/base/common/arrays'; import { BugIndicatingError } from 'vs/base/common/errors'; import { ILanguageService } from 'vs/editor/common/languages/language'; -import { ITextModel } from 'vs/editor/common/model'; +import { ITextModel, ITextSnapshot } from 'vs/editor/common/model'; import { IModelService } from 'vs/editor/common/services/model'; import { EditorModel } from 'vs/workbench/common/editor/editorModel'; import { autorunHandleChanges, derivedObservable, IObservable, IReader, ITransaction, keepAlive, ObservableValue, transaction, waitForState } from 'vs/workbench/contrib/audioCues/browser/observable'; @@ -120,6 +120,8 @@ export class MergeEditorModel extends EditorModel { ); }); + readonly resultSnapshot: ITextSnapshot; + constructor( readonly base: ITextModel, readonly input1: ITextModel, @@ -137,6 +139,7 @@ export class MergeEditorModel extends EditorModel { ) { super(); + this.resultSnapshot = result.createSnapshot(); this._register(keepAlive(this.modifiedBaseRangeStateStores)); this._register(keepAlive(this.modifiedBaseRangeHandlingStateStores)); this._register(keepAlive(this.input1ResultMapping)); -- cgit v1.2.3 From dc5fd78fb9701f3b9895a3224fe21721e676e8c2 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 1 Jul 2022 17:45:19 +0200 Subject: use simple SPAN elements over `IconLabel` fixes https://github.com/microsoft/vscode/issues/151036 --- .../browser/view/editors/codeEditorView.ts | 19 +++++++++++-------- .../browser/view/editors/resultCodeEditorView.ts | 9 +++++---- .../mergeEditor/browser/view/media/mergeEditor.css | 22 +++++++++++++++++++--- 3 files changed, 35 insertions(+), 15 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts index e9a1b888ce0..49d4726b463 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts @@ -3,9 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { h } from 'vs/base/browser/dom'; +import { h, reset } from 'vs/base/browser/dom'; import { IView, IViewSize } from 'vs/base/browser/ui/grid/grid'; -import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel'; +import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { IEditorContributionDescription } from 'vs/editor/browser/editorExtensions'; @@ -24,7 +24,11 @@ export abstract class CodeEditorView extends Disposable { readonly model = this._viewModel.map(m => m?.model); protected readonly htmlElements = h('div.code-view', [ - h('div.title', { $: 'title' }), + h('div.title', [ + h('span.title', { $: 'title' }), + h('span.description', { $: 'description' }), + h('span.detail', { $: 'detail' }), + ]), h('div.container', [ h('div.gutter', { $: 'gutterDiv' }), h('div', { $: 'editor' }), @@ -53,9 +57,6 @@ export abstract class CodeEditorView extends Disposable { // snap?: boolean | undefined; }; - private readonly _title = new IconLabel(this.htmlElements.title, { supportIcons: true }); - protected readonly _detail = new IconLabel(this.htmlElements.title, { supportIcons: true }); - public readonly editor = this.instantiationService.createInstance( CodeEditorWidget, this.htmlElements.editor, @@ -100,8 +101,10 @@ export abstract class CodeEditorView extends Disposable { detail: string | undefined ): void { this.editor.setModel(textModel); - this._title.setLabel(title, description); - this._detail.setLabel('', detail); + + reset(this.htmlElements.title, ...renderLabelWithIcons(title)); + reset(this.htmlElements.description, ...(description ? renderLabelWithIcons(description) : [])); + reset(this.htmlElements.detail, ...(detail ? renderLabelWithIcons(detail) : [])); this._viewModel.set(viewModel, undefined); } diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts index fc6919af08a..84921d8ccd9 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts @@ -114,17 +114,18 @@ export class ResultCodeEditorView extends CodeEditorView { } const count = model.unhandledConflictsCount.read(reader); - this._detail.setLabel(count === 1 + this.htmlElements.detail.innerText = count === 1 ? localize( 'mergeEditor.remainingConflicts', - '{0} Remaining Conflict', + '{0} Conflict Remaining', count ) : localize( 'mergeEditor.remainingConflict', - '{0} Remaining Conflicts', + '{0} Conflicts Remaining ', count - )); + ); + }, 'update label')); } } diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/media/mergeEditor.css b/src/vs/workbench/contrib/mergeEditor/browser/view/media/mergeEditor.css index b832e88bd84..e9c0ada7df3 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/media/mergeEditor.css +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/media/mergeEditor.css @@ -8,11 +8,27 @@ height: 30px; display: flex; align-content: center; - justify-content: space-between; } -.monaco-workbench .merge-editor .code-view > .title .monaco-icon-label { - margin: auto 0; +.monaco-workbench .merge-editor .code-view > .title>SPAN { + align-self: center; + text-overflow: ellipsis; + overflow: hidden; + padding-right: 6px; +} + +.monaco-workbench .merge-editor .code-view > .title>SPAN.title { + flex-shrink: 0; +} + +.monaco-workbench .merge-editor .code-view > .title>SPAN.description { + opacity: 0.7; + font-size: 90%; +} + +.monaco-workbench .merge-editor .code-view > .title>SPAN.detail { + margin-left: auto; + flex-shrink: 0; } .monaco-workbench .merge-editor .code-view > .container { -- cgit v1.2.3 From f4ab3480cbd3d549b020ba04e37eaa66190db176 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Fri, 1 Jul 2022 10:11:20 -0700 Subject: have edit sessions use ILocalizedString (#153933) --- .../browser/sessionSync.contribution.ts | 24 ++++++++++------------ .../browser/sessionSyncWorkbenchService.ts | 5 +++-- .../services/sessionSync/common/sessionSync.ts | 6 +++++- 3 files changed, 19 insertions(+), 16 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts b/src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts index d075977cb45..08381fc3d9c 100644 --- a/src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts +++ b/src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts @@ -10,7 +10,7 @@ import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { localize } from 'vs/nls'; -import { ISessionSyncWorkbenchService, Change, ChangeType, Folder, EditSession, FileType, EDIT_SESSION_SYNC_TITLE, EditSessionSchemaVersion } from 'vs/workbench/services/sessionSync/common/sessionSync'; +import { ISessionSyncWorkbenchService, Change, ChangeType, Folder, EditSession, FileType, EDIT_SESSION_SYNC_CATEGORY, EditSessionSchemaVersion } from 'vs/workbench/services/sessionSync/common/sessionSync'; import { ISCMRepository, ISCMService } from 'vs/workbench/contrib/scm/common/scm'; import { IFileService } from 'vs/platform/files/common/files'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; @@ -44,11 +44,13 @@ registerSingleton(ISessionSyncWorkbenchService, SessionSyncWorkbenchService); const resumeLatestCommand = { id: 'workbench.experimental.editSessions.actions.resumeLatest', - title: { value: localize('resume latest', "{0}: Resume Latest Edit Session", EDIT_SESSION_SYNC_TITLE), original: 'Edit Sessions' }, + title: { value: localize('resume latest', "Resume Latest Edit Session"), original: 'Resume Latest Edit Session' }, + category: EDIT_SESSION_SYNC_CATEGORY, }; const storeCurrentCommand = { id: 'workbench.experimental.editSessions.actions.storeCurrent', - title: { value: localize('store current', "{0}: Store Current Edit Session", EDIT_SESSION_SYNC_TITLE), original: 'Edit Sessions' }, + title: { value: localize('store current', "Store Current Edit Session"), original: 'Store Current Edit Session' }, + category: EDIT_SESSION_SYNC_CATEGORY, }; const continueEditSessionCommand = { id: '_workbench.experimental.editSessions.actions.continueEditSession', @@ -56,7 +58,7 @@ const continueEditSessionCommand = { }; const openLocalFolderCommand = { id: '_workbench.experimental.editSessions.actions.continueEditSession.openLocalFolder', - title: localize('continue edit session in local folder', "Open In Local Folder"), + title: { value: localize('continue edit session in local folder', "Open In Local Folder"), original: 'Open In Local Folder' }, }; const queryParamName = 'editSessionId'; @@ -146,8 +148,7 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon this._register(registerAction2(class ContinueEditSessionAction extends Action2 { constructor() { super({ - id: continueEditSessionCommand.id, - title: continueEditSessionCommand.title, + ...continueEditSessionCommand, f1: true }); } @@ -181,8 +182,7 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon this._register(registerAction2(class ApplyLatestEditSessionAction extends Action2 { constructor() { super({ - id: resumeLatestCommand.id, - title: resumeLatestCommand.title, + ...resumeLatestCommand, menu: { id: MenuId.CommandPalette, } @@ -203,8 +203,7 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon this._register(registerAction2(class StoreLatestEditSessionAction extends Action2 { constructor() { super({ - id: storeCurrentCommand.id, - title: storeCurrentCommand.title, + ...storeCurrentCommand, menu: { id: MenuId.CommandPalette, } @@ -275,7 +274,7 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon const result = await this.dialogService.confirm({ message: localize('apply edit session warning', 'Applying your edit session may overwrite your existing uncommitted changes. Do you want to proceed?'), type: 'warning', - title: EDIT_SESSION_SYNC_TITLE + title: EDIT_SESSION_SYNC_CATEGORY.value }); if (!result.confirmed) { return; @@ -399,8 +398,7 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon this._register(registerAction2(class ContinueInLocalFolderAction extends Action2 { constructor() { super({ - id: openLocalFolderCommand.id, - title: openLocalFolderCommand.title, + ...openLocalFolderCommand, precondition: IsWebContext }); } diff --git a/src/vs/workbench/services/sessionSync/browser/sessionSyncWorkbenchService.ts b/src/vs/workbench/services/sessionSync/browser/sessionSyncWorkbenchService.ts index 2c0a8bb167e..4274c62031d 100644 --- a/src/vs/workbench/services/sessionSync/browser/sessionSyncWorkbenchService.ts +++ b/src/vs/workbench/services/sessionSync/browser/sessionSyncWorkbenchService.ts @@ -19,7 +19,7 @@ import { IAuthenticationProvider } from 'vs/platform/userDataSync/common/userDat import { UserDataSyncStoreClient } from 'vs/platform/userDataSync/common/userDataSyncStoreService'; import { AuthenticationSession, AuthenticationSessionsChangeEvent, IAuthenticationService } from 'vs/workbench/services/authentication/common/authentication'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { EDIT_SESSIONS_SIGNED_IN, EditSession, EDIT_SESSION_SYNC_TITLE, ISessionSyncWorkbenchService, EDIT_SESSIONS_SIGNED_IN_KEY } from 'vs/workbench/services/sessionSync/common/sessionSync'; +import { EDIT_SESSIONS_SIGNED_IN, EditSession, EDIT_SESSION_SYNC_CATEGORY, ISessionSyncWorkbenchService, EDIT_SESSIONS_SIGNED_IN_KEY } from 'vs/workbench/services/sessionSync/common/sessionSync'; type ExistingSession = IQuickPickItem & { session: AuthenticationSession & { providerId: string } }; type AuthenticationProviderOption = IQuickPickItem & { provider: IAuthenticationProvider }; @@ -337,7 +337,8 @@ export class SessionSyncWorkbenchService extends Disposable implements ISessionS constructor() { super({ id: 'workbench.sessionSync.actions.resetAuth', - title: localize('reset auth', '{0}: Sign Out', EDIT_SESSION_SYNC_TITLE), + title: localize('reset auth', 'Sign Out'), + category: EDIT_SESSION_SYNC_CATEGORY, precondition: ContextKeyExpr.equals(EDIT_SESSIONS_SIGNED_IN_KEY, true), menu: [{ id: MenuId.CommandPalette, diff --git a/src/vs/workbench/services/sessionSync/common/sessionSync.ts b/src/vs/workbench/services/sessionSync/common/sessionSync.ts index 6eafdb65490..c671ae2aeab 100644 --- a/src/vs/workbench/services/sessionSync/common/sessionSync.ts +++ b/src/vs/workbench/services/sessionSync/common/sessionSync.ts @@ -4,10 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import { localize } from 'vs/nls'; +import { ILocalizedString } from 'vs/platform/action/common/action'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -export const EDIT_SESSION_SYNC_TITLE = localize('session sync', 'Edit Sessions'); +export const EDIT_SESSION_SYNC_CATEGORY: ILocalizedString = { + original: 'Edit Sessions', + value: localize('session sync', 'Edit Sessions') +}; export const ISessionSyncWorkbenchService = createDecorator('ISessionSyncWorkbenchService'); export interface ISessionSyncWorkbenchService { -- cgit v1.2.3 From 46234601a20b70c50873a53b3a8b8477946f846e Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 1 Jul 2022 11:04:11 -0700 Subject: Allow to specify language id in command to create a new untitled file (#153872) * Allow to specify language id in command to create a new untitled file * Make viewtype optional --- src/vs/workbench/contrib/files/browser/fileCommands.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/files/browser/fileCommands.ts b/src/vs/workbench/contrib/files/browser/fileCommands.ts index 2641877c8cd..67ab692b603 100644 --- a/src/vs/workbench/contrib/files/browser/fileCommands.ts +++ b/src/vs/workbench/contrib/files/browser/fileCommands.ts @@ -628,21 +628,23 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ args: [ { isOptional: true, - name: 'viewType', - description: 'The editor view type', + name: 'New Untitled File args', + description: 'The editor view type and language ID if known', schema: { 'type': 'object', - 'required': ['viewType'], 'properties': { 'viewType': { 'type': 'string' + }, + 'languageId': { + 'type': 'string' } } } } ] }, - handler: async (accessor, args?: { viewType: string }) => { + handler: async (accessor, args?: { languageId?: string; viewType?: string }) => { const editorService = accessor.get(IEditorService); await editorService.openEditor({ @@ -650,7 +652,8 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ options: { override: args?.viewType, pinned: true - } + }, + languageId: args?.languageId, }); } }); -- cgit v1.2.3 From fecd1aa404ee0faaaf279e0e76bfd32277edf5af Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Fri, 1 Jul 2022 12:46:26 -0700 Subject: update command title for better localization (#153940) refs #153865 --- src/vs/workbench/browser/actions/layoutActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/browser/actions/layoutActions.ts b/src/vs/workbench/browser/actions/layoutActions.ts index 4b4cc8b38f0..9bf977172a8 100644 --- a/src/vs/workbench/browser/actions/layoutActions.ts +++ b/src/vs/workbench/browser/actions/layoutActions.ts @@ -1182,7 +1182,7 @@ registerAction2(class CustomizeLayoutAction extends Action2 { constructor() { super({ id: 'workbench.action.customizeLayout', - title: localize('customizeLayout', "Customize Layout..."), + title: { original: 'Customize Layout...', value: localize('customizeLayout', "Customize Layout...") }, f1: true, icon: configureLayoutIcon, menu: [ -- cgit v1.2.3 From 71b996eff4cef4405d1d1cc4fe308545dac0b255 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Fri, 1 Jul 2022 14:41:48 -0700 Subject: use ILocalizedString in a few places (#153950) --- .../browser/languageDetection.contribution.ts | 2 +- .../contrib/notebook/browser/controller/editActions.ts | 2 +- .../workbench/contrib/update/browser/update.contribution.ts | 12 ++++++------ .../welcomeGettingStarted/browser/gettingStartedService.ts | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/languageDetection/browser/languageDetection.contribution.ts b/src/vs/workbench/contrib/languageDetection/browser/languageDetection.contribution.ts index a931e2bb2f2..ef593cb3de1 100644 --- a/src/vs/workbench/contrib/languageDetection/browser/languageDetection.contribution.ts +++ b/src/vs/workbench/contrib/languageDetection/browser/languageDetection.contribution.ts @@ -123,7 +123,7 @@ registerAction2(class extends Action2 { constructor() { super({ id: detectLanguageCommandId, - title: localize('detectlang', 'Detect Language from Content'), + title: { value: localize('detectlang', 'Detect Language from Content'), original: 'Detect Language from Content' }, f1: true, precondition: ContextKeyExpr.and(NOTEBOOK_EDITOR_EDITABLE.toNegated(), EditorContextKeys.editorTextFocus), keybinding: { primary: KeyCode.KeyD | KeyMod.Alt | KeyMod.Shift, weight: KeybindingWeight.WorkbenchContrib } diff --git a/src/vs/workbench/contrib/notebook/browser/controller/editActions.ts b/src/vs/workbench/contrib/notebook/browser/controller/editActions.ts index 7250d2dc560..ebcdf94c782 100644 --- a/src/vs/workbench/contrib/notebook/browser/controller/editActions.ts +++ b/src/vs/workbench/contrib/notebook/browser/controller/editActions.ts @@ -469,7 +469,7 @@ registerAction2(class DetectCellLanguageAction extends NotebookCellAction { constructor() { super({ id: DETECT_CELL_LANGUAGE, - title: localize('detectLanguage', 'Accept Detected Language for Cell'), + title: { value: localize('detectLanguage', 'Accept Detected Language for Cell'), original: 'Accept Detected Language for Cell' }, f1: true, precondition: ContextKeyExpr.and(NOTEBOOK_EDITOR_EDITABLE, NOTEBOOK_CELL_EDITABLE), keybinding: { primary: KeyCode.KeyD | KeyMod.Alt | KeyMod.Shift, weight: KeybindingWeight.WorkbenchContrib } diff --git a/src/vs/workbench/contrib/update/browser/update.contribution.ts b/src/vs/workbench/contrib/update/browser/update.contribution.ts index 5d22660c689..1ff72278d33 100644 --- a/src/vs/workbench/contrib/update/browser/update.contribution.ts +++ b/src/vs/workbench/contrib/update/browser/update.contribution.ts @@ -34,8 +34,8 @@ class DownloadUpdateAction extends Action2 { constructor() { super({ id: 'update.downloadUpdate', - title: localize('downloadUpdate', "Download Update"), - category: product.nameShort, + title: { value: localize('downloadUpdate', "Download Update"), original: 'Download Update' }, + category: { value: product.nameShort, original: product.nameShort }, f1: true, precondition: CONTEXT_UPDATE_STATE.isEqualTo(StateType.AvailableForDownload) }); @@ -50,8 +50,8 @@ class InstallUpdateAction extends Action2 { constructor() { super({ id: 'update.installUpdate', - title: localize('installUpdate', "Install Update"), - category: product.nameShort, + title: { value: localize('installUpdate', "Install Update"), original: 'Install Update' }, + category: { value: product.nameShort, original: product.nameShort }, f1: true, precondition: CONTEXT_UPDATE_STATE.isEqualTo(StateType.Downloaded) }); @@ -66,8 +66,8 @@ class RestartToUpdateAction extends Action2 { constructor() { super({ id: 'update.restartToUpdate', - title: localize('restartToUpdate', "Restart to Update"), - category: product.nameShort, + title: { value: localize('restartToUpdate', "Restart to Update"), original: 'Restart to Update' }, + category: { value: product.nameShort, original: product.nameShort }, f1: true, precondition: CONTEXT_UPDATE_STATE.isEqualTo(StateType.Ready) }); diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts index 74b541681a6..dcbddfc4097 100644 --- a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts +++ b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts @@ -691,8 +691,8 @@ registerAction2(class extends Action2 { constructor() { super({ id: 'resetGettingStartedProgress', - category: 'Developer', - title: 'Reset Welcome Page Walkthrough Progress', + category: { original: 'Developer', value: localize('developer', "Developer") }, + title: { original: 'Reset Welcome Page Walkthrough Progress', value: localize('resetWelcomePageWalkthroughProgress', "Reset Welcome Page Walkthrough Progress") }, f1: true }); } -- cgit v1.2.3 From 562ec1e22c1f5a5038e092f2de2a894234abe366 Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Fri, 1 Jul 2022 21:40:30 -0400 Subject: Move debounce onto onDidRenderAsync --- src/vs/editor/contrib/markdownRenderer/browser/markdownRenderer.ts | 4 ++-- src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/vs') diff --git a/src/vs/editor/contrib/markdownRenderer/browser/markdownRenderer.ts b/src/vs/editor/contrib/markdownRenderer/browser/markdownRenderer.ts index 7220dbf1a4f..3956f8e4536 100644 --- a/src/vs/editor/contrib/markdownRenderer/browser/markdownRenderer.ts +++ b/src/vs/editor/contrib/markdownRenderer/browser/markdownRenderer.ts @@ -10,7 +10,7 @@ import { ILanguageService } from 'vs/editor/common/languages/language'; import { onUnexpectedError } from 'vs/base/common/errors'; import { tokenizeToString } from 'vs/editor/common/languages/textToHtmlTokenizer'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { Emitter } from 'vs/base/common/event'; +import { Emitter, Event } from 'vs/base/common/event'; import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { applyFontInfo } from 'vs/editor/browser/config/domFontInfo'; @@ -39,7 +39,7 @@ export class MarkdownRenderer { }); private readonly _onDidRenderAsync = new Emitter(); - readonly onDidRenderAsync = this._onDidRenderAsync.event; + readonly onDidRenderAsync = Event.debounce(this._onDidRenderAsync.event, (_, e) => e, 50); constructor( private readonly _options: IMarkdownRendererOptions, diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts b/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts index 6abaf65b377..e9d6c4c5130 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts @@ -172,7 +172,7 @@ export class SuggestDetailsWidget { const renderedContents = this._markdownRenderer.render(documentation); this._docs.appendChild(renderedContents.element); this._renderDisposeable.add(renderedContents); - this._renderDisposeable.add(Event.debounce(this._markdownRenderer.onDidRenderAsync, () => (last: Event, event: Event) => event, 50)(() => { + this._renderDisposeable.add(this._markdownRenderer.onDidRenderAsync(() => { this.layout(this._size.width, this._type.clientHeight + this._docs.clientHeight); this._onDidChangeContents.fire(this); })); -- cgit v1.2.3 From 7c78640d86e5de1ca0270912584d9d38beafeec1 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 2 Jul 2022 18:24:41 +0200 Subject: Cannot read properties of undefined (reading 'resource') (fix #153361) (#153960) --- src/vs/workbench/services/history/browser/historyService.ts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/vs') diff --git a/src/vs/workbench/services/history/browser/historyService.ts b/src/vs/workbench/services/history/browser/historyService.ts index e0fb71b15ed..6f73bd54add 100644 --- a/src/vs/workbench/services/history/browser/historyService.ts +++ b/src/vs/workbench/services/history/browser/historyService.ts @@ -993,6 +993,10 @@ export class HistoryService extends Disposable implements IHistoryService { try { const entriesParsed: ISerializedEditorHistoryEntry[] = JSON.parse(entriesRaw); for (const entryParsed of entriesParsed) { + if (!entryParsed.editor || !entryParsed.editor.resource) { + continue; // unexpected data format + } + try { entries.push({ ...entryParsed.editor, -- cgit v1.2.3 From c7a100ff1bf942cc94b9476a7652a1f9785cf22d Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 3 Jul 2022 08:28:20 -0700 Subject: Add missing register for onData listener --- .../contrib/terminal/browser/xterm/commandNavigationAddon.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/commandNavigationAddon.ts b/src/vs/workbench/contrib/terminal/browser/xterm/commandNavigationAddon.ts index 08174e3b53c..83de46d909f 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/commandNavigationAddon.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/commandNavigationAddon.ts @@ -34,9 +34,9 @@ export class CommandNavigationAddon extends Disposable implements ICommandTracke activate(terminal: Terminal): void { this._terminal = terminal; - this._terminal.onData(() => { + this._register(this._terminal.onData(() => { this._currentMarker = Boundary.Bottom; - }); + })); } constructor( -- cgit v1.2.3 From c01da07ec15759e8bb532468b2cb0f1fcf0eba93 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Sun, 3 Jul 2022 19:07:03 +0200 Subject: Fixes #153898. --- src/vs/editor/browser/widget/codeEditorWidget.ts | 26 +++++++++++++++++----- src/vs/editor/common/viewLayout/linesLayout.ts | 18 +++++++++++++-- src/vs/editor/common/viewLayout/viewLayout.ts | 7 ++++-- .../mergeEditor/browser/view/editorGutter.ts | 22 +++++------------- 4 files changed, 47 insertions(+), 26 deletions(-) (limited to 'src/vs') diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 1ba384d520f..f4e8c0d10db 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -564,27 +564,43 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE return this._modelData.viewModel.viewLayout.getWhitespaces(); } - private static _getVerticalOffsetForPosition(modelData: ModelData, modelLineNumber: number, modelColumn: number): number { + private static _getVerticalOffsetAfterPosition(modelData: ModelData, modelLineNumber: number, modelColumn: number, includeViewZones: boolean): number { const modelPosition = modelData.model.validatePosition({ lineNumber: modelLineNumber, column: modelColumn }); const viewPosition = modelData.viewModel.coordinatesConverter.convertModelPositionToViewPosition(modelPosition); - return modelData.viewModel.viewLayout.getVerticalOffsetForLineNumber(viewPosition.lineNumber); + return modelData.viewModel.viewLayout.getVerticalOffsetAfterLineNumber(viewPosition.lineNumber, includeViewZones); } - public getTopForLineNumber(lineNumber: number): number { + public getTopForLineNumber(lineNumber: number, includeViewZones: boolean = false): number { if (!this._modelData) { return -1; } - return CodeEditorWidget._getVerticalOffsetForPosition(this._modelData, lineNumber, 1); + return CodeEditorWidget._getVerticalOffsetForPosition(this._modelData, lineNumber, 1, includeViewZones); } public getTopForPosition(lineNumber: number, column: number): number { if (!this._modelData) { return -1; } - return CodeEditorWidget._getVerticalOffsetForPosition(this._modelData, lineNumber, column); + return CodeEditorWidget._getVerticalOffsetForPosition(this._modelData, lineNumber, column, false); + } + + private static _getVerticalOffsetForPosition(modelData: ModelData, modelLineNumber: number, modelColumn: number, includeViewZones: boolean = false): number { + const modelPosition = modelData.model.validatePosition({ + lineNumber: modelLineNumber, + column: modelColumn + }); + const viewPosition = modelData.viewModel.coordinatesConverter.convertModelPositionToViewPosition(modelPosition); + return modelData.viewModel.viewLayout.getVerticalOffsetForLineNumber(viewPosition.lineNumber, includeViewZones); + } + + public getBottomForLineNumber(lineNumber: number, includeViewZones: boolean = false): number { + if (!this._modelData) { + return -1; + } + return CodeEditorWidget._getVerticalOffsetAfterPosition(this._modelData, lineNumber, 1, includeViewZones); } public setHiddenAreas(ranges: IRange[]): void { diff --git a/src/vs/editor/common/viewLayout/linesLayout.ts b/src/vs/editor/common/viewLayout/linesLayout.ts index 01e2d26cf5a..7bb55aeef6e 100644 --- a/src/vs/editor/common/viewLayout/linesLayout.ts +++ b/src/vs/editor/common/viewLayout/linesLayout.ts @@ -482,7 +482,7 @@ export class LinesLayout { * @param lineNumber The line number * @return The sum of heights for all objects above `lineNumber`. */ - public getVerticalOffsetForLineNumber(lineNumber: number): number { + public getVerticalOffsetForLineNumber(lineNumber: number, includeViewZones = false): number { this._checkPendingChanges(); lineNumber = lineNumber | 0; @@ -493,11 +493,25 @@ export class LinesLayout { previousLinesHeight = 0; } - const previousWhitespacesHeight = this.getWhitespaceAccumulatedHeightBeforeLineNumber(lineNumber); + const previousWhitespacesHeight = this.getWhitespaceAccumulatedHeightBeforeLineNumber(lineNumber - (includeViewZones ? 1 : 0)); return previousLinesHeight + previousWhitespacesHeight + this._paddingTop; } + /** + * Get the vertical offset (the sum of heights for all objects above) a certain line number. + * + * @param lineNumber The line number + * @return The sum of heights for all objects above `lineNumber`. + */ + public getVerticalOffsetAfterLineNumber(lineNumber: number, includeViewZones = false): number { + this._checkPendingChanges(); + lineNumber = lineNumber | 0; + const previousLinesHeight = this._lineHeight * lineNumber; + const previousWhitespacesHeight = this.getWhitespaceAccumulatedHeightBeforeLineNumber(lineNumber + (includeViewZones ? 1 : 0)); + return previousLinesHeight + previousWhitespacesHeight + this._paddingTop; + } + /** * Returns if there is any whitespace in the document. */ diff --git a/src/vs/editor/common/viewLayout/viewLayout.ts b/src/vs/editor/common/viewLayout/viewLayout.ts index fa5013cac62..0acbe29204f 100644 --- a/src/vs/editor/common/viewLayout/viewLayout.ts +++ b/src/vs/editor/common/viewLayout/viewLayout.ts @@ -362,8 +362,11 @@ export class ViewLayout extends Disposable implements IViewLayout { } return hadAChange; } - public getVerticalOffsetForLineNumber(lineNumber: number): number { - return this._linesLayout.getVerticalOffsetForLineNumber(lineNumber); + public getVerticalOffsetForLineNumber(lineNumber: number, includeViewZones: boolean = false): number { + return this._linesLayout.getVerticalOffsetForLineNumber(lineNumber, includeViewZones); + } + public getVerticalOffsetAfterLineNumber(lineNumber: number, includeViewZones: boolean = false): number { + return this._linesLayout.getVerticalOffsetAfterLineNumber(lineNumber, includeViewZones); } public isAfterLines(verticalOffset: number): boolean { return this._linesLayout.isAfterLines(verticalOffset); diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts index 2b208650738..08a13900476 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts @@ -6,7 +6,6 @@ import { h } from 'vs/base/browser/dom'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; -import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { autorun, IReader, observableFromEvent, ObservableValue } from 'vs/workbench/contrib/audioCues/browser/observable'; import { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange'; @@ -68,15 +67,13 @@ export class EditorGutter extends D const visibleRange2 = new LineRange( visibleRange.startLineNumber, visibleRange.endLineNumber - visibleRange.startLineNumber - ); + ).deltaEnd(1); const gutterItems = this.itemProvider.getIntersectingGutterItems( visibleRange2, reader ); - const lineHeight = this._editor.getOptions().get(EditorOption.lineHeight); - for (const gutterItem of gutterItems) { if (!gutterItem.range.touches(visibleRange2)) { continue; @@ -99,19 +96,10 @@ export class EditorGutter extends D } const top = - (gutterItem.range.startLineNumber === 1 - ? -lineHeight - : this._editor.getTopForLineNumber( - gutterItem.range.startLineNumber - 1 - )) - - scrollTop + - lineHeight; - - const bottom = ( - gutterItem.range.endLineNumberExclusive <= this._editor.getModel()!.getLineCount() - ? this._editor.getTopForLineNumber(gutterItem.range.endLineNumberExclusive) - : this._editor.getTopForLineNumber(gutterItem.range.endLineNumberExclusive - 1) + lineHeight - ) - scrollTop; + gutterItem.range.startLineNumber <= this._editor.getModel()!.getLineCount() + ? this._editor.getTopForLineNumber(gutterItem.range.startLineNumber, true) - scrollTop + : this._editor.getBottomForLineNumber(gutterItem.range.startLineNumber - 1, false) - scrollTop; + const bottom = this._editor.getBottomForLineNumber(gutterItem.range.endLineNumberExclusive - 1, true) - scrollTop; const height = bottom - top; -- cgit v1.2.3 From 20324ac1370af77899d239d26000b3cd32ff4981 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Sun, 3 Jul 2022 19:06:40 +0200 Subject: navigation now only considers actual conflicts. --- .../mergeEditor/browser/commands/commands.ts | 4 +-- .../contrib/mergeEditor/browser/view/viewModel.ts | 29 +++++++++++++++------- 2 files changed, 22 insertions(+), 11 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts b/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts index 4fa542c981d..375c202ea6a 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts @@ -175,7 +175,7 @@ export class GoToNextConflict extends Action2 { run(accessor: ServicesAccessor): void { const { activeEditorPane } = accessor.get(IEditorService); if (activeEditorPane instanceof MergeEditor) { - activeEditorPane.viewModel.get()?.goToNextConflict(); + activeEditorPane.viewModel.get()?.goToNextModifiedBaseRange(true); } } } @@ -200,7 +200,7 @@ export class GoToPreviousConflict extends Action2 { run(accessor: ServicesAccessor): void { const { activeEditorPane } = accessor.get(IEditorService); if (activeEditorPane instanceof MergeEditor) { - activeEditorPane.viewModel.get()?.goToPreviousConflict(); + activeEditorPane.viewModel.get()?.goToPreviousModifiedBaseRange(true); } } } diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts index b53549fea4b..3f90643ea4a 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts @@ -3,13 +3,12 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { findLast, lastOrDefault } from 'vs/base/common/arrays'; +import { findLast } from 'vs/base/common/arrays'; import { ScrollType } from 'vs/editor/common/editorCommon'; import { derivedObservable, derivedObservableWithWritableCache, IReader, ITransaction, ObservableValue, transaction } from 'vs/workbench/contrib/audioCues/browser/observable'; import { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange'; import { MergeEditorModel } from 'vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel'; import { ModifiedBaseRange, ModifiedBaseRangeState } from 'vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange'; -import { elementAtOrUndefined } from 'vs/workbench/contrib/mergeEditor/browser/utils'; import { CodeEditorView } from 'vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView'; import { InputCodeEditorView } from 'vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView'; import { ResultCodeEditorView } from 'vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView'; @@ -78,7 +77,7 @@ export class MergeEditorViewModel { this.model.setState(baseRange, state, true, tx); } - public goToConflict(getModifiedBaseRange: (editor: CodeEditorView, curLineNumber: number) => ModifiedBaseRange | undefined): void { + private goToConflict(getModifiedBaseRange: (editor: CodeEditorView, curLineNumber: number) => ModifiedBaseRange | undefined): void { const lastFocusedEditor = this.lastFocusedEditor.get(); if (!lastFocusedEditor) { return; @@ -98,23 +97,35 @@ export class MergeEditorViewModel { } } - public goToNextConflict(): void { + public goToNextModifiedBaseRange(onlyConflicting: boolean): void { this.goToConflict( (e, l) => this.model.modifiedBaseRanges .get() - .find((r) => this.getRange(e, r, undefined).startLineNumber > l) || - elementAtOrUndefined(this.model.modifiedBaseRanges.get(), 0) + .find( + (r) => + (!onlyConflicting || r.isConflicting) && + this.getRange(e, r, undefined).startLineNumber > l + ) || + this.model.modifiedBaseRanges + .get() + .find((r) => !onlyConflicting || r.isConflicting) ); } - public goToPreviousConflict(): void { + public goToPreviousModifiedBaseRange(onlyConflicting: boolean): void { this.goToConflict( (e, l) => findLast( this.model.modifiedBaseRanges.get(), - (r) => this.getRange(e, r, undefined).endLineNumberExclusive < l - ) || lastOrDefault(this.model.modifiedBaseRanges.get()) + (r) => + (!onlyConflicting || r.isConflicting) && + this.getRange(e, r, undefined).endLineNumberExclusive < l + ) || + findLast( + this.model.modifiedBaseRanges.get(), + (r) => !onlyConflicting || r.isConflicting + ) ); } -- cgit v1.2.3 From fc90795932e82ab75b2a69d52f6103a3a86f05a3 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 1 Jul 2022 18:26:11 +0200 Subject: Use middle click on a checkbox to toggle its state. --- .../browser/view/editors/inputCodeEditorView.ts | 32 ++++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts index 1610a9a0b0d..aadd274e6e1 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts @@ -140,6 +140,21 @@ export class InputCodeEditorView extends CodeEditorView { .withInputValue(this.inputNumber, value), tx ), + toggleBothSides() { + transaction(tx => { + const state = model + .getState(baseRange) + .get(); + model.setState( + baseRange, + state + .toggle(inputNumber) + .toggle(inputNumber === 1 ? 2 : 1), + true, + tx + ); + }); + }, getContextMenuActions: () => { const state = model.getState(baseRange).get(); const handled = model.isHandled(baseRange).get(); @@ -233,6 +248,7 @@ export interface ModifiedBaseRangeGutterItemInfo extends IGutterItemInfo { enabled: IObservable; toggleState: IObservable; setState(value: boolean, tx: ITransaction): void; + toggleBothSides(): void; getContextMenuActions(): readonly IAction[]; } @@ -257,22 +273,28 @@ export class MergeConflictGutterItemView extends Disposable implements IGutterIt this._register( dom.addDisposableListener(checkBox.domNode, dom.EventType.MOUSE_DOWN, (e) => { - if (e.button === 2) { - const item = this.item.get(); - if (!item) { - return; - } + const item = this.item.get(); + if (!item) { + return; + } + if (e.button === /* Right */ 2) { contextMenuService.showContextMenu({ getAnchor: () => checkBox.domNode, getActions: item.getContextMenuActions, }); + e.stopPropagation(); + e.preventDefault(); + } else if (e.button === /* Middle */ 1) { + item.toggleBothSides(); + e.stopPropagation(); e.preventDefault(); } }) ); + checkBox.domNode.classList.add('accept-conflict-group'); this._register( -- cgit v1.2.3 From 63d90d3a34697d2a008d45da3a6460ec9a602352 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Sun, 3 Jul 2022 19:45:01 +0200 Subject: Moves observables to base/common. Adds observable tests & logging. --- src/vs/base/common/observable.ts | 30 + src/vs/base/common/observableImpl/autorun.ts | 167 +++++ src/vs/base/common/observableImpl/base.ts | 244 +++++++ src/vs/base/common/observableImpl/derived.ts | 167 +++++ src/vs/base/common/observableImpl/logging.ts | 312 +++++++++ src/vs/base/common/observableImpl/utils.ts | 281 ++++++++ src/vs/base/test/common/observable.test.ts | 468 ++++++++++++++ .../browser/audioCueLineFeatureContribution.ts | 9 +- .../contrib/audioCues/browser/audioCueService.ts | 10 +- .../contrib/audioCues/browser/observable.ts | 718 +-------------------- .../audioCues/test/browser/observable.test.ts | 468 ++++++++++++++ 11 files changed, 2181 insertions(+), 693 deletions(-) create mode 100644 src/vs/base/common/observable.ts create mode 100644 src/vs/base/common/observableImpl/autorun.ts create mode 100644 src/vs/base/common/observableImpl/base.ts create mode 100644 src/vs/base/common/observableImpl/derived.ts create mode 100644 src/vs/base/common/observableImpl/logging.ts create mode 100644 src/vs/base/common/observableImpl/utils.ts create mode 100644 src/vs/base/test/common/observable.test.ts create mode 100644 src/vs/workbench/contrib/audioCues/test/browser/observable.test.ts (limited to 'src/vs') diff --git a/src/vs/base/common/observable.ts b/src/vs/base/common/observable.ts new file mode 100644 index 00000000000..c588d68b9f6 --- /dev/null +++ b/src/vs/base/common/observable.ts @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export { + IObservable, + IObserver, + IReader, + ISettable, + ISettableObservable, + ITransaction, + observableValue, + transaction, +} from 'vs/base/common/observableImpl/base'; +export { derived } from 'vs/base/common/observableImpl/derived'; +export { + autorun, + autorunDelta, + autorunHandleChanges, + autorunWithStore, +} from 'vs/base/common/observableImpl/autorun'; +export * from 'vs/base/common/observableImpl/utils'; + +import { ConsoleObservableLogger, setLogger } from 'vs/base/common/observableImpl/logging'; + +const enableLogging = false; +if (enableLogging) { + setLogger(new ConsoleObservableLogger()); +} diff --git a/src/vs/base/common/observableImpl/autorun.ts b/src/vs/base/common/observableImpl/autorun.ts new file mode 100644 index 00000000000..6efe4736783 --- /dev/null +++ b/src/vs/base/common/observableImpl/autorun.ts @@ -0,0 +1,167 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IReader, IObservable, IObserver } from 'vs/base/common/observableImpl/base'; +import { getLogger } from 'vs/base/common/observableImpl/logging'; + +export function autorun(debugName: string, fn: (reader: IReader) => void): IDisposable { + return new AutorunObserver(debugName, fn, undefined); +} + +interface IChangeContext { + readonly changedObservable: IObservable; + readonly change: unknown; + + didChange(observable: IObservable): this is { change: TChange }; +} + +export function autorunHandleChanges( + debugName: string, + options: { + /** + * Returns if this change should cause a re-run of the autorun. + */ + handleChange: (context: IChangeContext) => boolean; + }, + fn: (reader: IReader) => void +): IDisposable { + return new AutorunObserver(debugName, fn, options.handleChange); +} + +export function autorunWithStore( + fn: (reader: IReader, store: DisposableStore) => void, + debugName: string +): IDisposable { + const store = new DisposableStore(); + const disposable = autorun( + debugName, + reader => { + store.clear(); + fn(reader, store); + } + ); + return toDisposable(() => { + disposable.dispose(); + store.dispose(); + }); +} + +export class AutorunObserver implements IObserver, IReader, IDisposable { + public needsToRun = true; + private updateCount = 0; + private disposed = false; + + /** + * The actual dependencies. + */ + private _dependencies = new Set>(); + public get dependencies() { + return this._dependencies; + } + + /** + * Dependencies that have to be removed when {@link runFn} ran through. + */ + private staleDependencies = new Set>(); + + constructor( + public readonly debugName: string, + private readonly runFn: (reader: IReader) => void, + private readonly _handleChange: ((context: IChangeContext) => boolean) | undefined + ) { + getLogger()?.handleAutorunCreated(this); + this.runIfNeeded(); + } + + public subscribeTo(observable: IObservable) { + // In case the run action disposes the autorun + if (this.disposed) { + return; + } + this._dependencies.add(observable); + if (!this.staleDependencies.delete(observable)) { + observable.addObserver(this); + } + } + + public handleChange(observable: IObservable, change: TChange): void { + const shouldReact = this._handleChange ? this._handleChange({ + changedObservable: observable, + change, + didChange: o => o === observable as any, + }) : true; + this.needsToRun = this.needsToRun || shouldReact; + + if (this.updateCount === 0) { + this.runIfNeeded(); + } + } + + public beginUpdate(): void { + this.updateCount++; + } + + public endUpdate(): void { + this.updateCount--; + if (this.updateCount === 0) { + this.runIfNeeded(); + } + } + + private runIfNeeded(): void { + if (!this.needsToRun) { + return; + } + // Assert: this.staleDependencies is an empty set. + const emptySet = this.staleDependencies; + this.staleDependencies = this._dependencies; + this._dependencies = emptySet; + + this.needsToRun = false; + + getLogger()?.handleAutorunTriggered(this); + + try { + this.runFn(this); + } finally { + // We don't want our observed observables to think that they are (not even temporarily) not being observed. + // Thus, we only unsubscribe from observables that are definitely not read anymore. + for (const o of this.staleDependencies) { + o.removeObserver(this); + } + this.staleDependencies.clear(); + } + } + + public dispose(): void { + this.disposed = true; + for (const o of this._dependencies) { + o.removeObserver(this); + } + this._dependencies.clear(); + } + + public toString(): string { + return `Autorun<${this.debugName}>`; + } +} + +export namespace autorun { + export const Observer = AutorunObserver; +} +export function autorunDelta( + name: string, + observable: IObservable, + handler: (args: { lastValue: T | undefined; newValue: T }) => void +): IDisposable { + let _lastValue: T | undefined; + return autorun(name, (reader) => { + const newValue = observable.read(reader); + const lastValue = _lastValue; + _lastValue = newValue; + handler({ lastValue, newValue }); + }); +} diff --git a/src/vs/base/common/observableImpl/base.ts b/src/vs/base/common/observableImpl/base.ts new file mode 100644 index 00000000000..fd91e6f8d8d --- /dev/null +++ b/src/vs/base/common/observableImpl/base.ts @@ -0,0 +1,244 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import type { derived } from 'vs/base/common/observableImpl/derived'; +import { getLogger } from 'vs/base/common/observableImpl/logging'; + +export interface IObservable { + readonly TChange: TChange; + + /** + * Reads the current value. + * + * Must not be called from {@link IObserver.handleChange}. + */ + get(): T; + + /** + * Adds an observer. + */ + addObserver(observer: IObserver): void; + removeObserver(observer: IObserver): void; + + /** + * Subscribes the reader to this observable and returns the current value of this observable. + */ + read(reader: IReader): T; + + map(fn: (value: T) => TNew): IObservable; + + readonly debugName: string; +} + +export interface IReader { + /** + * Reports an observable that was read. + * + * Is called by {@link IObservable.read}. + */ + subscribeTo(observable: IObservable): void; +} + +export interface IObserver { + /** + * Indicates that an update operation is about to begin. + * + * During an update, invariants might not hold for subscribed observables and + * change events might be delayed. + * However, all changes must be reported before all update operations are over. + */ + beginUpdate(observable: IObservable): void; + + /** + * Is called by a subscribed observable immediately after it notices a change. + * + * When {@link IObservable.get} returns and no change has been reported, + * there has been no change for that observable. + * + * Implementations must not call into other observables! + * The change should be processed when {@link IObserver.endUpdate} is called. + */ + handleChange(observable: IObservable, change: TChange): void; + + /** + * Indicates that an update operation has completed. + */ + endUpdate(observable: IObservable): void; +} + +export interface ISettable { + set(value: T, transaction: ITransaction | undefined, change: TChange): void; +} + +export interface ITransaction { + /** + * Calls `Observer.beginUpdate` immediately + * and `Observer.endUpdate` when the transaction is complete. + */ + updateObserver( + observer: IObserver, + observable: IObservable + ): void; +} + +let _derived: typeof derived; +/** + * @internal + * This is to allow splitting files. +*/ +export function _setDerived(derived: typeof _derived) { + _derived = derived; +} + +export abstract class ConvenientObservable implements IObservable { + get TChange(): TChange { return null!; } + + public abstract get(): T; + public abstract addObserver(observer: IObserver): void; + public abstract removeObserver(observer: IObserver): void; + + /** @sealed */ + public read(reader: IReader): T { + reader.subscribeTo(this); + return this.get(); + } + + /** @sealed */ + public map(fn: (value: T) => TNew): IObservable { + return _derived( + () => { + const name = getFunctionName(fn); + return name !== undefined ? name : `${this.debugName} (mapped)`; + }, + (reader) => fn(this.read(reader)) + ); + } + + public abstract get debugName(): string; +} + +export abstract class BaseObservable extends ConvenientObservable { + protected readonly observers = new Set(); + + /** @sealed */ + public addObserver(observer: IObserver): void { + const len = this.observers.size; + this.observers.add(observer); + if (len === 0) { + this.onFirstObserverAdded(); + } + } + + /** @sealed */ + public removeObserver(observer: IObserver): void { + const deleted = this.observers.delete(observer); + if (deleted && this.observers.size === 0) { + this.onLastObserverRemoved(); + } + } + + protected onFirstObserverAdded(): void { } + protected onLastObserverRemoved(): void { } +} + +export function transaction(fn: (tx: ITransaction) => void, getDebugName?: () => string): void { + const tx = new TransactionImpl(fn, getDebugName); + try { + getLogger()?.handleBeginTransaction(tx); + fn(tx); + } finally { + tx.finish(); + getLogger()?.handleEndTransaction(); + } +} + +export function getFunctionName(fn: Function): string | undefined { + const fnSrc = fn.toString(); + // Pattern: /** @description ... */ + const regexp = /\/\*\*\s*@description\s*([^*]*)\*\//; + const match = regexp.exec(fnSrc); + const result = match ? match[1] : undefined; + return result?.trim(); +} + +export class TransactionImpl implements ITransaction { + private updatingObservers: { observer: IObserver; observable: IObservable }[] | null = []; + + constructor(private readonly fn: Function, private readonly _getDebugName?: () => string) { } + + public getDebugName(): string | undefined { + if (this._getDebugName) { + return this._getDebugName(); + } + return getFunctionName(this.fn); + } + + public updateObserver( + observer: IObserver, + observable: IObservable + ): void { + this.updatingObservers!.push({ observer, observable }); + observer.beginUpdate(observable); + } + + public finish(): void { + const updatingObservers = this.updatingObservers!; + // Prevent anyone from updating observers from now on. + this.updatingObservers = null; + for (const { observer, observable } of updatingObservers) { + observer.endUpdate(observable); + } + } +} + +export interface ISettableObservable extends IObservable, ISettable { +} + +export function observableValue(name: string, initialValue: T): ISettableObservable { + return new ObservableValue(name, initialValue); +} + +export class ObservableValue + extends BaseObservable + implements ISettableObservable +{ + private value: T; + + constructor(public readonly debugName: string, initialValue: T) { + super(); + this.value = initialValue; + } + + public get(): T { + return this.value; + } + + public set(value: T, tx: ITransaction | undefined, change: TChange): void { + if (this.value === value) { + return; + } + + if (!tx) { + transaction((tx) => { + this.set(value, tx, change); + }, () => `Setting ${this.debugName}`); + return; + } + + const oldValue = this.value; + this.value = value; + getLogger()?.handleObservableChanged(this, { oldValue, newValue: value, change, didChange: true }); + + for (const observer of this.observers) { + tx.updateObserver(observer, this); + observer.handleChange(this, change); + } + } + + override toString(): string { + return `${this.debugName}: ${this.value}`; + } +} + diff --git a/src/vs/base/common/observableImpl/derived.ts b/src/vs/base/common/observableImpl/derived.ts new file mode 100644 index 00000000000..84a93132f15 --- /dev/null +++ b/src/vs/base/common/observableImpl/derived.ts @@ -0,0 +1,167 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IReader, IObservable, BaseObservable, IObserver, _setDerived } from 'vs/base/common/observableImpl/base'; +import { getLogger } from 'vs/base/common/observableImpl/logging'; + +export function derived(debugName: string | (() => string), computeFn: (reader: IReader) => T): IObservable { + return new Derived(debugName, computeFn); +} + +_setDerived(derived); + +export class Derived extends BaseObservable implements IReader, IObserver { + private hadValue = false; + private hasValue = false; + private value: T | undefined = undefined; + private updateCount = 0; + + private _dependencies = new Set>(); + public get dependencies(): ReadonlySet> { + return this._dependencies; + } + + /** + * Dependencies that have to be removed when {@link runFn} ran through. + */ + private staleDependencies = new Set>(); + + public override get debugName(): string { + return typeof this._debugName === 'function' ? this._debugName() : this._debugName; + } + + constructor( + private readonly _debugName: string | (() => string), + private readonly computeFn: (reader: IReader) => T + ) { + super(); + + getLogger()?.handleDerivedCreated(this); + } + + protected override onLastObserverRemoved(): void { + /** + * We are not tracking changes anymore, thus we have to assume + * that our cache is invalid. + */ + this.hasValue = false; + this.hadValue = false; + this.value = undefined; + for (const d of this._dependencies) { + d.removeObserver(this); + } + this._dependencies.clear(); + } + + public get(): T { + if (this.observers.size === 0) { + // Cache is not valid and don't refresh the cache. + // Observables should not be read in non-reactive contexts. + const result = this.computeFn(this); + // Clear new dependencies + this.onLastObserverRemoved(); + return result; + } + + if (this.updateCount > 0 && this.hasValue) { + // Refresh dependencies + for (const d of this._dependencies) { + // Maybe `.get()` triggers `handleChange`? + d.get(); + if (!this.hasValue) { + // The other dependencies will refresh on demand + break; + } + } + } + + if (!this.hasValue) { + const emptySet = this.staleDependencies; + this.staleDependencies = this._dependencies; + this._dependencies = emptySet; + + const oldValue = this.value; + try { + this.value = this.computeFn(this); + } finally { + // We don't want our observed observables to think that they are (not even temporarily) not being observed. + // Thus, we only unsubscribe from observables that are definitely not read anymore. + for (const o of this.staleDependencies) { + o.removeObserver(this); + } + this.staleDependencies.clear(); + } + + this.hasValue = true; + const didChange = this.hadValue && oldValue !== this.value; + getLogger()?.handleDerivedRecomputed(this, { + oldValue, + newValue: this.value, + change: undefined, + didChange + }); + if (didChange) { + for (const r of this.observers) { + r.handleChange(this, undefined); + } + } + } + return this.value!; + } + + // IObserver Implementation + public beginUpdate(): void { + if (this.updateCount === 0) { + for (const r of this.observers) { + r.beginUpdate(this); + } + } + this.updateCount++; + } + + public handleChange( + _observable: IObservable, + _change: TChange + ): void { + if (this.hasValue) { + this.hadValue = true; + this.hasValue = false; + } + + // Not in transaction: Recompute & inform observers immediately + if (this.updateCount === 0 && this.observers.size > 0) { + this.get(); + } + + // Otherwise, recompute in `endUpdate` or on demand. + } + + public endUpdate(): void { + this.updateCount--; + if (this.updateCount === 0) { + if (this.observers.size > 0) { + // Propagate invalidation + this.get(); + } + + for (const r of this.observers) { + r.endUpdate(this); + } + } + } + + // IReader Implementation + public subscribeTo(observable: IObservable) { + this._dependencies.add(observable); + // We are already added as observer for stale dependencies. + if (!this.staleDependencies.delete(observable)) { + observable.addObserver(this); + } + } + + override toString(): string { + return `LazyDerived<${this.debugName}>`; + } +} diff --git a/src/vs/base/common/observableImpl/logging.ts b/src/vs/base/common/observableImpl/logging.ts new file mode 100644 index 00000000000..0c221d0c700 --- /dev/null +++ b/src/vs/base/common/observableImpl/logging.ts @@ -0,0 +1,312 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { AutorunObserver } from 'vs/base/common/observableImpl/autorun'; +import { IObservable, ObservableValue, TransactionImpl } from 'vs/base/common/observableImpl/base'; +import { Derived } from 'vs/base/common/observableImpl/derived'; +import { FromEventObservable } from 'vs/base/common/observableImpl/utils'; + +let globalObservableLogger: IObservableLogger | undefined; + +export function setLogger(logger: IObservableLogger): void { + globalObservableLogger = logger; +} + +export function getLogger(): IObservableLogger | undefined { + return globalObservableLogger; +} + +interface IChangeInformation { + oldValue: unknown; + newValue: unknown; + change: unknown; + didChange: boolean; +} + +export interface IObservableLogger { + handleObservableChanged(observable: ObservableValue, info: IChangeInformation): void; + handleFromEventObservableTriggered(observable: FromEventObservable, info: IChangeInformation): void; + + handleAutorunCreated(autorun: AutorunObserver): void; + handleAutorunTriggered(autorun: AutorunObserver): void; + + handleDerivedCreated(observable: Derived): void; + handleDerivedRecomputed(observable: Derived, info: IChangeInformation): void; + + handleBeginTransaction(transaction: TransactionImpl): void; + handleEndTransaction(): void; +} + +export class ConsoleObservableLogger implements IObservableLogger { + private indentation = 0; + + private textToConsoleArgs(text: ConsoleText): unknown[] { + return consoleTextToArgs([ + normalText(repeat('| ', this.indentation)), + text, + ]); + } + + private formatInfo(info: IChangeInformation): ConsoleText[] { + return info.didChange + ? [ + normalText(` `), + styled(formatValue(info.oldValue, 70), { + color: 'red', + strikeThrough: true, + }), + normalText(` `), + styled(formatValue(info.newValue, 60), { + color: 'green', + }), + ] + : [normalText(` (unchanged)`)]; + } + + handleObservableChanged(observable: IObservable, info: IChangeInformation): void { + console.log(...this.textToConsoleArgs([ + formatKind('observable value changed'), + styled(observable.debugName, { color: 'BlueViolet' }), + ...this.formatInfo(info), + ])); + } + + private readonly changedObservablesSets = new WeakMap>>(); + + formatChanges(changes: Set>): ConsoleText | undefined { + if (changes.size === 0) { + return undefined; + } + return styled( + ' (changed deps: ' + + [...changes].map((o) => o.debugName).join(', ') + + ')', + { color: 'gray' } + ); + } + + handleDerivedCreated(derived: Derived): void { + const existingHandleChange = derived.handleChange; + this.changedObservablesSets.set(derived, new Set()); + derived.handleChange = (observable, change) => { + this.changedObservablesSets.get(derived)!.add(observable); + return existingHandleChange.apply(derived, [observable, change]); + }; + } + + handleDerivedRecomputed(derived: Derived, info: IChangeInformation): void { + const changedObservables = this.changedObservablesSets.get(derived)!; + console.log(...this.textToConsoleArgs([ + formatKind('derived recomputed'), + styled(derived.debugName, { color: 'BlueViolet' }), + ...this.formatInfo(info), + this.formatChanges(changedObservables) + ])); + changedObservables.clear(); + } + + handleFromEventObservableTriggered(observable: FromEventObservable, info: IChangeInformation): void { + console.log(...this.textToConsoleArgs([ + formatKind('observable from event triggered'), + styled(observable.debugName, { color: 'BlueViolet' }), + ...this.formatInfo(info), + ])); + } + + handleAutorunCreated(autorun: AutorunObserver): void { + const existingHandleChange = autorun.handleChange; + this.changedObservablesSets.set(autorun, new Set()); + autorun.handleChange = (observable, change) => { + this.changedObservablesSets.get(autorun)!.add(observable); + return existingHandleChange.apply(autorun, [observable, change]); + }; + } + + handleAutorunTriggered(autorun: AutorunObserver): void { + const changedObservables = this.changedObservablesSets.get(autorun)!; + console.log(...this.textToConsoleArgs([ + formatKind('autorun'), + styled(autorun.debugName, { color: 'BlueViolet' }), + this.formatChanges(changedObservables) + ])); + changedObservables.clear(); + } + + handleBeginTransaction(transaction: TransactionImpl): void { + let transactionName = transaction.getDebugName(); + if (transactionName === undefined) { + transactionName = ''; + } + console.log(...this.textToConsoleArgs([ + formatKind('transaction'), + styled(transactionName, { color: 'BlueViolet' }), + ])); + this.indentation++; + } + + handleEndTransaction(): void { + this.indentation--; + } +} + +type ConsoleText = + | (ConsoleText | undefined)[] + | { text: string; style: string; data?: Record } + | { data: Record }; + +function consoleTextToArgs(text: ConsoleText): unknown[] { + const styles = new Array(); + const initial = {}; + const data = initial; + let firstArg = ''; + + function process(t: ConsoleText): void { + if ('length' in t) { + for (const item of t) { + if (item) { + process(item); + } + } + } else if ('text' in t) { + firstArg += `%c${t.text}`; + styles.push(t.style); + if (t.data) { + Object.assign(data, t.data); + } + } else if ('data' in t) { + Object.assign(data, t.data); + } + } + + process(text); + + const result = [firstArg, ...styles]; + if (Object.keys(data).length > 0) { + result.push(data); + } + + return result; +} + +function normalText(text: string): ConsoleText { + return styled(text, { color: 'black' }); +} + +function formatKind(kind: string): ConsoleText { + return styled(padStr(`${kind}: `, 10), { color: 'black', bold: true }); +} + +function styled( + text: string, + options: { color: string; strikeThrough?: boolean; bold?: boolean } = { + color: 'black', + } +): ConsoleText { + function objToCss(styleObj: Record): string { + return Object.entries(styleObj).reduce( + (styleString, [propName, propValue]) => { + return `${styleString}${propName}:${propValue};`; + }, + '' + ); + } + + const style: Record = { + color: options.color, + }; + if (options.strikeThrough) { + style['text-decoration'] = 'line-through'; + } + if (options.bold) { + style['font-weight'] = 'bold'; + } + + return { + text, + style: objToCss(style), + }; +} + +function formatValue(value: unknown, availableLen: number): string { + switch (typeof value) { + case 'number': + return '' + value; + case 'string': + if (value.length + 2 <= availableLen) { + return `"${value}"`; + } + return `"${value.substr(0, availableLen - 7)}"+...`; + + case 'boolean': + return value ? 'true' : 'false'; + case 'undefined': + return 'undefined'; + case 'object': + if (value === null) { + return 'null'; + } + if (Array.isArray(value)) { + return formatArray(value, availableLen); + } + return formatObject(value, availableLen); + case 'symbol': + return value.toString(); + case 'function': + return `[[Function${value.name ? ' ' + value.name : ''}]]`; + default: + return '' + value; + } +} + +function formatArray(value: unknown[], availableLen: number): string { + let result = '[ '; + let first = true; + for (const val of value) { + if (!first) { + result += ', '; + } + if (result.length - 5 > availableLen) { + result += '...'; + break; + } + first = false; + result += `${formatValue(val, availableLen - result.length)}`; + } + result += ' ]'; + return result; +} + +function formatObject(value: object, availableLen: number): string { + let result = '{ '; + let first = true; + for (const [key, val] of Object.entries(value)) { + if (!first) { + result += ', '; + } + if (result.length - 5 > availableLen) { + result += '...'; + break; + } + first = false; + result += `${key}: ${formatValue(val, availableLen - result.length)}`; + } + result += ' }'; + return result; +} + +function repeat(str: string, count: number): string { + let result = ''; + for (let i = 1; i <= count; i++) { + result += str; + } + return result; +} + +function padStr(str: string, length: number): string { + while (str.length < length) { + str += ' '; + } + return str; +} diff --git a/src/vs/base/common/observableImpl/utils.ts b/src/vs/base/common/observableImpl/utils.ts new file mode 100644 index 00000000000..0b07d089b83 --- /dev/null +++ b/src/vs/base/common/observableImpl/utils.ts @@ -0,0 +1,281 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { autorun } from 'vs/base/common/observableImpl/autorun'; +import { IObservable, BaseObservable, transaction, IReader, ITransaction, ConvenientObservable, IObserver, observableValue, getFunctionName } from 'vs/base/common/observableImpl/base'; +import { derived } from 'vs/base/common/observableImpl/derived'; +import { Event } from 'vs/base/common/event'; +import { getLogger } from 'vs/base/common/observableImpl/logging'; + +export function constObservable(value: T): IObservable { + return new ConstObservable(value); +} + +class ConstObservable extends ConvenientObservable { + constructor(private readonly value: T) { + super(); + } + + public override get debugName(): string { + return this.toString(); + } + + public get(): T { + return this.value; + } + public addObserver(observer: IObserver): void { + // NO OP + } + public removeObserver(observer: IObserver): void { + // NO OP + } + + override toString(): string { + return `Const: ${this.value}`; + } +} + + +export function observableFromPromise(promise: Promise): IObservable<{ value?: T }> { + const observable = observableValue<{ value?: T }>('promiseValue', {}); + promise.then((value) => { + observable.set({ value }, undefined); + }); + return observable; +} + +export function waitForState(observable: IObservable, predicate: (state: T) => state is TState): Promise; +export function waitForState(observable: IObservable, predicate: (state: T) => boolean): Promise; +export function waitForState(observable: IObservable, predicate: (state: T) => boolean): Promise { + return new Promise(resolve => { + const d = autorun('waitForState', reader => { + const currentState = observable.read(reader); + if (predicate(currentState)) { + d.dispose(); + resolve(currentState); + } + }); + }); +} + +export function observableFromEvent( + event: Event, + getValue: (args: TArgs | undefined) => T +): IObservable { + return new FromEventObservable(event, getValue); +} + +export class FromEventObservable extends BaseObservable { + private value: T | undefined; + private hasValue = false; + private subscription: IDisposable | undefined; + + constructor( + private readonly event: Event, + private readonly getValue: (args: TArgs | undefined) => T + ) { + super(); + } + + private getDebugName(): string | undefined { + return getFunctionName(this.getValue); + } + + public get debugName(): string { + const name = this.getDebugName(); + return 'From Event' + (name ? `: ${name}` : ''); + } + + protected override onFirstObserverAdded(): void { + this.subscription = this.event(this.handleEvent); + } + + private readonly handleEvent = (args: TArgs | undefined) => { + const newValue = this.getValue(args); + + const didChange = this.value !== newValue; + + getLogger()?.handleFromEventObservableTriggered(this, { oldValue: this.value, newValue, change: undefined, didChange }); + + if (didChange) { + this.value = newValue; + + if (this.hasValue) { + transaction( + (tx) => { + for (const o of this.observers) { + tx.updateObserver(o, this); + o.handleChange(this, undefined); + } + }, + () => { + const name = this.getDebugName(); + return 'Event fired' + (name ? `: ${name}` : ''); + } + ); + } + this.hasValue = true; + } + }; + + protected override onLastObserverRemoved(): void { + this.subscription!.dispose(); + this.subscription = undefined; + this.hasValue = false; + this.value = undefined; + } + + public get(): T { + if (this.subscription) { + if (!this.hasValue) { + this.handleEvent(undefined); + } + return this.value!; + } else { + // no cache, as there are no subscribers to keep it updated + return this.getValue(undefined); + } + } +} + +export namespace observableFromEvent { + export const Observer = FromEventObservable; +} + +export function observableSignalFromEvent( + debugName: string, + event: Event +): IObservable { + return new FromEventObservableSignal(debugName, event); +} + +class FromEventObservableSignal extends BaseObservable { + private subscription: IDisposable | undefined; + + constructor( + public readonly debugName: string, + private readonly event: Event, + ) { + super(); + } + + protected override onFirstObserverAdded(): void { + this.subscription = this.event(this.handleEvent); + } + + private readonly handleEvent = () => { + transaction( + (tx) => { + for (const o of this.observers) { + tx.updateObserver(o, this); + o.handleChange(this, undefined); + } + }, + () => this.debugName + ); + }; + + protected override onLastObserverRemoved(): void { + this.subscription!.dispose(); + this.subscription = undefined; + } + + public override get(): void { + // NO OP + } +} + +export function debouncedObservable(observable: IObservable, debounceMs: number, disposableStore: DisposableStore): IObservable { + const debouncedObservable = observableValue('debounced', undefined); + + let timeout: any = undefined; + + disposableStore.add(autorun('debounce', reader => { + const value = observable.read(reader); + + if (timeout) { + clearTimeout(timeout); + } + timeout = setTimeout(() => { + transaction(tx => { + debouncedObservable.set(value, tx); + }); + }, debounceMs); + + })); + + return debouncedObservable; +} + +export function wasEventTriggeredRecently(event: Event, timeoutMs: number, disposableStore: DisposableStore): IObservable { + const observable = observableValue('triggeredRecently', false); + + let timeout: any = undefined; + + disposableStore.add(event(() => { + observable.set(true, undefined); + + if (timeout) { + clearTimeout(timeout); + } + timeout = setTimeout(() => { + observable.set(false, undefined); + }, timeoutMs); + })); + + return observable; +} + +/** + * This ensures the observable is kept up-to-date. + * This is useful when the observables `get` method is used. +*/ +export function keepAlive(observable: IObservable): IDisposable { + const o = new KeepAliveObserver(); + observable.addObserver(o); + return toDisposable(() => { + observable.removeObserver(o); + }); +} + +class KeepAliveObserver implements IObserver { + beginUpdate(observable: IObservable): void { + // NO OP + } + + handleChange(observable: IObservable, change: TChange): void { + // NO OP + } + + endUpdate(observable: IObservable): void { + // NO OP + } +} + +export function derivedObservableWithCache(name: string, computeFn: (reader: IReader, lastValue: T | undefined) => T): IObservable { + let lastValue: T | undefined = undefined; + const observable = derived(name, reader => { + lastValue = computeFn(reader, lastValue); + return lastValue; + }); + return observable; +} + +export function derivedObservableWithWritableCache(name: string, computeFn: (reader: IReader, lastValue: T | undefined) => T): IObservable & { clearCache(transaction: ITransaction): void } { + let lastValue: T | undefined = undefined; + const counter = observableValue('derivedObservableWithWritableCache.counter', 0); + const observable = derived(name, reader => { + counter.read(reader); + lastValue = computeFn(reader, lastValue); + return lastValue; + }); + return Object.assign(observable, { + clearCache: (transaction: ITransaction) => { + lastValue = undefined; + counter.set(counter.get() + 1, transaction); + }, + }); +} diff --git a/src/vs/base/test/common/observable.test.ts b/src/vs/base/test/common/observable.test.ts new file mode 100644 index 00000000000..8adba720180 --- /dev/null +++ b/src/vs/base/test/common/observable.test.ts @@ -0,0 +1,468 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { Emitter } from 'vs/base/common/event'; +import { autorun, derived, IObserver, ITransaction, observableFromEvent, observableValue, transaction } from 'vs/base/common/observable'; +import { BaseObservable } from 'vs/base/common/observableImpl/base'; + +suite('observable integration', () => { + test('basic observable + autorun', () => { + const log = new Log(); + const observable = observableValue('MyObservableValue', 0); + + autorun('MyAutorun', (reader) => { + log.log(`value: ${observable.read(reader)}`); + }); + assert.deepStrictEqual(log.getAndClearEntries(), ['value: 0']); + + observable.set(1, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), ['value: 1']); + + observable.set(1, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), []); + + transaction((tx) => { + observable.set(2, tx); + assert.deepStrictEqual(log.getAndClearEntries(), []); + + observable.set(3, tx); + assert.deepStrictEqual(log.getAndClearEntries(), []); + }); + + assert.deepStrictEqual(log.getAndClearEntries(), ['value: 3']); + }); + + test('basic computed + autorun', () => { + const log = new Log(); + const observable1 = observableValue('MyObservableValue1', 0); + const observable2 = observableValue('MyObservableValue2', 0); + + const computed = derived('computed', (reader) => { + const value1 = observable1.read(reader); + const value2 = observable2.read(reader); + const sum = value1 + value2; + log.log(`recompute: ${value1} + ${value2} = ${sum}`); + return sum; + }); + + autorun('MyAutorun', (reader) => { + log.log(`value: ${computed.read(reader)}`); + }); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute: 0 + 0 = 0', + 'value: 0', + ]); + + observable1.set(1, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute: 1 + 0 = 1', + 'value: 1', + ]); + + observable2.set(1, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute: 1 + 1 = 2', + 'value: 2', + ]); + + transaction((tx) => { + observable1.set(5, tx); + assert.deepStrictEqual(log.getAndClearEntries(), []); + + observable2.set(5, tx); + assert.deepStrictEqual(log.getAndClearEntries(), []); + }); + + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute: 5 + 5 = 10', + 'value: 10', + ]); + + transaction((tx) => { + observable1.set(6, tx); + assert.deepStrictEqual(log.getAndClearEntries(), []); + + observable2.set(4, tx); + assert.deepStrictEqual(log.getAndClearEntries(), []); + }); + + assert.deepStrictEqual(log.getAndClearEntries(), ['recompute: 6 + 4 = 10']); + }); + + test('read during transaction', () => { + const log = new Log(); + const observable1 = observableValue('MyObservableValue1', 0); + const observable2 = observableValue('MyObservableValue2', 0); + + const computed = derived('computed', (reader) => { + const value1 = observable1.read(reader); + const value2 = observable2.read(reader); + const sum = value1 + value2; + log.log(`recompute: ${value1} + ${value2} = ${sum}`); + return sum; + }); + + autorun('MyAutorun', (reader) => { + log.log(`value: ${computed.read(reader)}`); + }); + + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute: 0 + 0 = 0', + 'value: 0', + ]); + + log.log(`computed is ${computed.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), ['computed is 0']); + + transaction((tx) => { + observable1.set(-1, tx); + log.log(`computed is ${computed.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute: -1 + 0 = -1', + 'computed is -1', + ]); + + log.log(`computed is ${computed.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), ['computed is -1']); + + observable2.set(1, tx); + assert.deepStrictEqual(log.getAndClearEntries(), []); + }); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute: -1 + 1 = 0', + 'value: 0', + ]); + }); + + test('topological order', () => { + const log = new Log(); + const observable1 = observableValue('MyObservableValue1', 0); + const observable2 = observableValue('MyObservableValue2', 0); + + const computed1 = derived('computed1', (reader) => { + const value1 = observable1.read(reader); + const value2 = observable2.read(reader); + const sum = value1 + value2; + log.log(`recompute1: ${value1} + ${value2} = ${sum}`); + return sum; + }); + + const computed2 = derived('computed2', (reader) => { + const value1 = computed1.read(reader); + const value2 = observable1.read(reader); + const value3 = observable2.read(reader); + const sum = value1 + value2 + value3; + log.log(`recompute2: ${value1} + ${value2} + ${value3} = ${sum}`); + return sum; + }); + + const computed3 = derived('computed3', (reader) => { + const value1 = computed2.read(reader); + const value2 = observable1.read(reader); + const value3 = observable2.read(reader); + const sum = value1 + value2 + value3; + log.log(`recompute3: ${value1} + ${value2} + ${value3} = ${sum}`); + return sum; + }); + + autorun('MyAutorun', (reader) => { + log.log(`value: ${computed3.read(reader)}`); + }); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute1: 0 + 0 = 0', + 'recompute2: 0 + 0 + 0 = 0', + 'recompute3: 0 + 0 + 0 = 0', + 'value: 0', + ]); + + observable1.set(1, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute1: 1 + 0 = 1', + 'recompute2: 1 + 1 + 0 = 2', + 'recompute3: 2 + 1 + 0 = 3', + 'value: 3', + ]); + + transaction((tx) => { + observable1.set(2, tx); + log.log(`computed2: ${computed2.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute1: 2 + 0 = 2', + 'recompute2: 2 + 2 + 0 = 4', + 'computed2: 4', + ]); + + observable1.set(3, tx); + log.log(`computed2: ${computed2.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute1: 3 + 0 = 3', + 'recompute2: 3 + 3 + 0 = 6', + 'computed2: 6', + ]); + }); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute3: 6 + 3 + 0 = 9', + 'value: 9', + ]); + }); + + test('transaction from autorun', () => { + const log = new Log(); + + const observable1 = observableValue('MyObservableValue1', 0); + const observable2 = observableValue('MyObservableValue2', 0); + + const computed = derived('computed', (reader) => { + const value1 = observable1.read(reader); + const value2 = observable2.read(reader); + const sum = value1 + value2; + log.log(`recompute: ${value1} + ${value2} = ${sum}`); + return sum; + }); + + autorun('autorun', (reader) => { + log.log(`value: ${computed.read(reader)}`); + transaction(tx => { + + }); + + }); + + + }); + + test('from event', () => { + const log = new Log(); + + let value = 0; + const eventEmitter = new Emitter(); + + let id = 0; + const observable = observableFromEvent( + (handler) => { + const curId = id++; + log.log(`subscribed handler ${curId}`); + const disposable = eventEmitter.event(handler); + + return { + dispose: () => { + log.log(`unsubscribed handler ${curId}`); + disposable.dispose(); + }, + }; + }, + () => { + log.log(`compute value ${value}`); + return value; + } + ); + assert.deepStrictEqual(log.getAndClearEntries(), []); + + log.log(`get value: ${observable.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'compute value 0', + 'get value: 0', + ]); + + log.log(`get value: ${observable.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'compute value 0', + 'get value: 0', + ]); + + const shouldReadObservable = observableValue('shouldReadObservable', true); + + const autorunDisposable = autorun('MyAutorun', (reader) => { + if (shouldReadObservable.read(reader)) { + observable.read(reader); + log.log( + `autorun, should read: true, value: ${observable.read(reader)}` + ); + } else { + log.log(`autorun, should read: false`); + } + }); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'subscribed handler 0', + 'compute value 0', + 'autorun, should read: true, value: 0', + ]); + + log.log(`get value: ${observable.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), ['get value: 0']); + + value = 1; + eventEmitter.fire(); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'compute value 1', + 'autorun, should read: true, value: 1', + ]); + + shouldReadObservable.set(false, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'autorun, should read: false', + 'unsubscribed handler 0', + ]); + + shouldReadObservable.set(true, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'subscribed handler 1', + 'compute value 1', + 'autorun, should read: true, value: 1', + ]); + + autorunDisposable.dispose(); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'unsubscribed handler 1', + ]); + }); + + test('get without observers', () => { + // Maybe this scenario should not be supported. + + const log = new Log(); + const observable1 = observableValue('MyObservableValue1', 0); + const computed1 = derived('computed', (reader) => { + const value1 = observable1.read(reader); + const result = value1 % 3; + log.log(`recompute1: ${value1} % 3 = ${result}`); + return result; + }); + const computed2 = derived('computed', (reader) => { + const value1 = computed1.read(reader); + + const result = value1 * 2; + log.log(`recompute2: ${value1} * 2 = ${result}`); + return result; + }); + const computed3 = derived('computed', (reader) => { + const value1 = computed1.read(reader); + + const result = value1 * 3; + log.log(`recompute3: ${value1} * 3 = ${result}`); + return result; + }); + const computedSum = derived('computed', (reader) => { + const value1 = computed2.read(reader); + const value2 = computed3.read(reader); + + const result = value1 + value2; + log.log(`recompute4: ${value1} + ${value2} = ${result}`); + return result; + }); + assert.deepStrictEqual(log.getAndClearEntries(), []); + + observable1.set(1, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), []); + + log.log(`value: ${computedSum.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute1: 1 % 3 = 1', + 'recompute2: 1 * 2 = 2', + 'recompute3: 1 * 3 = 3', + 'recompute4: 2 + 3 = 5', + 'value: 5', + ]); + + log.log(`value: ${computedSum.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute1: 1 % 3 = 1', + 'recompute2: 1 * 2 = 2', + 'recompute3: 1 * 3 = 3', + 'recompute4: 2 + 3 = 5', + 'value: 5', + ]); + }); +}); + +suite('observable details', () => { + test('1', () => { + const log = new Log(); + + class TrackedObservableValue extends BaseObservable { + private value: T; + + constructor(initialValue: T) { + super(); + this.value = initialValue; + } + + readonly debugName = 'TrackedObservableValue'; + + public override addObserver(observer: IObserver): void { + log.log(`observable.addObserver ${observer.toString()}`); + super.addObserver(observer); + } + + public override removeObserver(observer: IObserver): void { + log.log(`observable.removeObserver ${observer.toString()}`); + super.removeObserver(observer); + } + + public get(): T { + log.log('observable.get'); + return this.value; + } + + public set(value: T, tx: ITransaction): void { + log.log(`observable.set (value ${value})`); + + if (this.value === value) { + return; + } + this.value = value; + for (const observer of this.observers) { + tx.updateObserver(observer, this); + observer.handleChange(this, undefined); + } + } + } + + const shouldReadObservable = observableValue('shouldReadObservable', true); + const observable = new TrackedObservableValue(0); + const computed = derived('test', reader => { + if (shouldReadObservable.read(reader)) { + return observable.read(reader) * 2; + } + return 1; + }); + autorun('test', reader => { + const value = computed.read(reader); + log.log(`autorun: ${value}`); + }); + + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'observable.addObserver LazyDerived', + 'observable.get', + 'autorun: 0', + ]); + + transaction(tx => { + observable.set(1, tx); + assert.deepStrictEqual(log.getAndClearEntries(), (["observable.set (value 1)"])); + + shouldReadObservable.set(false, tx); + assert.deepStrictEqual(log.getAndClearEntries(), ([])); + + computed.get(); + assert.deepStrictEqual(log.getAndClearEntries(), (["observable.removeObserver LazyDerived"])); + }); + assert.deepStrictEqual(log.getAndClearEntries(), (["autorun: 1"])); + }); +}); + +class Log { + private readonly entries: string[] = []; + public log(message: string): void { + this.entries.push(message); + } + + public getAndClearEntries(): string[] { + const entries = [...this.entries]; + this.entries.length = 0; + return entries; + } +} diff --git a/src/vs/workbench/contrib/audioCues/browser/audioCueLineFeatureContribution.ts b/src/vs/workbench/contrib/audioCues/browser/audioCueLineFeatureContribution.ts index 3c348baa40a..edbdd468675 100644 --- a/src/vs/workbench/contrib/audioCues/browser/audioCueLineFeatureContribution.ts +++ b/src/vs/workbench/contrib/audioCues/browser/audioCueLineFeatureContribution.ts @@ -96,6 +96,7 @@ export class AudioCueLineFeatureContribution const curLineNumber = observableFromEvent( editor.onDidChangeCursorPosition, (args) => { + /** @description editor.onDidChangeCursorPosition (caused by user) */ if ( args && args.reason !== CursorChangeReason.Explicit && @@ -193,7 +194,7 @@ class MarkerLineFeature implements LineFeature { Event.filter(this.markerService.onMarkerChanged, (changedUris) => changedUris.some((u) => u.toString() === model.uri.toString()) ), - () => ({ + () => /** @description this.markerService.onMarkerChanged */({ isPresent: (lineNumber) => { const hasMarker = this.markerService .read({ resource: model.uri }) @@ -245,7 +246,7 @@ class BreakpointLineFeature implements LineFeature { getObservableState(editor: ICodeEditor, model: ITextModel): IObservable { return observableFromEvent( this.debugService.getModel().onDidChangeBreakpoints, - () => ({ + () => /** @description debugService.getModel().onDidChangeBreakpoints */({ isPresent: (lineNumber) => { const breakpoints = this.debugService .getModel() @@ -271,12 +272,12 @@ class InlineCompletionLineFeature implements LineFeature { const activeGhostText = observableFromEvent( ghostTextController.onActiveModelDidChange, - () => ghostTextController.activeModel + () => /** @description ghostTextController.onActiveModelDidChange */ ghostTextController.activeModel ).map((activeModel) => ( activeModel ? observableFromEvent( activeModel.inlineCompletionsModel.onDidChange, - () => activeModel.inlineCompletionsModel.ghostText + () => /** @description activeModel.inlineCompletionsModel.onDidChange */ activeModel.inlineCompletionsModel.ghostText ) : undefined )); diff --git a/src/vs/workbench/contrib/audioCues/browser/audioCueService.ts b/src/vs/workbench/contrib/audioCues/browser/audioCueService.ts index dcac8bf037b..f313933a8ec 100644 --- a/src/vs/workbench/contrib/audioCues/browser/audioCueService.ts +++ b/src/vs/workbench/contrib/audioCues/browser/audioCueService.ts @@ -9,7 +9,7 @@ import { FileAccess } from 'vs/base/common/network'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { observableFromEvent, IObservable, LazyDerived } from 'vs/workbench/contrib/audioCues/browser/observable'; +import { observableFromEvent, IObservable, derivedObservable } from 'vs/workbench/contrib/audioCues/browser/observable'; import { Event } from 'vs/base/common/event'; import { localize } from 'vs/nls'; @@ -29,7 +29,7 @@ export class AudioCueService extends Disposable implements IAudioCueService { private readonly screenReaderAttached = observableFromEvent( this.accessibilityService.onDidChangeScreenReaderOptimized, - () => this.accessibilityService.isScreenReaderOptimized() + () => /** @description accessibilityService.onDidChangeScreenReaderOptimized */ this.accessibilityService.isScreenReaderOptimized() ); constructor( @@ -85,7 +85,7 @@ export class AudioCueService extends Disposable implements IAudioCueService { Event.filter(this.configurationService.onDidChangeConfiguration, (e) => e.affectsConfiguration('audioCues.enabled') ), - () => this.configurationService.getValue<'on' | 'off' | 'auto'>('audioCues.enabled') + () => /** @description config: audioCues.enabled */ this.configurationService.getValue<'on' | 'off' | 'auto'>('audioCues.enabled') ); private readonly isEnabledCache = new Cache((cue: AudioCue) => { @@ -95,7 +95,7 @@ export class AudioCueService extends Disposable implements IAudioCueService { ), () => this.configurationService.getValue<'on' | 'off' | 'auto'>(cue.settingsKey) ); - return new LazyDerived(reader => { + return derivedObservable('audio cue enabled', reader => { const setting = settingObservable.read(reader); if ( setting === 'on' || @@ -113,7 +113,7 @@ export class AudioCueService extends Disposable implements IAudioCueService { } return false; - }, 'audio cue enabled'); + }); }); public isEnabled(cue: AudioCue): IObservable { diff --git a/src/vs/workbench/contrib/audioCues/browser/observable.ts b/src/vs/workbench/contrib/audioCues/browser/observable.ts index 2ad62412411..37d2f8a97c8 100644 --- a/src/vs/workbench/contrib/audioCues/browser/observable.ts +++ b/src/vs/workbench/contrib/audioCues/browser/observable.ts @@ -3,688 +3,38 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Event } from 'vs/base/common/event'; -import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; - -export interface IObservable { - _change: TChange; - - /** - * Reads the current value. - * - * This causes a recomputation if needed. - * Calling this method forces changes to propagate to observers during update operations. - * Must not be called from {@link IObserver.handleChange}. - */ - get(): T; - - /** - * Registers an observer. - * - * Calls {@link IObserver.handleChange} immediately after a change is noticed. - * Might happen while someone calls {@link IObservable.get} or {@link IObservable.read}. - */ - subscribe(observer: IObserver): void; - unsubscribe(observer: IObserver): void; - - /** - * Calls {@link IObservable.get} and then {@link IReader.handleBeforeReadObservable}. - */ - read(reader: IReader): T; - - map(fn: (value: T) => TNew): IObservable; -} - -export interface IReader { - /** - * Reports an observable that was read. - * - * Is called by `Observable.read`. - */ - handleBeforeReadObservable(observable: IObservable): void; -} - -export interface IObserver { - /** - * Indicates that an update operation is about to begin. - * - * During an update, invariants might not hold for subscribed observables and - * change events might be delayed. - * However, all changes must be reported before all update operations are over. - */ - beginUpdate(observable: IObservable): void; - - /** - * Is called by a subscribed observable immediately after it notices a change. - * - * When {@link IObservable.get} returns and no change has been reported, - * there has been no change for that observable. - * - * Implementations must not call into other observables! - * The change should be processed when {@link IObserver.endUpdate} is called. - */ - handleChange(observable: IObservable, change: TChange): void; - - /** - * Indicates that an update operation has completed. - */ - endUpdate(observable: IObservable): void; -} - -export interface ISettable { - set(value: T, transaction: ITransaction | undefined, change: TChange): void; -} - -export interface ITransaction { - /** - * Calls `Observer.beginUpdate` immediately - * and `Observer.endUpdate` when the transaction is complete. - */ - updateObserver( - observer: IObserver, - observable: IObservable - ): void; -} - -// === Base === -export abstract class ConvenientObservable implements IObservable { - get _change(): TChange { return null!; } - - public abstract get(): T; - public abstract subscribe(observer: IObserver): void; - public abstract unsubscribe(observer: IObserver): void; - - public read(reader: IReader): T { - reader.handleBeforeReadObservable(this); - return this.get(); - } - - public map(fn: (value: T) => TNew): IObservable { - return new LazyDerived((reader) => fn(this.read(reader)), '(mapped)'); - } -} - -export abstract class BaseObservable extends ConvenientObservable { - protected readonly observers = new Set(); - - public subscribe(observer: IObserver): void { - const len = this.observers.size; - this.observers.add(observer); - if (len === 0) { - this.onFirstObserverSubscribed(); - } - } - - public unsubscribe(observer: IObserver): void { - const deleted = this.observers.delete(observer); - if (deleted && this.observers.size === 0) { - this.onLastObserverUnsubscribed(); - } - } - - protected onFirstObserverSubscribed(): void { } - protected onLastObserverUnsubscribed(): void { } -} - -export function transaction(fn: (tx: ITransaction) => void) { - const tx = new TransactionImpl(); - try { - fn(tx); - } finally { - tx.finish(); - } -} - -class TransactionImpl implements ITransaction { - private readonly finishActions = new Array<() => void>(); - - public updateObserver( - observer: IObserver, - observable: IObservable - ): void { - this.finishActions.push(function () { - observer.endUpdate(observable); - }); - observer.beginUpdate(observable); - } - - public finish(): void { - for (const action of this.finishActions) { - action(); - } - } -} - -export class ObservableValue - extends BaseObservable - implements ISettable -{ - private value: T; - - constructor(initialValue: T, public readonly name: string) { - super(); - this.value = initialValue; - } - - public get(): T { - return this.value; - } - - public set(value: T, tx: ITransaction | undefined, change: TChange): void { - if (this.value === value) { - return; - } - - if (!tx) { - transaction((tx) => { - this.set(value, tx, change); - }); - return; - } - - this.value = value; - - for (const observer of this.observers) { - tx.updateObserver(observer, this); - observer.handleChange(this, change); - } - } -} - -export function constObservable(value: T): IObservable { - return new ConstObservable(value); -} - -class ConstObservable extends ConvenientObservable { - constructor(private readonly value: T) { - super(); - } - - public get(): T { - return this.value; - } - public subscribe(observer: IObserver): void { - // NO OP - } - public unsubscribe(observer: IObserver): void { - // NO OP - } -} - -// == autorun == -export function autorun(fn: (reader: IReader) => void, name: string): IDisposable { - return new AutorunObserver(fn, name, undefined); -} - -interface IChangeContext { - readonly changedObservable: IObservable; - readonly change: unknown; - - didChange(observable: IObservable): this is { change: TChange }; -} - -export function autorunHandleChanges( - name: string, - options: { - /** - * Returns if this change should cause a re-run of the autorun. - */ - handleChange: (context: IChangeContext) => boolean; - }, - fn: (reader: IReader) => void -): IDisposable { - return new AutorunObserver(fn, name, options.handleChange); -} - -export function autorunWithStore( - fn: (reader: IReader, store: DisposableStore) => void, - name: string -): IDisposable { - const store = new DisposableStore(); - const disposable = autorun( - reader => { - store.clear(); - fn(reader, store); - }, - name - ); - return toDisposable(() => { - disposable.dispose(); - store.dispose(); - }); -} - -export class AutorunObserver implements IObserver, IReader, IDisposable { - public needsToRun = true; - private updateCount = 0; - - /** - * The actual dependencies. - */ - private _dependencies = new Set>(); - public get dependencies() { - return this._dependencies; - } - - /** - * Dependencies that have to be removed when {@link runFn} ran through. - */ - private staleDependencies = new Set>(); - - constructor( - private readonly runFn: (reader: IReader) => void, - public readonly name: string, - private readonly _handleChange: ((context: IChangeContext) => boolean) | undefined - ) { - this.runIfNeeded(); - } - - public handleBeforeReadObservable(observable: IObservable) { - this._dependencies.add(observable); - if (!this.staleDependencies.delete(observable)) { - observable.subscribe(this); - } - } - - public handleChange(observable: IObservable, change: TChange): void { - const shouldReact = this._handleChange ? this._handleChange({ - changedObservable: observable, - change, - didChange: o => o === observable as any, - }) : true; - this.needsToRun = this.needsToRun || shouldReact; - - if (this.updateCount === 0) { - this.runIfNeeded(); - } - } - - public beginUpdate() { - this.updateCount++; - } - - public endUpdate() { - this.updateCount--; - if (this.updateCount === 0) { - this.runIfNeeded(); - } - } - - private runIfNeeded(): void { - if (!this.needsToRun) { - return; - } - // Assert: this.staleDependencies is an empty set. - const emptySet = this.staleDependencies; - this.staleDependencies = this._dependencies; - this._dependencies = emptySet; - - this.needsToRun = false; - - try { - this.runFn(this); - } finally { - // We don't want our observed observables to think that they are (not even temporarily) not being observed. - // Thus, we only unsubscribe from observables that are definitely not read anymore. - for (const o of this.staleDependencies) { - o.unsubscribe(this); - } - this.staleDependencies.clear(); - } - } - - public dispose() { - for (const o of this._dependencies) { - o.unsubscribe(this); - } - this._dependencies.clear(); - } -} - -export namespace autorun { - export const Observer = AutorunObserver; -} -export function autorunDelta( - name: string, - observable: IObservable, - handler: (args: { lastValue: T | undefined; newValue: T }) => void -): IDisposable { - let _lastValue: T | undefined; - return autorun((reader) => { - const newValue = observable.read(reader); - const lastValue = _lastValue; - _lastValue = newValue; - handler({ lastValue, newValue }); - }, name); -} - - -// == Lazy Derived == - -export function derivedObservable(name: string, computeFn: (reader: IReader) => T): IObservable { - return new LazyDerived(computeFn, name); -} -export class LazyDerived extends ConvenientObservable { - private readonly observer: LazyDerivedObserver; - - constructor(computeFn: (reader: IReader) => T, name: string) { - super(); - this.observer = new LazyDerivedObserver(computeFn, name, this); - } - - public subscribe(observer: IObserver): void { - this.observer.subscribe(observer); - } - - public unsubscribe(observer: IObserver): void { - this.observer.unsubscribe(observer); - } - - public override read(reader: IReader): T { - return this.observer.read(reader); - } - - public get(): T { - return this.observer.get(); - } -} - -/** - * @internal - */ -class LazyDerivedObserver - extends BaseObservable - implements IReader, IObserver { - private hadValue = false; - private hasValue = false; - private value: T | undefined = undefined; - private updateCount = 0; - - private _dependencies = new Set>(); - public get dependencies(): ReadonlySet> { - return this._dependencies; - } - - /** - * Dependencies that have to be removed when {@link runFn} ran through. - */ - private staleDependencies = new Set>(); - - constructor( - private readonly computeFn: (reader: IReader) => T, - public readonly name: string, - private readonly actualObservable: LazyDerived, - ) { - super(); - } - - protected override onLastObserverUnsubscribed(): void { - /** - * We are not tracking changes anymore, thus we have to assume - * that our cache is invalid. - */ - this.hasValue = false; - this.hadValue = false; - this.value = undefined; - for (const d of this._dependencies) { - d.unsubscribe(this); - } - this._dependencies.clear(); - } - - public handleBeforeReadObservable(observable: IObservable) { - this._dependencies.add(observable); - if (!this.staleDependencies.delete(observable)) { - observable.subscribe(this); - } - } - - public handleChange() { - if (this.hasValue) { - this.hadValue = true; - this.hasValue = false; - } - - // Not in transaction: Recompute & inform observers immediately - if (this.updateCount === 0 && this.observers.size > 0) { - this.get(); - } - - // Otherwise, recompute in `endUpdate` or on demand. - } - - public beginUpdate() { - if (this.updateCount === 0) { - for (const r of this.observers) { - r.beginUpdate(this); - } - } - this.updateCount++; - } - - public endUpdate() { - this.updateCount--; - if (this.updateCount === 0) { - if (this.observers.size > 0) { - // Propagate invalidation - this.get(); - } - - for (const r of this.observers) { - r.endUpdate(this); - } - } - } - - public get(): T { - if (this.observers.size === 0) { - // Cache is not valid and don't refresh the cache. - // Observables should not be read in non-reactive contexts. - return this.computeFn(this); - } - - if (this.updateCount > 0 && this.hasValue) { - // Refresh dependencies - for (const d of this._dependencies) { - // Maybe `.get()` triggers `handleChange`? - d.get(); - if (!this.hasValue) { - // The other dependencies will refresh on demand - break; - } - } - } - - if (!this.hasValue) { - const emptySet = this.staleDependencies; - this.staleDependencies = this._dependencies; - this._dependencies = emptySet; - - const oldValue = this.value; - try { - this.value = this.computeFn(this); - } finally { - // We don't want our observed observables to think that they are (not even temporarily) not being observed. - // Thus, we only unsubscribe from observables that are definitely not read anymore. - for (const o of this.staleDependencies) { - o.unsubscribe(this); - } - this.staleDependencies.clear(); - } - - this.hasValue = true; - if (this.hadValue && oldValue !== this.value) { - for (const r of this.observers) { - r.handleChange(this.actualObservable, undefined); - } - } - } - return this.value!; - } -} - -export namespace LazyDerived { - export const Observer = LazyDerivedObserver; -} - -export function observableFromPromise(promise: Promise): IObservable<{ value?: T }> { - const observable = new ObservableValue<{ value?: T }>({}, 'promiseValue'); - promise.then((value) => { - observable.set({ value }, undefined); - }); - return observable; -} - -export function waitForState(observable: IObservable, predicate: (state: T) => state is TState): Promise; -export function waitForState(observable: IObservable, predicate: (state: T) => boolean): Promise; -export function waitForState(observable: IObservable, predicate: (state: T) => boolean): Promise { - return new Promise(resolve => { - const d = autorun(reader => { - const currentState = observable.read(reader); - if (predicate(currentState)) { - d.dispose(); - resolve(currentState); - } - }, 'waitForState'); - }); -} - -export function observableFromEvent( - event: Event, - getValue: (args: TArgs | undefined) => T -): IObservable { - return new FromEventObservable(event, getValue); -} - -class FromEventObservable extends BaseObservable { - private value: T | undefined; - private hasValue = false; - private subscription: IDisposable | undefined; - - constructor( - private readonly event: Event, - private readonly getValue: (args: TArgs | undefined) => T - ) { - super(); - } - - protected override onFirstObserverSubscribed(): void { - this.subscription = this.event(this.handleEvent); - } - - private readonly handleEvent = (args: TArgs | undefined) => { - const newValue = this.getValue(args); - if (this.value !== newValue) { - this.value = newValue; - - if (this.hasValue) { - transaction(tx => { - for (const o of this.observers) { - tx.updateObserver(o, this); - o.handleChange(this, undefined); - } - }); - } - this.hasValue = true; - } - }; - - protected override onLastObserverUnsubscribed(): void { - this.subscription!.dispose(); - this.subscription = undefined; - this.hasValue = false; - this.value = undefined; - } - - public get(): T { - if (this.subscription) { - if (!this.hasValue) { - this.handleEvent(undefined); - } - return this.value!; - } else { - // no cache, as there are no subscribers to clean it up - return this.getValue(undefined); - } - } -} - -export namespace observableFromEvent { - export const Observer = FromEventObservable; -} - -export function debouncedObservable(observable: IObservable, debounceMs: number, disposableStore: DisposableStore): IObservable { - const debouncedObservable = new ObservableValue(undefined, 'debounced'); - - let timeout: any = undefined; - - disposableStore.add(autorun(reader => { - const value = observable.read(reader); - - if (timeout) { - clearTimeout(timeout); - } - timeout = setTimeout(() => { - transaction(tx => { - debouncedObservable.set(value, tx); - }); - }, debounceMs); - - }, 'debounce')); - - return debouncedObservable; -} - -export function wasEventTriggeredRecently(event: Event, timeoutMs: number, disposableStore: DisposableStore): IObservable { - const observable = new ObservableValue(false, 'triggeredRecently'); - - let timeout: any = undefined; - - disposableStore.add(event(() => { - observable.set(true, undefined); - - if (timeout) { - clearTimeout(timeout); - } - timeout = setTimeout(() => { - observable.set(false, undefined); - }, timeoutMs); - })); - - return observable; -} - -/** - * This ensures the observable is kept up-to-date. - * This is useful when the observables `get` method is used. -*/ -export function keepAlive(observable: IObservable): IDisposable { - return autorun(reader => { - observable.read(reader); - }, 'keep-alive'); -} - -export function derivedObservableWithCache(name: string, computeFn: (reader: IReader, lastValue: T | undefined) => T): IObservable { - let lastValue: T | undefined = undefined; - const observable = derivedObservable(name, reader => { - lastValue = computeFn(reader, lastValue); - return lastValue; - }); - return observable; -} - -export function derivedObservableWithWritableCache(name: string, computeFn: (reader: IReader, lastValue: T | undefined) => T): IObservable & { clearCache(transaction: ITransaction): void } { - let lastValue: T | undefined = undefined; - const counter = new ObservableValue(0, 'counter'); - const observable = derivedObservable(name, reader => { - counter.read(reader); - lastValue = computeFn(reader, lastValue); - return lastValue; - }); - return Object.assign(observable, { - clearCache: (transaction: ITransaction) => { - lastValue = undefined; - counter.set(counter.get() + 1, transaction); - }, - }); +import { IDisposable } from 'vs/base/common/lifecycle'; +import * as observable from 'vs/base/common/observable'; +export { + observableFromEvent, + autorunWithStore, + IObservable, + transaction, + ITransaction, + autorunDelta, + constObservable, + observableFromPromise, + wasEventTriggeredRecently, + debouncedObservable, + autorunHandleChanges, + waitForState, + keepAlive, + IReader, + derivedObservableWithCache, + derivedObservableWithWritableCache, +} from 'vs/base/common/observable'; +import * as observableValue from 'vs/base/common/observableImpl/base'; + +export function autorun(fn: (reader: observable.IReader) => void, name: string): IDisposable { + return observable.autorun(name, fn); +} + +export class ObservableValue extends observableValue.ObservableValue { + constructor(initialValue: T, name: string) { + super(name, initialValue); + } +} + +export function derivedObservable(name: string, computeFn: (reader: observable.IReader) => T): observable.IObservable { + return observable.derived(name, computeFn); } diff --git a/src/vs/workbench/contrib/audioCues/test/browser/observable.test.ts b/src/vs/workbench/contrib/audioCues/test/browser/observable.test.ts new file mode 100644 index 00000000000..646464cb636 --- /dev/null +++ b/src/vs/workbench/contrib/audioCues/test/browser/observable.test.ts @@ -0,0 +1,468 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { Emitter } from 'vs/base/common/event'; +import { autorun, autorun2, BaseObservable, derivedObservable, IObserver, ITransaction, observableFromEvent, observableValue, ObservableValue, transaction } from 'vs/workbench/contrib/audioCues/browser/observable'; + +suite('observable integration', () => { + test('basic observable + autorun', () => { + const log = new Log(); + const observable = new ObservableValue(0, 'MyObservableValue'); + + autorun((reader) => { + log.log(`value: ${observable.read(reader)}`); + }, 'MyAutorun'); + assert.deepStrictEqual(log.getAndClearEntries(), ['value: 0']); + + observable.set(1, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), ['value: 1']); + + observable.set(1, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), []); + + transaction((tx) => { + observable.set(2, tx); + assert.deepStrictEqual(log.getAndClearEntries(), []); + + observable.set(3, tx); + assert.deepStrictEqual(log.getAndClearEntries(), []); + }); + + assert.deepStrictEqual(log.getAndClearEntries(), ['value: 3']); + }); + + test('basic computed + autorun', () => { + const log = new Log(); + const observable1 = new ObservableValue(0, 'MyObservableValue1'); + const observable2 = new ObservableValue(0, 'MyObservableValue2'); + + const computed = derivedObservable('computed', (reader) => { + const value1 = observable1.read(reader); + const value2 = observable2.read(reader); + const sum = value1 + value2; + log.log(`recompute: ${value1} + ${value2} = ${sum}`); + return sum; + }); + + autorun((reader) => { + log.log(`value: ${computed.read(reader)}`); + }, 'MyAutorun'); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute: 0 + 0 = 0', + 'value: 0', + ]); + + observable1.set(1, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute: 1 + 0 = 1', + 'value: 1', + ]); + + observable2.set(1, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute: 1 + 1 = 2', + 'value: 2', + ]); + + transaction((tx) => { + observable1.set(5, tx); + assert.deepStrictEqual(log.getAndClearEntries(), []); + + observable2.set(5, tx); + assert.deepStrictEqual(log.getAndClearEntries(), []); + }); + + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute: 5 + 5 = 10', + 'value: 10', + ]); + + transaction((tx) => { + observable1.set(6, tx); + assert.deepStrictEqual(log.getAndClearEntries(), []); + + observable2.set(4, tx); + assert.deepStrictEqual(log.getAndClearEntries(), []); + }); + + assert.deepStrictEqual(log.getAndClearEntries(), ['recompute: 6 + 4 = 10']); + }); + + test('read during transaction', () => { + const log = new Log(); + const observable1 = new ObservableValue(0, 'MyObservableValue1'); + const observable2 = new ObservableValue(0, 'MyObservableValue2'); + + const computed = derivedObservable('computed', (reader) => { + const value1 = observable1.read(reader); + const value2 = observable2.read(reader); + const sum = value1 + value2; + log.log(`recompute: ${value1} + ${value2} = ${sum}`); + return sum; + }); + + autorun((reader) => { + log.log(`value: ${computed.read(reader)}`); + }, 'MyAutorun'); + + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute: 0 + 0 = 0', + 'value: 0', + ]); + + log.log(`computed is ${computed.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), ['computed is 0']); + + transaction((tx) => { + observable1.set(-1, tx); + log.log(`computed is ${computed.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute: -1 + 0 = -1', + 'computed is -1', + ]); + + log.log(`computed is ${computed.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), ['computed is -1']); + + observable2.set(1, tx); + assert.deepStrictEqual(log.getAndClearEntries(), []); + }); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute: -1 + 1 = 0', + 'value: 0', + ]); + }); + + test('topological order', () => { + const log = new Log(); + const observable1 = new ObservableValue(0, 'MyObservableValue1'); + const observable2 = new ObservableValue(0, 'MyObservableValue2'); + + const computed1 = derivedObservable('computed1', (reader) => { + const value1 = observable1.read(reader); + const value2 = observable2.read(reader); + const sum = value1 + value2; + log.log(`recompute1: ${value1} + ${value2} = ${sum}`); + return sum; + }); + + const computed2 = derivedObservable('computed2', (reader) => { + const value1 = computed1.read(reader); + const value2 = observable1.read(reader); + const value3 = observable2.read(reader); + const sum = value1 + value2 + value3; + log.log(`recompute2: ${value1} + ${value2} + ${value3} = ${sum}`); + return sum; + }); + + const computed3 = derivedObservable('computed3', (reader) => { + const value1 = computed2.read(reader); + const value2 = observable1.read(reader); + const value3 = observable2.read(reader); + const sum = value1 + value2 + value3; + log.log(`recompute3: ${value1} + ${value2} + ${value3} = ${sum}`); + return sum; + }); + + autorun((reader) => { + log.log(`value: ${computed3.read(reader)}`); + }, 'MyAutorun'); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute1: 0 + 0 = 0', + 'recompute2: 0 + 0 + 0 = 0', + 'recompute3: 0 + 0 + 0 = 0', + 'value: 0', + ]); + + observable1.set(1, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute1: 1 + 0 = 1', + 'recompute2: 1 + 1 + 0 = 2', + 'recompute3: 2 + 1 + 0 = 3', + 'value: 3', + ]); + + transaction((tx) => { + observable1.set(2, tx); + log.log(`computed2: ${computed2.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute1: 2 + 0 = 2', + 'recompute2: 2 + 2 + 0 = 4', + 'computed2: 4', + ]); + + observable1.set(3, tx); + log.log(`computed2: ${computed2.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute1: 3 + 0 = 3', + 'recompute2: 3 + 3 + 0 = 6', + 'computed2: 6', + ]); + }); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute3: 6 + 3 + 0 = 9', + 'value: 9', + ]); + }); + + test('transaction from autorun', () => { + const log = new Log(); + + const observable1 = new ObservableValue(0, 'MyObservableValue1'); + const observable2 = new ObservableValue(0, 'MyObservableValue2'); + + const computed = derivedObservable('computed', (reader) => { + const value1 = observable1.read(reader); + const value2 = observable2.read(reader); + const sum = value1 + value2; + log.log(`recompute: ${value1} + ${value2} = ${sum}`); + return sum; + }); + + autorun((reader) => { + log.log(`value: ${computed.read(reader)}`); + transaction(tx => { + + }); + + }, 'autorun'); + + + }); + + test('from event', () => { + const log = new Log(); + + let value = 0; + const eventEmitter = new Emitter(); + + let id = 0; + const observable = observableFromEvent( + (handler) => { + const curId = id++; + log.log(`subscribed handler ${curId}`); + const disposable = eventEmitter.event(handler); + + return { + dispose: () => { + log.log(`unsubscribed handler ${curId}`); + disposable.dispose(); + }, + }; + }, + () => { + log.log(`compute value ${value}`); + return value; + } + ); + assert.deepStrictEqual(log.getAndClearEntries(), []); + + log.log(`get value: ${observable.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'compute value 0', + 'get value: 0', + ]); + + log.log(`get value: ${observable.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'compute value 0', + 'get value: 0', + ]); + + const shouldReadObservable = new ObservableValue( + true, + 'shouldReadObservable' + ); + + const autorunDisposable = autorun((reader) => { + if (shouldReadObservable.read(reader)) { + observable.read(reader); + log.log( + `autorun, should read: true, value: ${observable.read(reader)}` + ); + } else { + log.log(`autorun, should read: false`); + } + }, 'MyAutorun'); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'subscribed handler 0', + 'compute value 0', + 'autorun, should read: true, value: 0', + ]); + + log.log(`get value: ${observable.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), ['get value: 0']); + + value = 1; + eventEmitter.fire(); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'compute value 1', + 'autorun, should read: true, value: 1', + ]); + + shouldReadObservable.set(false, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'autorun, should read: false', + 'unsubscribed handler 0', + ]); + + shouldReadObservable.set(true, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'subscribed handler 1', + 'compute value 1', + 'autorun, should read: true, value: 1', + ]); + + autorunDisposable.dispose(); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'unsubscribed handler 1', + ]); + }); + + test('get without observers', () => { + // Maybe this scenario should not be supported. + + const log = new Log(); + const observable1 = new ObservableValue(0, 'MyObservableValue1'); + const computed1 = derivedObservable('computed', (reader) => { + const value1 = observable1.read(reader); + const result = value1 % 3; + log.log(`recompute1: ${value1} % 3 = ${result}`); + return result; + }); + const computed2 = derivedObservable('computed', (reader) => { + const value1 = computed1.read(reader); + + const result = value1 * 2; + log.log(`recompute2: ${value1} * 2 = ${result}`); + return result; + }); + const computed3 = derivedObservable('computed', (reader) => { + const value1 = computed1.read(reader); + + const result = value1 * 3; + log.log(`recompute3: ${value1} * 3 = ${result}`); + return result; + }); + const computedSum = derivedObservable('computed', (reader) => { + const value1 = computed2.read(reader); + const value2 = computed3.read(reader); + + const result = value1 + value2; + log.log(`recompute4: ${value1} + ${value2} = ${result}`); + return result; + }); + assert.deepStrictEqual(log.getAndClearEntries(), []); + + observable1.set(1, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), []); + + log.log(`value: ${computedSum.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute1: 1 % 3 = 1', + 'recompute2: 1 * 2 = 2', + 'recompute3: 1 * 3 = 3', + 'recompute4: 2 + 3 = 5', + 'value: 5', + ]); + + log.log(`value: ${computedSum.get()}`); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'recompute1: 1 % 3 = 1', + 'recompute2: 1 * 2 = 2', + 'recompute3: 1 * 3 = 3', + 'recompute4: 2 + 3 = 5', + 'value: 5', + ]); + }); +}); + +suite('observable details', () => { + test('1', () => { + const log = new Log(); + + class TrackedObservableValue extends BaseObservable { + private value: T; + + constructor(initialValue: T) { + super(); + this.value = initialValue; + } + + public override addObserver(observer: IObserver): void { + log.log(`observable.addObserver ${observer.toString()}`); + super.addObserver(observer); + } + + public override removeObserver(observer: IObserver): void { + log.log(`observable.removeObserver ${observer.toString()}`); + super.removeObserver(observer); + } + + public get(): T { + log.log('observable.get'); + return this.value; + } + + public set(value: T, tx: ITransaction): void { + log.log(`observable.set (value ${value})`); + + if (this.value === value) { + return; + } + this.value = value; + for (const observer of this.observers) { + tx.updateObserver(observer, this); + observer.handleChange(this, undefined); + } + } + } + + const shouldReadObservable = observableValue('shouldReadObservable', true); + const observable = new TrackedObservableValue(0); + const computed = derivedObservable('test', reader => { + if (shouldReadObservable.read(reader)) { + return observable.read(reader) * 2; + } + return 1; + }); + autorun2('test', reader => { + const value = computed.read(reader); + log.log(`autorun: ${value}`); + }); + + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'observable.addObserver LazyDerived', + 'observable.get', + 'autorun: 0', + ]); + + transaction(tx => { + observable.set(1, tx); + assert.deepStrictEqual(log.getAndClearEntries(), (["observable.set (value 1)"])); + + shouldReadObservable.set(false, tx); + assert.deepStrictEqual(log.getAndClearEntries(), ([])); + + computed.get(); + assert.deepStrictEqual(log.getAndClearEntries(), (["observable.removeObserver LazyDerived"])); + }); + assert.deepStrictEqual(log.getAndClearEntries(), (["autorun: 1"])); + }); +}); + +class Log { + private readonly entries: string[] = []; + public log(message: string): void { + this.entries.push(message); + } + + public getAndClearEntries(): string[] { + const entries = [...this.entries]; + this.entries.length = 0; + return entries; + } +} -- cgit v1.2.3 From 2a447e5e3aef839b96b6301329bd67085232ff1f Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Sun, 3 Jul 2022 19:46:52 +0200 Subject: Improves 3wm observables. --- .../mergeEditor/browser/model/mergeEditorModel.ts | 14 +- .../mergeEditor/browser/model/modifiedBaseRange.ts | 4 + .../mergeEditor/browser/model/textModelDiffs.ts | 2 + .../workbench/contrib/mergeEditor/browser/utils.ts | 2 +- .../mergeEditor/browser/view/editorGutter.ts | 29 +-- .../browser/view/editors/codeEditorView.ts | 15 +- .../browser/view/editors/inputCodeEditorView.ts | 267 +++++++++++---------- .../browser/view/editors/resultCodeEditorView.ts | 4 +- .../contrib/mergeEditor/browser/view/viewModel.ts | 1 + 9 files changed, 183 insertions(+), 155 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts b/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts index d9f61d89baf..2c1f3b1c4e7 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts @@ -44,7 +44,7 @@ export class MergeEditorModel extends EditorModel { return MergeEditorModelState.upToDate; }); - public readonly isUpToDate = derivedObservable('isUpdating', reader => this.state.read(reader) === MergeEditorModelState.upToDate); + public readonly isUpToDate = derivedObservable('isUpToDate', reader => this.state.read(reader) === MergeEditorModelState.upToDate); public readonly onInitialized = waitForState(this.state, state => state === MergeEditorModelState.upToDate); @@ -84,7 +84,7 @@ export class MergeEditorModel extends EditorModel { return map.size - handledCount; }); - public readonly hasUnhandledConflicts = this.unhandledConflictsCount.map(value => value > 0); + public readonly hasUnhandledConflicts = this.unhandledConflictsCount.map(value => /** @description hasUnhandledConflicts */ value > 0); public readonly input1ResultMapping = derivedObservable('input1ResultMapping', reader => { const resultDiffs = this.resultDiffs.read(reader); @@ -145,7 +145,7 @@ export class MergeEditorModel extends EditorModel { let shouldResetHandlingState = true; this._register( autorunHandleChanges( - 'Recompute State', + 'Merge Editor Model: Recompute State', { handleChange: (ctx) => { if (ctx.didChange(this.modifiedBaseRangeHandlingStateStores)) { @@ -165,6 +165,7 @@ export class MergeEditorModel extends EditorModel { const resultDiffs = this.resultTextModelDiffs.diffs.read(reader); const stores = this.modifiedBaseRangeStateStores.read(reader); transaction(tx => { + /** @description Merge Editor Model: Recompute State */ this.recomputeState(resultDiffs, stores, tx); if (shouldResetHandlingState) { shouldResetHandlingState = false; @@ -202,12 +203,16 @@ export class MergeEditorModel extends EditorModel { ); for (const row of baseRangeWithStoreAndTouchingDiffs) { - row.left[1].set(this.computeState(row.left[0], row.rights), tx); + const newState = this.computeState(row.left[0], row.rights); + if (!row.left[1].get().equals(newState)) { + row.left[1].set(newState, tx); + } } } public resetUnknown(): void { transaction(tx => { + /** @description Reset Unknown Base Range States */ for (const range of this.modifiedBaseRanges.get()) { if (this.getState(range).get().conflicting) { this.setState(range, ModifiedBaseRangeState.default, false, tx); @@ -218,6 +223,7 @@ export class MergeEditorModel extends EditorModel { public mergeNonConflictingDiffs(): void { transaction((tx) => { + /** @description Merge None Conflicting Diffs */ for (const m of this.modifiedBaseRanges.get()) { if (m.isConflicting) { continue; diff --git a/src/vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange.ts b/src/vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange.ts index 4dadbb6816a..028b9afe986 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange.ts @@ -293,6 +293,10 @@ export class ModifiedBaseRangeState { } return arr.join(','); } + + equals(newState: ModifiedBaseRangeState): boolean { + return this.input1 === newState.input1 && this.input2 === newState.input2 && this.input2First === newState.input2First; + } } export const enum InputState { diff --git a/src/vs/workbench/contrib/mergeEditor/browser/model/textModelDiffs.ts b/src/vs/workbench/contrib/mergeEditor/browser/model/textModelDiffs.ts index c57c0ff51ea..ed894cc7e25 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/model/textModelDiffs.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/model/textModelDiffs.ts @@ -54,6 +54,7 @@ export class TextModelDiffs extends Disposable { } transaction(tx => { + /** @description Starting Diff Computation. */ this._state.set( initializing ? TextModelDiffState.initializing : TextModelDiffState.updating, tx, @@ -72,6 +73,7 @@ export class TextModelDiffs extends Disposable { } transaction(tx => { + /** @description Completed Diff Computation */ if (result.diffs) { this._state.set(TextModelDiffState.upToDate, tx, TextModelDiffChangeReason.textChange); this._diffs.set(result.diffs, tx, TextModelDiffChangeReason.textChange); diff --git a/src/vs/workbench/contrib/mergeEditor/browser/utils.ts b/src/vs/workbench/contrib/mergeEditor/browser/utils.ts index 23277aeae95..3188a3b2e7a 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/utils.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/utils.ts @@ -79,7 +79,7 @@ export function applyObservableDecorations(editor: CodeEditorWidget, decorations editor.changeDecorations(a => { decorationIds = a.deltaDecorations(decorationIds, d); }); - }, 'Update Decorations')); + }, `Apply decorations from ${decorations.debugName}`)); d.add({ dispose: () => { editor.changeDecorations(a => { diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts index 08a13900476..0a54f686ca4 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts @@ -5,21 +5,24 @@ import { h } from 'vs/base/browser/dom'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { observableSignalFromEvent } from 'vs/base/common/observable'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; -import { autorun, IReader, observableFromEvent, ObservableValue } from 'vs/workbench/contrib/audioCues/browser/observable'; +import { autorun, IReader, observableFromEvent } from 'vs/workbench/contrib/audioCues/browser/observable'; import { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange'; export class EditorGutter extends Disposable { private readonly scrollTop = observableFromEvent( this._editor.onDidScrollChange, - (e) => this._editor.getScrollTop() + (e) => /** @description editor.onDidScrollChange */ this._editor.getScrollTop() ); + private readonly isScrollTopZero = this.scrollTop.map((scrollTop) => /** @description isScrollTopZero */ scrollTop === 0); private readonly modelAttached = observableFromEvent( this._editor.onDidChangeModel, - (e) => this._editor.hasModel() + (e) => /** @description editor.onDidChangeModel */ this._editor.hasModel() ); - private readonly changeCounter = new ObservableValue(0, 'counter'); + private readonly editorOnDidChangeViewZones = observableSignalFromEvent('onDidChangeViewZones', this._editor.onDidChangeViewZones); + private readonly editorOnDidContentSizeChange = observableSignalFromEvent('onDidContentSizeChange', this._editor.onDidContentSizeChange); constructor( private readonly _editor: CodeEditorWidget, @@ -34,19 +37,10 @@ export class EditorGutter extends D ); this._register(autorun((reader) => { - scrollDecoration.className = this.scrollTop.read(reader) === 0 ? '' : 'scroll-decoration'; + scrollDecoration.className = this.isScrollTopZero.read(reader) ? '' : 'scroll-decoration'; }, 'update scroll decoration')); - - this._register(autorun((reader) => this.render(reader), 'Render')); - - this._editor.onDidChangeViewZones(e => { - this.changeCounter.set(this.changeCounter.get() + 1, undefined); - }); - - this._editor.onDidContentSizeChange(e => { - this.changeCounter.set(this.changeCounter.get() + 1, undefined); - }); + this._register(autorun((reader) => this.render(reader), 'EditorGutter.Render')); } private readonly views = new Map(); @@ -55,7 +49,10 @@ export class EditorGutter extends D if (!this.modelAttached.read(reader)) { return; } - this.changeCounter.read(reader); + + this.editorOnDidChangeViewZones.read(reader); + this.editorOnDidContentSizeChange.read(reader); + const scrollTop = this.scrollTop.read(reader); const visibleRanges = this._editor.getVisibleRanges(); diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts index e9a1b888ce0..415eea716ce 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts @@ -14,14 +14,14 @@ import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { ITextModel } from 'vs/editor/common/model'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { DEFAULT_EDITOR_MAX_DIMENSIONS, DEFAULT_EDITOR_MIN_DIMENSIONS } from 'vs/workbench/browser/parts/editor/editor'; -import { IObservable, observableFromEvent, ObservableValue } from 'vs/workbench/contrib/audioCues/browser/observable'; +import { IObservable, observableFromEvent, ObservableValue, transaction } from 'vs/workbench/contrib/audioCues/browser/observable'; import { setStyle } from 'vs/workbench/contrib/mergeEditor/browser/utils'; import { MergeEditorViewModel } from 'vs/workbench/contrib/mergeEditor/browser/view/viewModel'; export abstract class CodeEditorView extends Disposable { private readonly _viewModel = new ObservableValue(undefined, 'viewModel'); readonly viewModel: IObservable = this._viewModel; - readonly model = this._viewModel.map(m => m?.model); + readonly model = this._viewModel.map(m => /** @description model */ m?.model); protected readonly htmlElements = h('div.code-view', [ h('div.title', { $: 'title' }), @@ -71,15 +71,15 @@ export abstract class CodeEditorView extends Disposable { public readonly isFocused = observableFromEvent( Event.any(this.editor.onDidBlurEditorWidget, this.editor.onDidFocusEditorWidget), - () => this.editor.hasWidgetFocus() + () => /** @description editor.hasWidgetFocus */ this.editor.hasWidgetFocus() ); public readonly cursorPosition = observableFromEvent( this.editor.onDidChangeCursorPosition, - () => this.editor.getPosition() + () => /** @description editor.getPosition */ this.editor.getPosition() ); - public readonly cursorLineNumber = this.cursorPosition.map(p => p?.lineNumber); + public readonly cursorLineNumber = this.cursorPosition.map(p => /** @description cursorPosition.lineNumber */ p?.lineNumber); constructor( @IInstantiationService @@ -103,6 +103,9 @@ export abstract class CodeEditorView extends Disposable { this._title.setLabel(title, description); this._detail.setLabel('', detail); - this._viewModel.set(viewModel, undefined); + transaction(tx => { + /** @description CodeEditorView: Set Model */ + this._viewModel.set(viewModel, tx); + }); } } diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts index aadd274e6e1..476e5143570 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts @@ -8,6 +8,7 @@ import { Toggle } from 'vs/base/browser/ui/toggle/toggle'; import { Action, IAction, Separator } from 'vs/base/common/actions'; import { Codicon } from 'vs/base/common/codicons'; import { Disposable } from 'vs/base/common/lifecycle'; +import { derived, ISettableObservable } from 'vs/base/common/observable'; import { noBreakWhitespace } from 'vs/base/common/strings'; import { isDefined } from 'vs/base/common/types'; import { EditorExtensionsRegistry, IEditorContributionDescription } from 'vs/editor/browser/editorExtensions'; @@ -26,7 +27,7 @@ import { EditorGutter, IGutterItemInfo, IGutterItemView } from '../editorGutter' import { CodeEditorView } from './codeEditorView'; export class InputCodeEditorView extends CodeEditorView { - private readonly decorations = derivedObservable('decorations', reader => { + private readonly decorations = derivedObservable(`input${this.inputNumber}.decorations`, reader => { const viewModel = this.viewModel.read(reader); if (!viewModel) { return []; @@ -99,6 +100,136 @@ export class InputCodeEditorView extends CodeEditorView { return result; }); + private readonly modifiedBaseRangeGutterItemInfos = derived(`input${this.inputNumber}.modifiedBaseRangeGutterItemInfos`, reader => { + const viewModel = this.viewModel.read(reader); + if (!viewModel) { return []; } + const model = viewModel.model; + const inputNumber = this.inputNumber; + + return model.modifiedBaseRanges.read(reader) + .filter((r) => r.getInputDiffs(this.inputNumber).length > 0) + .map((baseRange, idx) => ({ + id: idx.toString(), + range: baseRange.getInputRange(this.inputNumber), + enabled: model.isUpToDate, + toggleState: derivedObservable('checkbox is checked', (reader) => { + const input = model + .getState(baseRange) + .read(reader) + .getInput(this.inputNumber); + return input === InputState.second && !baseRange.isOrderRelevant + ? InputState.first + : input; + } + ), + setState: (value, tx) => viewModel.setState( + baseRange, + model + .getState(baseRange) + .get() + .withInputValue(this.inputNumber, value), + tx + ), + toggleBothSides() { + transaction(tx => { + /** @description Context Menu: toggle both sides */ + const state = model + .getState(baseRange) + .get(); + model.setState( + baseRange, + state + .toggle(inputNumber) + .toggle(inputNumber === 1 ? 2 : 1), + true, + tx + ); + }); + }, + getContextMenuActions: () => { + const state = model.getState(baseRange).get(); + const handled = model.isHandled(baseRange).get(); + + const update = (newState: ModifiedBaseRangeState) => { + transaction(tx => { + /** @description Context Menu: Update Base Range State */ + return viewModel.setState(baseRange, newState, tx); + }); + }; + + function action(id: string, label: string, targetState: ModifiedBaseRangeState, checked: boolean) { + const action = new Action(id, label, undefined, true, () => { + update(targetState); + }); + action.checked = checked; + return action; + } + const both = state.input1 && state.input2; + + return [ + baseRange.input1Diffs.length > 0 + ? action( + 'mergeEditor.acceptInput1', + localize('mergeEditor.accept', 'Accept {0}', model.input1Title), + state.toggle(1), + state.input1 + ) + : undefined, + baseRange.input2Diffs.length > 0 + ? action( + 'mergeEditor.acceptInput2', + localize('mergeEditor.accept', 'Accept {0}', model.input2Title), + state.toggle(2), + state.input2 + ) + : undefined, + baseRange.isConflicting + ? setFields( + action( + 'mergeEditor.acceptBoth', + localize( + 'mergeEditor.acceptBoth', + 'Accept Both' + ), + state.withInput1(!both).withInput2(!both), + both + ), + { enabled: baseRange.canBeCombined } + ) + : undefined, + new Separator(), + baseRange.isConflicting + ? setFields( + action( + 'mergeEditor.swap', + localize('mergeEditor.swap', 'Swap'), + state.swap(), + false + ), + { enabled: !state.isEmpty && (!both || baseRange.isOrderRelevant) } + ) + : undefined, + + setFields( + new Action( + 'mergeEditor.markAsHandled', + localize('mergeEditor.markAsHandled', 'Mark as Handled'), + undefined, + true, + () => { + transaction((tx) => { + /** @description Context Menu: Mark as handled */ + model.setHandled(baseRange, !handled, tx); + }); + } + ), + { checked: handled } + ), + ].filter(isDefined); + } + })); + }); + constructor( public readonly inputNumber: 1 | 2, @IInstantiationService instantiationService: IInstantiationService, @@ -112,127 +243,7 @@ export class InputCodeEditorView extends CodeEditorView { this._register( new EditorGutter(this.editor, this.htmlElements.gutterDiv, { getIntersectingGutterItems: (range, reader) => { - const viewModel = this.viewModel.read(reader); - if (!viewModel) { return []; } - const model = viewModel.model; - - return model.modifiedBaseRanges.read(reader) - .filter((r) => r.getInputDiffs(this.inputNumber).length > 0) - .map((baseRange, idx) => ({ - id: idx.toString(), - range: baseRange.getInputRange(this.inputNumber), - enabled: model.isUpToDate, - toggleState: derivedObservable('toggle', (reader) => { - const input = model - .getState(baseRange) - .read(reader) - .getInput(this.inputNumber); - return input === InputState.second && !baseRange.isOrderRelevant - ? InputState.first - : input; - } - ), - setState: (value, tx) => viewModel.setState( - baseRange, - model - .getState(baseRange) - .get() - .withInputValue(this.inputNumber, value), - tx - ), - toggleBothSides() { - transaction(tx => { - const state = model - .getState(baseRange) - .get(); - model.setState( - baseRange, - state - .toggle(inputNumber) - .toggle(inputNumber === 1 ? 2 : 1), - true, - tx - ); - }); - }, - getContextMenuActions: () => { - const state = model.getState(baseRange).get(); - const handled = model.isHandled(baseRange).get(); - - const update = (newState: ModifiedBaseRangeState) => { - transaction(tx => viewModel.setState(baseRange, newState, tx)); - }; - - function action(id: string, label: string, targetState: ModifiedBaseRangeState, checked: boolean) { - const action = new Action(id, label, undefined, true, () => { - update(targetState); - }); - action.checked = checked; - return action; - } - const both = state.input1 && state.input2; - - return [ - baseRange.input1Diffs.length > 0 - ? action( - 'mergeEditor.acceptInput1', - localize('mergeEditor.accept', 'Accept {0}', model.input1Title), - state.toggle(1), - state.input1 - ) - : undefined, - baseRange.input2Diffs.length > 0 - ? action( - 'mergeEditor.acceptInput2', - localize('mergeEditor.accept', 'Accept {0}', model.input2Title), - state.toggle(2), - state.input2 - ) - : undefined, - baseRange.isConflicting - ? setFields( - action( - 'mergeEditor.acceptBoth', - localize( - 'mergeEditor.acceptBoth', - 'Accept Both' - ), - state.withInput1(!both).withInput2(!both), - both - ), - { enabled: baseRange.canBeCombined } - ) - : undefined, - new Separator(), - baseRange.isConflicting - ? setFields( - action( - 'mergeEditor.swap', - localize('mergeEditor.swap', 'Swap'), - state.swap(), - false - ), - { enabled: !state.isEmpty && (!both || baseRange.isOrderRelevant) } - ) - : undefined, - - setFields( - new Action( - 'mergeEditor.markAsHandled', - localize('mergeEditor.markAsHandled', 'Mark as Handled'), - undefined, - true, - () => { - transaction((tx) => { - model.setHandled(baseRange, !handled, tx); - }); - } - ), - { checked: handled } - ), - ].filter(isDefined); - } - })); + return this.modifiedBaseRangeGutterItemInfos.read(reader); }, createView: (item, target) => new MergeConflictGutterItemView(item, target, contextMenuService, themeService), }) @@ -253,7 +264,7 @@ export interface ModifiedBaseRangeGutterItemInfo extends IGutterItemInfo { } export class MergeConflictGutterItemView extends Disposable implements IGutterItemView { - private readonly item = new ObservableValue(undefined, 'item'); + private readonly item: ISettableObservable; constructor( item: ModifiedBaseRangeGutterItemInfo, @@ -263,7 +274,7 @@ export class MergeConflictGutterItemView extends Disposable implements IGutterIt ) { super(); - this.item.set(item, undefined); + this.item = new ObservableValue(item, 'item'); target.classList.add('merge-accept-gutter-marker'); @@ -315,11 +326,12 @@ export class MergeConflictGutterItemView extends Disposable implements IGutterIt } else { checkBox.enable(); } - }, 'Update Toggle State') + }, 'Update Checkbox') ); this._register(checkBox.onChange(() => { transaction(tx => { + /** @description Handle Checkbox Change */ this.item.get()!.setState(checkBox.checked, tx); }); })); @@ -337,6 +349,9 @@ export class MergeConflictGutterItemView extends Disposable implements IGutterIt } update(baseRange: ModifiedBaseRangeGutterItemInfo): void { - this.item.set(baseRange, undefined); + transaction(tx => { + /** @description MergeConflictGutterItemView: Updating new base range */ + this.item.set(baseRange, tx); + }); } } diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts index fc6919af08a..89e8490cf90 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts @@ -14,7 +14,7 @@ import { handledConflictMinimapOverViewRulerColor, unhandledConflictMinimapOverV import { CodeEditorView } from './codeEditorView'; export class ResultCodeEditorView extends CodeEditorView { - private readonly decorations = derivedObservable('decorations', reader => { + private readonly decorations = derivedObservable('result.decorations', reader => { const viewModel = this.viewModel.read(reader); if (!viewModel) { return []; @@ -125,6 +125,6 @@ export class ResultCodeEditorView extends CodeEditorView { '{0} Remaining Conflicts', count )); - }, 'update label')); + }, 'update remainingConflicts label')); } } diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts index 3f90643ea4a..46c954fb2c3 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts @@ -135,6 +135,7 @@ export class MergeEditorViewModel { return; } transaction(tx => { + /** @description Toggle Active Conflict */ this.setState( activeModifiedBaseRange, this.model.getState(activeModifiedBaseRange).get().toggle(inputNumber), -- cgit v1.2.3 From 3ab72751707134b7a6ec523d6183629f6cfa52ad Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Mon, 4 Jul 2022 07:35:17 +0200 Subject: SCM - Fix issue with commit dropdown button (#154034) Fix issue with commit dropdown button --- src/vs/workbench/contrib/scm/browser/scmViewPane.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts index 1a733fb7680..47801f55fd9 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts @@ -2411,7 +2411,12 @@ export class SCMViewPane extends ViewPane { return; } else if (isSCMActionButton(e.element)) { this.scmViewService.focus(e.element.repository); - this.actionButtonRenderer.focusActionButton(e.element); + + // Focus the action button + const target = e.browserEvent?.target as HTMLElement; + if (target.classList.contains('monaco-tl-row') || target.classList.contains('button-container')) { + this.actionButtonRenderer.focusActionButton(e.element); + } return; } -- cgit v1.2.3 From 2471ff08d8d42e30abe2d606ae56c13e639a1d6e Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Mon, 4 Jul 2022 10:51:33 +0200 Subject: Removes old observable test. --- .../audioCues/test/browser/observable.test.ts | 468 --------------------- 1 file changed, 468 deletions(-) delete mode 100644 src/vs/workbench/contrib/audioCues/test/browser/observable.test.ts (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/audioCues/test/browser/observable.test.ts b/src/vs/workbench/contrib/audioCues/test/browser/observable.test.ts deleted file mode 100644 index 646464cb636..00000000000 --- a/src/vs/workbench/contrib/audioCues/test/browser/observable.test.ts +++ /dev/null @@ -1,468 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as assert from 'assert'; -import { Emitter } from 'vs/base/common/event'; -import { autorun, autorun2, BaseObservable, derivedObservable, IObserver, ITransaction, observableFromEvent, observableValue, ObservableValue, transaction } from 'vs/workbench/contrib/audioCues/browser/observable'; - -suite('observable integration', () => { - test('basic observable + autorun', () => { - const log = new Log(); - const observable = new ObservableValue(0, 'MyObservableValue'); - - autorun((reader) => { - log.log(`value: ${observable.read(reader)}`); - }, 'MyAutorun'); - assert.deepStrictEqual(log.getAndClearEntries(), ['value: 0']); - - observable.set(1, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), ['value: 1']); - - observable.set(1, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), []); - - transaction((tx) => { - observable.set(2, tx); - assert.deepStrictEqual(log.getAndClearEntries(), []); - - observable.set(3, tx); - assert.deepStrictEqual(log.getAndClearEntries(), []); - }); - - assert.deepStrictEqual(log.getAndClearEntries(), ['value: 3']); - }); - - test('basic computed + autorun', () => { - const log = new Log(); - const observable1 = new ObservableValue(0, 'MyObservableValue1'); - const observable2 = new ObservableValue(0, 'MyObservableValue2'); - - const computed = derivedObservable('computed', (reader) => { - const value1 = observable1.read(reader); - const value2 = observable2.read(reader); - const sum = value1 + value2; - log.log(`recompute: ${value1} + ${value2} = ${sum}`); - return sum; - }); - - autorun((reader) => { - log.log(`value: ${computed.read(reader)}`); - }, 'MyAutorun'); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute: 0 + 0 = 0', - 'value: 0', - ]); - - observable1.set(1, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute: 1 + 0 = 1', - 'value: 1', - ]); - - observable2.set(1, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute: 1 + 1 = 2', - 'value: 2', - ]); - - transaction((tx) => { - observable1.set(5, tx); - assert.deepStrictEqual(log.getAndClearEntries(), []); - - observable2.set(5, tx); - assert.deepStrictEqual(log.getAndClearEntries(), []); - }); - - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute: 5 + 5 = 10', - 'value: 10', - ]); - - transaction((tx) => { - observable1.set(6, tx); - assert.deepStrictEqual(log.getAndClearEntries(), []); - - observable2.set(4, tx); - assert.deepStrictEqual(log.getAndClearEntries(), []); - }); - - assert.deepStrictEqual(log.getAndClearEntries(), ['recompute: 6 + 4 = 10']); - }); - - test('read during transaction', () => { - const log = new Log(); - const observable1 = new ObservableValue(0, 'MyObservableValue1'); - const observable2 = new ObservableValue(0, 'MyObservableValue2'); - - const computed = derivedObservable('computed', (reader) => { - const value1 = observable1.read(reader); - const value2 = observable2.read(reader); - const sum = value1 + value2; - log.log(`recompute: ${value1} + ${value2} = ${sum}`); - return sum; - }); - - autorun((reader) => { - log.log(`value: ${computed.read(reader)}`); - }, 'MyAutorun'); - - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute: 0 + 0 = 0', - 'value: 0', - ]); - - log.log(`computed is ${computed.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), ['computed is 0']); - - transaction((tx) => { - observable1.set(-1, tx); - log.log(`computed is ${computed.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute: -1 + 0 = -1', - 'computed is -1', - ]); - - log.log(`computed is ${computed.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), ['computed is -1']); - - observable2.set(1, tx); - assert.deepStrictEqual(log.getAndClearEntries(), []); - }); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute: -1 + 1 = 0', - 'value: 0', - ]); - }); - - test('topological order', () => { - const log = new Log(); - const observable1 = new ObservableValue(0, 'MyObservableValue1'); - const observable2 = new ObservableValue(0, 'MyObservableValue2'); - - const computed1 = derivedObservable('computed1', (reader) => { - const value1 = observable1.read(reader); - const value2 = observable2.read(reader); - const sum = value1 + value2; - log.log(`recompute1: ${value1} + ${value2} = ${sum}`); - return sum; - }); - - const computed2 = derivedObservable('computed2', (reader) => { - const value1 = computed1.read(reader); - const value2 = observable1.read(reader); - const value3 = observable2.read(reader); - const sum = value1 + value2 + value3; - log.log(`recompute2: ${value1} + ${value2} + ${value3} = ${sum}`); - return sum; - }); - - const computed3 = derivedObservable('computed3', (reader) => { - const value1 = computed2.read(reader); - const value2 = observable1.read(reader); - const value3 = observable2.read(reader); - const sum = value1 + value2 + value3; - log.log(`recompute3: ${value1} + ${value2} + ${value3} = ${sum}`); - return sum; - }); - - autorun((reader) => { - log.log(`value: ${computed3.read(reader)}`); - }, 'MyAutorun'); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute1: 0 + 0 = 0', - 'recompute2: 0 + 0 + 0 = 0', - 'recompute3: 0 + 0 + 0 = 0', - 'value: 0', - ]); - - observable1.set(1, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute1: 1 + 0 = 1', - 'recompute2: 1 + 1 + 0 = 2', - 'recompute3: 2 + 1 + 0 = 3', - 'value: 3', - ]); - - transaction((tx) => { - observable1.set(2, tx); - log.log(`computed2: ${computed2.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute1: 2 + 0 = 2', - 'recompute2: 2 + 2 + 0 = 4', - 'computed2: 4', - ]); - - observable1.set(3, tx); - log.log(`computed2: ${computed2.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute1: 3 + 0 = 3', - 'recompute2: 3 + 3 + 0 = 6', - 'computed2: 6', - ]); - }); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute3: 6 + 3 + 0 = 9', - 'value: 9', - ]); - }); - - test('transaction from autorun', () => { - const log = new Log(); - - const observable1 = new ObservableValue(0, 'MyObservableValue1'); - const observable2 = new ObservableValue(0, 'MyObservableValue2'); - - const computed = derivedObservable('computed', (reader) => { - const value1 = observable1.read(reader); - const value2 = observable2.read(reader); - const sum = value1 + value2; - log.log(`recompute: ${value1} + ${value2} = ${sum}`); - return sum; - }); - - autorun((reader) => { - log.log(`value: ${computed.read(reader)}`); - transaction(tx => { - - }); - - }, 'autorun'); - - - }); - - test('from event', () => { - const log = new Log(); - - let value = 0; - const eventEmitter = new Emitter(); - - let id = 0; - const observable = observableFromEvent( - (handler) => { - const curId = id++; - log.log(`subscribed handler ${curId}`); - const disposable = eventEmitter.event(handler); - - return { - dispose: () => { - log.log(`unsubscribed handler ${curId}`); - disposable.dispose(); - }, - }; - }, - () => { - log.log(`compute value ${value}`); - return value; - } - ); - assert.deepStrictEqual(log.getAndClearEntries(), []); - - log.log(`get value: ${observable.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'compute value 0', - 'get value: 0', - ]); - - log.log(`get value: ${observable.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'compute value 0', - 'get value: 0', - ]); - - const shouldReadObservable = new ObservableValue( - true, - 'shouldReadObservable' - ); - - const autorunDisposable = autorun((reader) => { - if (shouldReadObservable.read(reader)) { - observable.read(reader); - log.log( - `autorun, should read: true, value: ${observable.read(reader)}` - ); - } else { - log.log(`autorun, should read: false`); - } - }, 'MyAutorun'); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'subscribed handler 0', - 'compute value 0', - 'autorun, should read: true, value: 0', - ]); - - log.log(`get value: ${observable.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), ['get value: 0']); - - value = 1; - eventEmitter.fire(); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'compute value 1', - 'autorun, should read: true, value: 1', - ]); - - shouldReadObservable.set(false, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'autorun, should read: false', - 'unsubscribed handler 0', - ]); - - shouldReadObservable.set(true, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'subscribed handler 1', - 'compute value 1', - 'autorun, should read: true, value: 1', - ]); - - autorunDisposable.dispose(); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'unsubscribed handler 1', - ]); - }); - - test('get without observers', () => { - // Maybe this scenario should not be supported. - - const log = new Log(); - const observable1 = new ObservableValue(0, 'MyObservableValue1'); - const computed1 = derivedObservable('computed', (reader) => { - const value1 = observable1.read(reader); - const result = value1 % 3; - log.log(`recompute1: ${value1} % 3 = ${result}`); - return result; - }); - const computed2 = derivedObservable('computed', (reader) => { - const value1 = computed1.read(reader); - - const result = value1 * 2; - log.log(`recompute2: ${value1} * 2 = ${result}`); - return result; - }); - const computed3 = derivedObservable('computed', (reader) => { - const value1 = computed1.read(reader); - - const result = value1 * 3; - log.log(`recompute3: ${value1} * 3 = ${result}`); - return result; - }); - const computedSum = derivedObservable('computed', (reader) => { - const value1 = computed2.read(reader); - const value2 = computed3.read(reader); - - const result = value1 + value2; - log.log(`recompute4: ${value1} + ${value2} = ${result}`); - return result; - }); - assert.deepStrictEqual(log.getAndClearEntries(), []); - - observable1.set(1, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), []); - - log.log(`value: ${computedSum.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute1: 1 % 3 = 1', - 'recompute2: 1 * 2 = 2', - 'recompute3: 1 * 3 = 3', - 'recompute4: 2 + 3 = 5', - 'value: 5', - ]); - - log.log(`value: ${computedSum.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute1: 1 % 3 = 1', - 'recompute2: 1 * 2 = 2', - 'recompute3: 1 * 3 = 3', - 'recompute4: 2 + 3 = 5', - 'value: 5', - ]); - }); -}); - -suite('observable details', () => { - test('1', () => { - const log = new Log(); - - class TrackedObservableValue extends BaseObservable { - private value: T; - - constructor(initialValue: T) { - super(); - this.value = initialValue; - } - - public override addObserver(observer: IObserver): void { - log.log(`observable.addObserver ${observer.toString()}`); - super.addObserver(observer); - } - - public override removeObserver(observer: IObserver): void { - log.log(`observable.removeObserver ${observer.toString()}`); - super.removeObserver(observer); - } - - public get(): T { - log.log('observable.get'); - return this.value; - } - - public set(value: T, tx: ITransaction): void { - log.log(`observable.set (value ${value})`); - - if (this.value === value) { - return; - } - this.value = value; - for (const observer of this.observers) { - tx.updateObserver(observer, this); - observer.handleChange(this, undefined); - } - } - } - - const shouldReadObservable = observableValue('shouldReadObservable', true); - const observable = new TrackedObservableValue(0); - const computed = derivedObservable('test', reader => { - if (shouldReadObservable.read(reader)) { - return observable.read(reader) * 2; - } - return 1; - }); - autorun2('test', reader => { - const value = computed.read(reader); - log.log(`autorun: ${value}`); - }); - - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'observable.addObserver LazyDerived', - 'observable.get', - 'autorun: 0', - ]); - - transaction(tx => { - observable.set(1, tx); - assert.deepStrictEqual(log.getAndClearEntries(), (["observable.set (value 1)"])); - - shouldReadObservable.set(false, tx); - assert.deepStrictEqual(log.getAndClearEntries(), ([])); - - computed.get(); - assert.deepStrictEqual(log.getAndClearEntries(), (["observable.removeObserver LazyDerived"])); - }); - assert.deepStrictEqual(log.getAndClearEntries(), (["autorun: 1"])); - }); -}); - -class Log { - private readonly entries: string[] = []; - public log(message: string): void { - this.entries.push(message); - } - - public getAndClearEntries(): string[] { - const entries = [...this.entries]; - this.entries.length = 0; - return entries; - } -} -- cgit v1.2.3 From 3559a3c34edd8fb01eb803ec0c63995dbe6d6329 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 4 Jul 2022 11:05:45 +0200 Subject: Process explorer: indicate extension host better (fix #150820) (#154043) --- src/vs/base/node/ps.ts | 5 +++++ src/vs/platform/extensions/electron-main/extensionHostStarter.ts | 1 + 2 files changed, 6 insertions(+) (limited to 'src/vs') diff --git a/src/vs/base/node/ps.ts b/src/vs/base/node/ps.ts index 4eded868127..8fd62606254 100644 --- a/src/vs/base/node/ps.ts +++ b/src/vs/base/node/ps.ts @@ -52,6 +52,7 @@ export function listProcesses(rootPid: number): Promise { const ISSUE_REPORTER_HINT = /--vscode-window-kind=issue-reporter/; const PROCESS_EXPLORER_HINT = /--vscode-window-kind=process-explorer/; const UTILITY_NETWORK_HINT = /--utility-sub-type=network/; + const UTILITY_EXTENSION_HOST_HINT = /--vscode-utility-kind=extensionHost/; const WINDOWS_CRASH_REPORTER = /--crashes-directory/; const WINDOWS_PTY = /\\pipe\\winpty-control/; const WINDOWS_CONSOLE_HOST = /conhost\.exe/; @@ -93,6 +94,10 @@ export function listProcesses(rootPid: number): Promise { if (UTILITY_NETWORK_HINT.exec(cmd)) { return 'utility-network-service'; } + + if (UTILITY_EXTENSION_HOST_HINT.exec(cmd)) { + return 'extension-host'; + } } return matches[1]; } diff --git a/src/vs/platform/extensions/electron-main/extensionHostStarter.ts b/src/vs/platform/extensions/electron-main/extensionHostStarter.ts index ca52229c320..027748ea8c1 100644 --- a/src/vs/platform/extensions/electron-main/extensionHostStarter.ts +++ b/src/vs/platform/extensions/electron-main/extensionHostStarter.ts @@ -324,6 +324,7 @@ class UtilityExtensionHostProcess extends Disposable { const modulePath = FileAccess.asFileUri('bootstrap-fork.js', require).fsPath; const args: string[] = ['--type=extensionHost', '--skipWorkspaceStorageLock']; const execArgv: string[] = opts.execArgv || []; + execArgv.push(`--vscode-utility-kind=extensionHost`); const env: { [key: string]: any } = { ...opts.env }; // Make sure all values are strings, otherwise the process will not start -- cgit v1.2.3 From a1a0283b7a018c97caa524fd3045e7ce92f27ee0 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 4 Jul 2022 14:21:51 +0200 Subject: adopt #153865 (#154067) --- src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts index 6faf5d3c10a..31cc538fa56 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts @@ -158,7 +158,12 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio constructor() { super({ id: 'workbench.extensions.installLocalExtensions', - get title() { return localize('select and install local extensions', "Install Local Extensions in '{0}'...", server.label); }, + get title() { + return { + value: localize('select and install local extensions', "Install Local Extensions in '{0}'...", server.label), + original: `Install Local Extensions in '${server.label}'...`, + }; + }, category: localize({ key: 'remote', comment: ['Remote as in remote machine'] }, "Remote"), icon: installLocalInRemoteIcon, f1: true, -- cgit v1.2.3 From 496d4b2c1f62db770a832847ac64251d09d506d3 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 4 Jul 2022 14:24:56 +0200 Subject: enable import/export profiles actions in no profile mode (#154022) - enable actions - bring back old code to import profile --- .../common/userDataProfileActions.ts | 32 +++++++++++++++++----- .../userDataProfile/common/userDataProfile.ts | 1 + .../common/userDataProfileImportExportService.ts | 22 +++++++++++++-- 3 files changed, 46 insertions(+), 9 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts b/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts index e796f1f897e..cda5ca4d8fe 100644 --- a/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts +++ b/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts @@ -7,8 +7,8 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { joinPath } from 'vs/base/common/resources'; import { localize } from 'vs/nls'; -import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; -import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; +import { IDialogService, IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IFileService } from 'vs/platform/files/common/files'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -19,6 +19,7 @@ import { ITextFileService } from 'vs/workbench/services/textfile/common/textfile import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { CATEGORIES } from 'vs/workbench/common/actions'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; registerAction2(class CreateFromCurrentProfileAction extends Action2 { constructor() { @@ -196,14 +197,14 @@ registerAction2(class ExportProfileAction extends Action2 { original: 'Export Settings Profile...' }, category: PROFILES_CATEGORY, - f1: true, - precondition: PROFILES_ENABLEMENT_CONTEXT, menu: [ { id: ManageProfilesSubMenu, group: '3_import_export_profiles', when: PROFILES_ENABLEMENT_CONTEXT, order: 1 + }, { + id: MenuId.CommandPalette } ] }); @@ -241,14 +242,14 @@ registerAction2(class ImportProfileAction extends Action2 { original: 'Import Settings Profile...' }, category: PROFILES_CATEGORY, - f1: true, - precondition: PROFILES_ENABLEMENT_CONTEXT, menu: [ { id: ManageProfilesSubMenu, group: '3_import_export_profiles', when: PROFILES_ENABLEMENT_CONTEXT, order: 2 + }, { + id: MenuId.CommandPalette } ] }); @@ -260,6 +261,19 @@ registerAction2(class ImportProfileAction extends Action2 { const fileService = accessor.get(IFileService); const requestService = accessor.get(IRequestService); const userDataProfileImportExportService = accessor.get(IUserDataProfileImportExportService); + const dialogService = accessor.get(IDialogService); + const contextKeyService = accessor.get(IContextKeyService); + + const isSettingProfilesEnabled = contextKeyService.contextMatchesRules(PROFILES_ENABLEMENT_CONTEXT); + + if (!isSettingProfilesEnabled) { + if (!(await dialogService.confirm({ + title: localize('import profile title', "Import Settings from a Profile"), + message: localize('confiirmation message', "This will replace your current settings. Are you sure you want to continue?"), + })).confirmed) { + return; + } + } const disposables = new DisposableStore(); const quickPick = disposables.add(quickInputService.createQuickPick()); @@ -278,7 +292,11 @@ registerAction2(class ImportProfileAction extends Action2 { quickPick.hide(); const profile = quickPick.selectedItems[0].description ? await this.getProfileFromURL(quickPick.value, requestService) : await this.getProfileFromFileSystem(fileDialogService, fileService); if (profile) { - await userDataProfileImportExportService.importProfile(profile); + if (isSettingProfilesEnabled) { + await userDataProfileImportExportService.importProfile(profile); + } else { + await userDataProfileImportExportService.setProfile(profile); + } } })); disposables.add(quickPick.onDidHide(() => disposables.dispose())); diff --git a/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts b/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts index a293ec712b1..bed76364445 100644 --- a/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts +++ b/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts @@ -60,6 +60,7 @@ export interface IUserDataProfileImportExportService { exportProfile(options?: ProfileCreationOptions): Promise; importProfile(profile: IUserDataProfileTemplate): Promise; + setProfile(profile: IUserDataProfileTemplate): Promise; } export interface IResourceProfile { diff --git a/src/vs/workbench/services/userDataProfile/common/userDataProfileImportExportService.ts b/src/vs/workbench/services/userDataProfile/common/userDataProfileImportExportService.ts index 7403079c1ef..8b9b4b76309 100644 --- a/src/vs/workbench/services/userDataProfile/common/userDataProfileImportExportService.ts +++ b/src/vs/workbench/services/userDataProfile/common/userDataProfileImportExportService.ts @@ -56,7 +56,7 @@ export class UserDataProfileImportExportService implements IUserDataProfileImpor await this.progressService.withProgress({ location: ProgressLocation.Notification, - title: localize('profiles.applying', "{0}: Importing...", PROFILES_CATEGORY), + title: localize('profiles.importing', "{0}: Importing...", PROFILES_CATEGORY), }, async progress => { await this.userDataProfileManagementService.createAndEnterProfile(name); if (profileTemplate.settings) { @@ -70,7 +70,25 @@ export class UserDataProfileImportExportService implements IUserDataProfileImpor } }); - this.notificationService.info(localize('applied profile', "{0}: Imported successfully.", PROFILES_CATEGORY)); + this.notificationService.info(localize('imported profile', "{0}: Imported successfully.", PROFILES_CATEGORY)); + } + + async setProfile(profile: IUserDataProfileTemplate): Promise { + await this.progressService.withProgress({ + location: ProgressLocation.Notification, + title: localize('profiles.applying', "{0}: Applying...", PROFILES_CATEGORY), + }, async progress => { + if (profile.settings) { + await this.settingsProfile.applyProfile(profile.settings); + } + if (profile.globalState) { + await this.globalStateProfile.applyProfile(profile.globalState); + } + if (profile.extensions) { + await this.extensionsProfile.applyProfile(profile.extensions); + } + }); + this.notificationService.info(localize('applied profile', "{0}: Applied successfully.", PROFILES_CATEGORY)); } } -- cgit v1.2.3 From 61188536ed77f5515346560db34f4046ab646d45 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Jul 2022 14:32:58 +0200 Subject: debt - add `Event#fromObservable` to bridge between observables and emitters (#154069) --- src/vs/base/common/event.ts | 50 ++++++++++++++++++++++ src/vs/base/test/common/event.test.ts | 30 ++++++++++++- .../mergeEditor/browser/mergeEditorInput.ts | 7 +-- 3 files changed, 81 insertions(+), 6 deletions(-) (limited to 'src/vs') diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index 647b5f1beed..5ceab5b92a0 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -8,6 +8,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { once as onceFn } from 'vs/base/common/functional'; import { combinedDisposable, Disposable, DisposableStore, IDisposable, SafeDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { LinkedList } from 'vs/base/common/linkedList'; +import { IObservable, IObserver } from 'vs/base/common/observable'; import { StopWatch } from 'vs/base/common/stopwatch'; @@ -423,6 +424,55 @@ export namespace Event { store?.dispose(); }); } + + class EmitterObserver implements IObserver { + + readonly emitter: Emitter; + + private _counter = 0; + private _hasChanged = false; + + constructor(readonly obs: IObservable, store: DisposableStore | undefined) { + const options = { + onFirstListenerAdd: () => { + obs.addObserver(this); + }, + onLastListenerRemove: () => { + obs.removeObserver(this); + } + }; + if (!store) { + _addLeakageTraceLogic(options); + } + this.emitter = new Emitter(options); + if (store) { + store.add(this.emitter); + } + } + + beginUpdate(_observable: IObservable): void { + // console.assert(_observable === this.obs); + this._counter++; + } + + handleChange(_observable: IObservable, _change: TChange): void { + this._hasChanged = true; + } + + endUpdate(_observable: IObservable): void { + if (--this._counter === 0) { + if (this._hasChanged) { + this._hasChanged = false; + this.emitter.fire(this.obs.get()); + } + } + } + } + + export function fromObservable(obs: IObservable, store?: DisposableStore): Event { + const observer = new EmitterObserver(obs, store); + return observer.emitter.event; + } } export interface EmitterOptions { diff --git a/src/vs/base/test/common/event.test.ts b/src/vs/base/test/common/event.test.ts index a34566c10f1..39d878bce5d 100644 --- a/src/vs/base/test/common/event.test.ts +++ b/src/vs/base/test/common/event.test.ts @@ -8,7 +8,8 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { errorHandler, setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { AsyncEmitter, DebounceEmitter, Emitter, Event, EventBufferer, EventMultiplexer, IWaitUntil, MicrotaskEmitter, PauseableEmitter, Relay } from 'vs/base/common/event'; import { DisposableStore, IDisposable, isDisposable, setDisposableTracker, toDisposable } from 'vs/base/common/lifecycle'; -import { DisposableTracker } from 'vs/base/test/common/utils'; +import { observableValue, transaction } from 'vs/base/common/observable'; +import { DisposableTracker, ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; namespace Samples { @@ -624,6 +625,33 @@ suite('PausableEmitter', function () { }); }); +suite('Event utils - ensureNoDisposablesAreLeakedInTestSuite', function () { + ensureNoDisposablesAreLeakedInTestSuite(); + + test('fromObservable', function () { + + const obs = observableValue('test', 12); + const event = Event.fromObservable(obs); + + const values: number[] = []; + const d = event(n => { values.push(n); }); + + obs.set(3, undefined); + obs.set(13, undefined); + obs.set(3, undefined); + obs.set(33, undefined); + obs.set(1, undefined); + + transaction(tx => { + obs.set(334, tx); + obs.set(99, tx); + }); + + assert.deepStrictEqual(values, ([3, 13, 3, 33, 1, 99])); + d.dispose(); + }); +}); + suite('Event utils', () => { suite('EventBufferer', () => { diff --git a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts index 137f5a9b992..660d10cb487 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts @@ -17,12 +17,12 @@ import { IEditorIdentifier, IUntypedEditorInput } from 'vs/workbench/common/edit import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { AbstractTextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { EditorWorkerServiceDiffComputer } from 'vs/workbench/contrib/mergeEditor/browser/model/diffComputer'; -import { autorun } from 'vs/workbench/contrib/audioCues/browser/observable'; import { MergeEditorModel } from 'vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { ILanguageSupport, ITextFileEditorModel, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { assertType } from 'vs/base/common/types'; +import { Event } from 'vs/base/common/event'; export class MergeEditorInputData { constructor( @@ -123,10 +123,7 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements this._store.add(input2); this._store.add(result); - this._store.add(autorun(reader => { - this._model?.hasUnhandledConflicts.read(reader); - this._onDidChangeDirty.fire(undefined); - }, 'drive::onDidChangeDirty')); + this._store.add(Event.fromObservable(this._model.hasUnhandledConflicts)(() => this._onDidChangeDirty.fire(undefined))); } this._ignoreUnhandledConflictsForDirtyState = undefined; -- cgit v1.2.3 From 62ab77fa2127d17624f918745029b80206c1bfd6 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Jul 2022 14:46:33 +0200 Subject: use `ICommandActionTitle` over simple string (#154081) https://github.com/microsoft/vscode/issues/153865 --- .../workbench/api/browser/mainThreadFileSystemEventService.ts | 5 ++++- .../contrib/inlayHints/browser/inlayHintsAccessibilty.ts | 10 ++++++++-- .../languageStatus/browser/languageStatus.contribution.ts | 10 ++++++++-- 3 files changed, 20 insertions(+), 5 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts b/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts index 54a2887e33b..c7c01c717bf 100644 --- a/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts +++ b/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts @@ -185,7 +185,10 @@ registerAction2(class ResetMemento extends Action2 { constructor() { super({ id: 'files.participants.resetChoice', - title: localize('label', "Reset choice for 'File operation needs preview'"), + title: { + value: localize('label', "Reset choice for 'File operation needs preview'"), + original: `Reset choice for 'File operation needs preview'` + }, f1: true }); } diff --git a/src/vs/workbench/contrib/inlayHints/browser/inlayHintsAccessibilty.ts b/src/vs/workbench/contrib/inlayHints/browser/inlayHintsAccessibilty.ts index 2766516fdc0..e3d83192f51 100644 --- a/src/vs/workbench/contrib/inlayHints/browser/inlayHintsAccessibilty.ts +++ b/src/vs/workbench/contrib/inlayHints/browser/inlayHintsAccessibilty.ts @@ -174,7 +174,10 @@ registerAction2(class StartReadHints extends EditorAction2 { constructor() { super({ id: 'inlayHints.startReadingLineWithHint', - title: localize('read.title', 'Read Line With Inline Hints'), + title: { + value: localize('read.title', 'Read Line With Inline Hints'), + original: 'Read Line With Inline Hints' + }, precondition: EditorContextKeys.hasInlayHintsProvider, f1: true }); @@ -193,7 +196,10 @@ registerAction2(class StopReadHints extends EditorAction2 { constructor() { super({ id: 'inlayHints.stopReadingLineWithHint', - title: localize('stop.title', 'Stop Inlay Hints Reading'), + title: { + value: localize('stop.title', 'Stop Inlay Hints Reading'), + original: 'Stop Inlay Hints Reading' + }, precondition: InlayHintsAccessibility.IsReading, f1: true, keybinding: { diff --git a/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts b/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts index 661059e89b9..63b120d3b3c 100644 --- a/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts +++ b/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts @@ -398,8 +398,14 @@ registerAction2(class extends Action2 { constructor() { super({ id: 'editor.inlayHints.Reset', - title: localize('reset', 'Reset Language Status Interaction Counter'), - category: localize('cat', 'View'), + title: { + value: localize('reset', 'Reset Language Status Interaction Counter'), + original: 'Reset Language Status Interaction Counter' + }, + category: { + value: localize('cat', 'View'), + original: 'View' + }, f1: true }); } -- cgit v1.2.3 From cdc1920447dc5d857ec947981f79a21674dcaa74 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 4 Jul 2022 14:53:00 +0200 Subject: introduce immediate update (#154082) --- .../contrib/output/browser/outputServices.ts | 2 +- .../contrib/output/common/outputChannelModel.ts | 28 +++++++++++----------- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/output/browser/outputServices.ts b/src/vs/workbench/contrib/output/browser/outputServices.ts index c13ec6b5e0c..e9f97c01b29 100644 --- a/src/vs/workbench/contrib/output/browser/outputServices.ts +++ b/src/vs/workbench/contrib/output/browser/outputServices.ts @@ -48,7 +48,7 @@ class OutputChannel extends Disposable implements IOutputChannel { } update(mode: OutputChannelUpdateMode, till?: number): void { - this.model.update(mode, till); + this.model.update(mode, till, true); } clear(): void { diff --git a/src/vs/workbench/contrib/output/common/outputChannelModel.ts b/src/vs/workbench/contrib/output/common/outputChannelModel.ts index 4c01e67797c..58f8374650b 100644 --- a/src/vs/workbench/contrib/output/common/outputChannelModel.ts +++ b/src/vs/workbench/contrib/output/common/outputChannelModel.ts @@ -26,7 +26,7 @@ import { OutputChannelUpdateMode } from 'vs/workbench/services/output/common/out export interface IOutputChannelModel extends IDisposable { readonly onDispose: Event; append(output: string): void; - update(mode: OutputChannelUpdateMode, till?: number): void; + update(mode: OutputChannelUpdateMode, till: number | undefined, immediate: boolean): void; loadModel(): Promise; clear(): void; replace(value: string): void; @@ -129,12 +129,12 @@ export class FileOutputChannelModel extends Disposable implements IOutputChannel } clear(): void { - this.update(OutputChannelUpdateMode.Clear, this.endOffset); + this.update(OutputChannelUpdateMode.Clear, this.endOffset, true); } - update(mode: OutputChannelUpdateMode, till?: number): void { + update(mode: OutputChannelUpdateMode, till: number | undefined, immediate: boolean): void { const loadModelPromise: Promise = this.loadModelPromise ? this.loadModelPromise : Promise.resolve(); - loadModelPromise.then(() => this.doUpdate(mode, till)); + loadModelPromise.then(() => this.doUpdate(mode, till, immediate)); } loadModel(): Promise { @@ -174,7 +174,7 @@ export class FileOutputChannelModel extends Disposable implements IOutputChannel return this.model; } - private doUpdate(mode: OutputChannelUpdateMode, till?: number): void { + private doUpdate(mode: OutputChannelUpdateMode, till: number | undefined, immediate: boolean): void { if (mode === OutputChannelUpdateMode.Clear || mode === OutputChannelUpdateMode.Replace) { this.startOffset = this.endOffset = isNumber(till) ? till : this.endOffset; this.cancelModelUpdate(); @@ -198,7 +198,7 @@ export class FileOutputChannelModel extends Disposable implements IOutputChannel } else { - this.appendContent(this.model, token); + this.appendContent(this.model, immediate, token); } } @@ -206,7 +206,7 @@ export class FileOutputChannelModel extends Disposable implements IOutputChannel this.doUpdateModel(model, [EditOperation.delete(model.getFullModelRange())], VSBuffer.fromString('')); } - private async appendContent(model: ITextModel, token: CancellationToken): Promise { + private async appendContent(model: ITextModel, immediate: boolean, token: CancellationToken): Promise { this.appendThrottler.trigger(async () => { /* Abort if operation is cancelled */ if (token.isCancellationRequested) { @@ -234,7 +234,7 @@ export class FileOutputChannelModel extends Disposable implements IOutputChannel const lastLineMaxColumn = model.getLineMaxColumn(lastLine); const edits = [EditOperation.insert(new Position(lastLine, lastLineMaxColumn), contentToAppend.toString())]; this.doUpdateModel(model, edits, contentToAppend); - }); + }, immediate ? 0 : undefined); } private async replaceContent(model: ITextModel, token: CancellationToken): Promise { @@ -298,10 +298,10 @@ export class FileOutputChannelModel extends Disposable implements IOutputChannel if (!this.modelUpdateInProgress) { if (isNumber(size) && this.endOffset > size) { // Reset - Content is removed - this.update(OutputChannelUpdateMode.Clear, 0); + this.update(OutputChannelUpdateMode.Clear, 0, true); } } - this.update(OutputChannelUpdateMode.Append); + this.update(OutputChannelUpdateMode.Append, undefined, false /* Not needed to update immediately. Wait to collect more changes and update. */); } } @@ -340,13 +340,13 @@ class OutputChannelBackedByFile extends FileOutputChannelModel implements IOutpu override append(message: string): void { this.write(message); - this.update(OutputChannelUpdateMode.Append); + this.update(OutputChannelUpdateMode.Append, undefined, this.isVisible()); } override replace(message: string): void { const till = this._offset; this.write(message); - this.update(OutputChannelUpdateMode.Replace, till); + this.update(OutputChannelUpdateMode.Replace, till, true); } private write(content: string): void { @@ -391,8 +391,8 @@ export class DelegatedOutputChannelModel extends Disposable implements IOutputCh this.outputChannelModel.then(outputChannelModel => outputChannelModel.append(output)); } - update(mode: OutputChannelUpdateMode, till?: number): void { - this.outputChannelModel.then(outputChannelModel => outputChannelModel.update(mode, till)); + update(mode: OutputChannelUpdateMode, till: number | undefined, immediate: boolean): void { + this.outputChannelModel.then(outputChannelModel => outputChannelModel.update(mode, till, immediate)); } loadModel(): Promise { -- cgit v1.2.3 From 428c8e29bd6b18729e4ba3c6af971f8db9eb8694 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Mon, 4 Jul 2022 15:37:48 +0200 Subject: SCM - More focus related fixes to the commit action button (#154087) More focus related fixes to the commit action button --- src/vs/base/browser/ui/list/listWidget.ts | 16 ++++++++++++++++ src/vs/base/browser/ui/tree/abstractTree.ts | 6 ++++-- src/vs/workbench/contrib/scm/browser/scmViewPane.ts | 2 ++ 3 files changed, 22 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 20df7f37ba8..d97fe00bbf2 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -258,6 +258,22 @@ export function isMonacoEditor(e: HTMLElement): boolean { return isMonacoEditor(e.parentElement); } +export function isButton(e: HTMLElement): boolean { + if (e.tagName === 'A' && e.classList.contains('monaco-button')) { + return true; + } + + if (e.classList.contains('monaco-list')) { + return false; + } + + if (!e.parentElement) { + return false; + } + + return isButton(e.parentElement); +} + class KeyboardController implements IDisposable { private readonly disposables = new DisposableStore(); diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index c03f5c5e1af..124d926541f 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -9,7 +9,7 @@ import { DomEmitter } from 'vs/base/browser/event'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IIdentityProvider, IKeyboardNavigationDelegate, IKeyboardNavigationLabelProvider, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IListMouseEvent, IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView'; -import { DefaultKeyboardNavigationDelegate, IListOptions, IListStyles, isInputElement, isMonacoEditor, List, MouseController } from 'vs/base/browser/ui/list/listWidget'; +import { DefaultKeyboardNavigationDelegate, IListOptions, IListStyles, isButton, isInputElement, isMonacoEditor, List, MouseController } from 'vs/base/browser/ui/list/listWidget'; import { getVisibleState, isFilterResult } from 'vs/base/browser/ui/tree/indexTreeModel'; import { ICollapseStateChangeEvent, ITreeContextMenuEvent, ITreeDragAndDrop, ITreeEvent, ITreeFilter, ITreeModel, ITreeModelSpliceEvent, ITreeMouseEvent, ITreeNavigator, ITreeNode, ITreeRenderer, TreeDragOverBubble, TreeError, TreeFilterResult, TreeMouseEventTarget, TreeVisibility } from 'vs/base/browser/ui/tree/tree'; import { distinct, equals, firstOrDefault, range } from 'vs/base/common/arrays'; @@ -1153,7 +1153,9 @@ class TreeNodeListMouseController extends MouseController< } protected override onViewPointer(e: IListMouseEvent>): void { - if (isInputElement(e.browserEvent.target as HTMLElement) || isMonacoEditor(e.browserEvent.target as HTMLElement)) { + if (isButton(e.browserEvent.target as HTMLElement) || + isInputElement(e.browserEvent.target as HTMLElement) || + isMonacoEditor(e.browserEvent.target as HTMLElement)) { return; } diff --git a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts index 47801f55fd9..41cce292993 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts @@ -2400,6 +2400,7 @@ export class SCMViewPane extends ViewPane { if (widget) { widget.focus(); + this.tree.setFocus([], e.browserEvent); const selection = this.tree.getSelection(); @@ -2416,6 +2417,7 @@ export class SCMViewPane extends ViewPane { const target = e.browserEvent?.target as HTMLElement; if (target.classList.contains('monaco-tl-row') || target.classList.contains('button-container')) { this.actionButtonRenderer.focusActionButton(e.element); + this.tree.setFocus([], e.browserEvent); } return; -- cgit v1.2.3 From d63c49ea080b51b65b73d348f2a09432ed4caab7 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Jul 2022 15:38:09 +0200 Subject: push workaround for https://github.com/microsoft/vscode/issues/154083 (#154084) --- src/vs/base/common/event.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index 5ceab5b92a0..d395e4a9f32 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -8,7 +8,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { once as onceFn } from 'vs/base/common/functional'; import { combinedDisposable, Disposable, DisposableStore, IDisposable, SafeDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { LinkedList } from 'vs/base/common/linkedList'; -import { IObservable, IObserver } from 'vs/base/common/observable'; +import { IObservable, IObserver } from 'vs/base/common/observableImpl/base'; import { StopWatch } from 'vs/base/common/stopwatch'; -- cgit v1.2.3 From e2209cb03d3d542075785aef89b6e5b6c8c719fa Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 4 Jul 2022 15:39:48 +0200 Subject: make sure focus outline fits into CC box fixes https://github.com/microsoft/vscode/issues/153763 --- src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css index b661db98d5c..b0452d28eb2 100644 --- a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css +++ b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css @@ -101,8 +101,8 @@ color: var(--vscode-commandCenter-foreground); background-color: var(--vscode-commandCenter-background); border: 1px solid var(--vscode-commandCenter-border); - border-radius: 5px; - height: 20px; + border-radius: 6px; + height: 22px; line-height: 18px; width: 38vw; max-width: 600px; @@ -119,9 +119,9 @@ line-height: 18px; } -.monaco-workbench .part.titlebar>.titlebar-container>.window-title>.command-center:HOVER .quickopen .action-label { - background-color: transparent !important; - outline-color: transparent !important; +.monaco-workbench .part.titlebar>.titlebar-container>.window-title>.command-center .action-item.quickopen>.action-label { + height: 16px; + line-height: 16px; } .monaco-workbench .part.titlebar>.titlebar-container>.window-title>.command-center .action-item.quickopen>.action-label.search { -- cgit v1.2.3 From b2d1f531341fa9416a7f5d3c8ce2226e0e43e8b8 Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 4 Jul 2022 16:34:20 +0200 Subject: make CC be two special `MenuEntryActionViewItem` instances and style them as one fixes https://github.com/microsoft/vscode/issues/153762 --- .../browser/parts/titlebar/commandCenterControl.ts | 53 +++++++++++-------- .../browser/parts/titlebar/media/titlebarpart.css | 59 +++++++++++----------- 2 files changed, 63 insertions(+), 49 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts b/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts index de2f74a7b2f..cc6278c3a34 100644 --- a/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts @@ -4,21 +4,20 @@ *--------------------------------------------------------------------------------------------*/ import { reset } from 'vs/base/browser/dom'; -import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems'; import { IHoverDelegate } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate'; import { renderIcon } from 'vs/base/browser/ui/iconLabel/iconLabels'; import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar'; -import { Action, IAction } from 'vs/base/common/actions'; +import { IAction } from 'vs/base/common/actions'; import { Codicon } from 'vs/base/common/codicons'; import { Emitter, Event } from 'vs/base/common/event'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { assertType } from 'vs/base/common/types'; import { localize } from 'vs/nls'; import { createActionViewItem, createAndFillInContextMenuActions, MenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem'; -import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions'; +import { Action2, IMenuService, MenuId, MenuItemAction, registerAction2 } from 'vs/platform/actions/common/actions'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import * as colors from 'vs/platform/theme/common/colorRegistry'; @@ -57,7 +56,7 @@ export class CommandCenterControl { override render(container: HTMLElement): void { super.render(container); - container.classList.add('quickopen'); + container.classList.add('quickopen', 'left'); assertType(this.label); this.label.classList.add('search'); @@ -68,7 +67,7 @@ export class CommandCenterControl { this.workspaceTitle.classList.add('search-label'); this._updateFromWindowTitle(); reset(this.label, searchIcon, this.workspaceTitle); - this._renderAllQuickPickItem(container); + // this._renderAllQuickPickItem(container); this._store.add(windowTitle.onDidChange(this._updateFromWindowTitle, this)); } @@ -96,24 +95,23 @@ export class CommandCenterControl { : localize('title2', "Search {0} \u2014 {1}", windowTitle.workspaceName, windowTitle.value); this._applyUpdateTooltip(title); } + } + return instantiationService.createInstance(InputLikeViewItem, action, { hoverDelegate }); - private _renderAllQuickPickItem(parent: HTMLElement): void { - const container = document.createElement('span'); - container.classList.add('all-options'); - parent.appendChild(container); - const action = new Action('all', localize('all', "Show Search Modes..."), Codicon.chevronDown.classNames, true, () => { - quickInputService.quickAccess.show('?'); - }); - const dropdown = new ActionViewItem(undefined, action, { icon: true, label: false, hoverDelegate }); - dropdown.render(container); - this._store.add(dropdown); - this._store.add(action); + } else if (action instanceof MenuItemAction && action.id === 'commandCenter.help') { + + class ExtraClass extends MenuEntryActionViewItem { + override render(container: HTMLElement): void { + super.render(container); + container.classList.add('quickopen', 'right'); } } - return instantiationService.createInstance(InputLikeViewItem, action, { hoverDelegate }); - } - return createActionViewItem(instantiationService, action, { hoverDelegate }); + return instantiationService.createInstance(ExtraClass, action, { hoverDelegate }); + + } else { + return createActionViewItem(instantiationService, action, { hoverDelegate }); + } } }); const menu = this._disposables.add(menuService.createMenu(MenuId.CommandCenter, contextKeyService)); @@ -143,6 +141,21 @@ export class CommandCenterControl { } } +registerAction2(class extends Action2 { + + constructor() { + super({ + id: 'commandCenter.help', + title: localize('all', "Show Search Modes..."), + icon: Codicon.chevronDown, + menu: { id: MenuId.CommandCenter, order: 100 } + }); + } + run(accessor: ServicesAccessor): void { + accessor.get(IQuickInputService).quickAccess.show('?'); + } +}); + // --- theme colors // foreground (inactive and active) diff --git a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css index b0452d28eb2..29f1142364e 100644 --- a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css +++ b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css @@ -101,13 +101,6 @@ color: var(--vscode-commandCenter-foreground); background-color: var(--vscode-commandCenter-background); border: 1px solid var(--vscode-commandCenter-border); - border-radius: 6px; - height: 22px; - line-height: 18px; - width: 38vw; - max-width: 600px; - min-width: 32px; - margin: 0 4px; flex-direction: row; justify-content: center; overflow: hidden; @@ -116,47 +109,55 @@ .monaco-workbench .part.titlebar>.titlebar-container>.window-title>.command-center .action-item.quickopen:HOVER { color: var(--vscode-commandCenter-activeForeground); background-color: var(--vscode-commandCenter-activeBackground); - line-height: 18px; } -.monaco-workbench .part.titlebar>.titlebar-container>.window-title>.command-center .action-item.quickopen>.action-label { - height: 16px; - line-height: 16px; +.monaco-workbench .part.titlebar>.titlebar-container>.window-title>.command-center .action-item.quickopen.left { + /* border,margin tricks */ + margin-left: 6px; + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; + border-right: none; + + /* width */ + width: 38vw; + max-width: 600px; + min-width: 32px; +} + +.monaco-workbench .part.titlebar>.titlebar-container>.window-title>.command-center .action-item.quickopen.right { + /* border,margin tricks */ + margin-right: 6px; + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; + border-left: none; + + /* width */ + width: 16px; } -.monaco-workbench .part.titlebar>.titlebar-container>.window-title>.command-center .action-item.quickopen>.action-label.search { +.monaco-workbench .part.titlebar>.titlebar-container>.window-title>.command-center .action-item.quickopen>.action-label { + height: 22px; + line-height: 22px; + padding: 0; + background-color: transparent; display: inline-flex; text-align: center; font-size: 12px; - background-color: inherit; justify-content: center; - width: calc(100% - 19px); + width: 100%; } -.monaco-workbench .part.titlebar>.titlebar-container>.window-title>.command-center .action-item.quickopen>.action-label.search>.search-icon { +.monaco-workbench .part.titlebar>.titlebar-container>.window-title>.command-center .action-item.quickopen.left>.action-label.search>.search-icon { font-size: 14px; opacity: .8; margin: auto 3px; } -.monaco-workbench .part.titlebar>.titlebar-container>.window-title>.command-center .action-item.quickopen>.action-label.search>.search-label { +.monaco-workbench .part.titlebar>.titlebar-container>.window-title>.command-center .action-item.quickopen.left>.action-label.search>.search-label { overflow: hidden; text-overflow: ellipsis; } -.monaco-workbench .part.titlebar>.titlebar-container>.window-title>.command-center .action-item.quickopen>.all-options>.action-label { - text-align: center; - font-size: 12px; - width: 16px; - border-left: 1px solid transparent; - border-radius: 0; - padding-right: 0; -} - -.monaco-workbench .part.titlebar>.titlebar-container>.window-title>.command-center:HOVER .action-item.quickopen>.all-options>.action-label { - border-color: var(--vscode-commandCenter-border); -} - /* Menubar */ .monaco-workbench .part.titlebar>.titlebar-container>.menubar { /* move menubar above drag region as negative z-index on drag region cause greyscale AA */ -- cgit v1.2.3 From 6e3e8aa68822662dd5de879e060016e5aeaf978f Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 4 Jul 2022 16:35:37 +0200 Subject: Fix #153730 (#154093) --- src/vs/platform/files/browser/indexedDBFileSystemProvider.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts b/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts index 36b2f65cdfc..af4458fe1c0 100644 --- a/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts +++ b/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts @@ -253,7 +253,7 @@ export class IndexedDBFileSystemProvider extends Disposable implements IFileSyst private readonly _onReportError = this._register(new Emitter()); readonly onReportError = this._onReportError.event; - private readonly versions = new Map(); + private readonly mtimes = new Map(); private cachedFiletree: Promise | undefined; private writeManyThrottler: Throttler; @@ -289,7 +289,7 @@ export class IndexedDBFileSystemProvider extends Disposable implements IFileSyst return { type: FileType.File, ctime: 0, - mtime: this.versions.get(resource.toString()) || 0, + mtime: this.mtimes.get(resource.toString()) || 0, size: entry.size ?? (await this.readFile(resource)).byteLength }; } @@ -434,7 +434,7 @@ export class IndexedDBFileSystemProvider extends Disposable implements IFileSyst } await this.deleteKeys(toDelete); (await this.getFiletree()).delete(resource.path); - toDelete.forEach(key => this.versions.delete(key)); + toDelete.forEach(key => this.mtimes.delete(key)); this.triggerChanges(toDelete.map(path => ({ resource: resource.with({ path }), type: FileChangeType.DELETED }))); } @@ -487,7 +487,7 @@ export class IndexedDBFileSystemProvider extends Disposable implements IFileSyst const fileTree = await this.getFiletree(); for (const [resource, content] of files) { fileTree.add(resource.path, { type: 'file', size: content.byteLength }); - this.versions.set(resource.toString(), (this.versions.get(resource.toString()) || 0) + 1); + this.mtimes.set(resource.toString(), Date.now()); } this.triggerChanges(files.map(([resource]) => ({ resource, type: FileChangeType.UPDATED }))); -- cgit v1.2.3 From 11d625ee1ff47bb46121af63ef6a0bb4f96cd9bd Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Mon, 4 Jul 2022 16:35:58 +0200 Subject: completes observable refactoring (#154089) --- src/vs/base/common/observableImpl/base.ts | 2 +- .../browser/audioCueDebuggerContribution.ts | 2 +- .../browser/audioCueLineFeatureContribution.ts | 26 +++++--------- .../contrib/audioCues/browser/audioCueService.ts | 4 +-- .../contrib/audioCues/browser/observable.ts | 40 ---------------------- .../mergeEditor/browser/model/mergeEditorModel.ts | 24 ++++++------- .../mergeEditor/browser/model/textModelDiffs.ts | 6 ++-- .../workbench/contrib/mergeEditor/browser/utils.ts | 9 +++-- .../mergeEditor/browser/view/editorGutter.ts | 9 +++-- .../browser/view/editors/codeEditorView.ts | 4 +-- .../browser/view/editors/inputCodeEditorView.ts | 13 ++++--- .../browser/view/editors/resultCodeEditorView.ts | 8 ++--- .../mergeEditor/browser/view/mergeEditor.ts | 2 +- .../contrib/mergeEditor/browser/view/viewModel.ts | 8 ++--- .../contrib/mergeEditor/test/browser/model.test.ts | 2 +- 15 files changed, 53 insertions(+), 106 deletions(-) delete mode 100644 src/vs/workbench/contrib/audioCues/browser/observable.ts (limited to 'src/vs') diff --git a/src/vs/base/common/observableImpl/base.ts b/src/vs/base/common/observableImpl/base.ts index fd91e6f8d8d..9d83083e49b 100644 --- a/src/vs/base/common/observableImpl/base.ts +++ b/src/vs/base/common/observableImpl/base.ts @@ -196,7 +196,7 @@ export class TransactionImpl implements ITransaction { export interface ISettableObservable extends IObservable, ISettable { } -export function observableValue(name: string, initialValue: T): ISettableObservable { +export function observableValue(name: string, initialValue: T): ISettableObservable { return new ObservableValue(name, initialValue); } diff --git a/src/vs/workbench/contrib/audioCues/browser/audioCueDebuggerContribution.ts b/src/vs/workbench/contrib/audioCues/browser/audioCueDebuggerContribution.ts index fc3727f804d..3b400d3fafc 100644 --- a/src/vs/workbench/contrib/audioCues/browser/audioCueDebuggerContribution.ts +++ b/src/vs/workbench/contrib/audioCues/browser/audioCueDebuggerContribution.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { autorunWithStore } from 'vs/base/common/observable'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { AudioCue, IAudioCueService } from 'vs/workbench/contrib/audioCues/browser/audioCueService'; -import { autorunWithStore } from 'vs/workbench/contrib/audioCues/browser/observable'; import { IDebugService, IDebugSession } from 'vs/workbench/contrib/debug/common/debug'; export class AudioCueLineDebuggerContribution diff --git a/src/vs/workbench/contrib/audioCues/browser/audioCueLineFeatureContribution.ts b/src/vs/workbench/contrib/audioCues/browser/audioCueLineFeatureContribution.ts index edbdd468675..490fab6c4c6 100644 --- a/src/vs/workbench/contrib/audioCues/browser/audioCueLineFeatureContribution.ts +++ b/src/vs/workbench/contrib/audioCues/browser/audioCueLineFeatureContribution.ts @@ -12,21 +12,11 @@ import { ICodeEditor, isCodeEditor, isDiffEditor } from 'vs/editor/browser/edito import { IMarkerService, MarkerSeverity } from 'vs/platform/markers/common/markers'; import { FoldingController } from 'vs/editor/contrib/folding/browser/folding'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { - autorun, - autorunDelta, - constObservable, - derivedObservable, - observableFromEvent, - observableFromPromise, - IObservable, - wasEventTriggeredRecently, - debouncedObservable, -} from 'vs/workbench/contrib/audioCues/browser/observable'; import { ITextModel } from 'vs/editor/common/model'; import { GhostTextController } from 'vs/editor/contrib/inlineCompletions/browser/ghostTextController'; import { AudioCue, IAudioCueService } from 'vs/workbench/contrib/audioCues/browser/audioCueService'; import { CursorChangeReason } from 'vs/editor/common/cursorEvents'; +import { autorun, autorunDelta, constObservable, debouncedObservable, derived, IObservable, observableFromEvent, observableFromPromise, wasEventTriggeredRecently } from 'vs/base/common/observable'; export class AudioCueLineFeatureContribution extends Disposable @@ -48,7 +38,7 @@ export class AudioCueLineFeatureContribution ) { super(); - const someAudioCueFeatureIsEnabled = derivedObservable( + const someAudioCueFeatureIsEnabled = derived( 'someAudioCueFeatureIsEnabled', (reader) => this.features.some((feature) => @@ -73,7 +63,7 @@ export class AudioCueLineFeatureContribution ); this._register( - autorun((reader) => { + autorun('updateAudioCuesEnabled', (reader) => { this.store.clear(); if (!someAudioCueFeatureIsEnabled.read(reader)) { @@ -84,7 +74,7 @@ export class AudioCueLineFeatureContribution if (activeEditor) { this.registerAudioCuesForEditor(activeEditor.editor, activeEditor.model, this.store); } - }, 'updateAudioCuesEnabled') + }) ); } @@ -118,7 +108,7 @@ export class AudioCueLineFeatureContribution const featureStates = this.features.map((feature) => { const lineFeatureState = feature.getObservableState(editor, editorModel); - const isFeaturePresent = derivedObservable( + const isFeaturePresent = derived( `isPresentInLine:${feature.audioCue.name}`, (reader) => { if (!this.audioCueService.isEnabled(feature.audioCue).read(reader)) { @@ -130,7 +120,7 @@ export class AudioCueLineFeatureContribution : lineFeatureState.read(reader).isPresent(lineNumber); } ); - return derivedObservable( + return derived( `typingDebouncedFeatureState:\n${feature.audioCue.name}`, (reader) => feature.debounceWhileTyping && isTyping.read(reader) @@ -139,7 +129,7 @@ export class AudioCueLineFeatureContribution ); }); - const state = derivedObservable( + const state = derived( 'states', (reader) => ({ lineNumber: debouncedLineNumber.read(reader), @@ -282,7 +272,7 @@ class InlineCompletionLineFeature implements LineFeature { : undefined )); - return derivedObservable('ghostText', reader => { + return derived('ghostText', reader => { const ghostText = activeGhostText.read(reader)?.read(reader); return { isPresent(lineNumber) { diff --git a/src/vs/workbench/contrib/audioCues/browser/audioCueService.ts b/src/vs/workbench/contrib/audioCues/browser/audioCueService.ts index f313933a8ec..4e491840f5a 100644 --- a/src/vs/workbench/contrib/audioCues/browser/audioCueService.ts +++ b/src/vs/workbench/contrib/audioCues/browser/audioCueService.ts @@ -9,9 +9,9 @@ import { FileAccess } from 'vs/base/common/network'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { observableFromEvent, IObservable, derivedObservable } from 'vs/workbench/contrib/audioCues/browser/observable'; import { Event } from 'vs/base/common/event'; import { localize } from 'vs/nls'; +import { IObservable, observableFromEvent, derived } from 'vs/base/common/observable'; export const IAudioCueService = createDecorator('audioCue'); @@ -95,7 +95,7 @@ export class AudioCueService extends Disposable implements IAudioCueService { ), () => this.configurationService.getValue<'on' | 'off' | 'auto'>(cue.settingsKey) ); - return derivedObservable('audio cue enabled', reader => { + return derived('audio cue enabled', reader => { const setting = settingObservable.read(reader); if ( setting === 'on' || diff --git a/src/vs/workbench/contrib/audioCues/browser/observable.ts b/src/vs/workbench/contrib/audioCues/browser/observable.ts deleted file mode 100644 index 37d2f8a97c8..00000000000 --- a/src/vs/workbench/contrib/audioCues/browser/observable.ts +++ /dev/null @@ -1,40 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IDisposable } from 'vs/base/common/lifecycle'; -import * as observable from 'vs/base/common/observable'; -export { - observableFromEvent, - autorunWithStore, - IObservable, - transaction, - ITransaction, - autorunDelta, - constObservable, - observableFromPromise, - wasEventTriggeredRecently, - debouncedObservable, - autorunHandleChanges, - waitForState, - keepAlive, - IReader, - derivedObservableWithCache, - derivedObservableWithWritableCache, -} from 'vs/base/common/observable'; -import * as observableValue from 'vs/base/common/observableImpl/base'; - -export function autorun(fn: (reader: observable.IReader) => void, name: string): IDisposable { - return observable.autorun(name, fn); -} - -export class ObservableValue extends observableValue.ObservableValue { - constructor(initialValue: T, name: string) { - super(name, initialValue); - } -} - -export function derivedObservable(name: string, computeFn: (reader: observable.IReader) => T): observable.IObservable { - return observable.derived(name, computeFn); -} diff --git a/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts b/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts index 721cd75e3d1..6bf21e30d44 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts @@ -5,11 +5,11 @@ import { CompareResult, equals } from 'vs/base/common/arrays'; import { BugIndicatingError } from 'vs/base/common/errors'; +import { ISettableObservable, derived, waitForState, observableValue, keepAlive, autorunHandleChanges, transaction, IReader, ITransaction, IObservable } from 'vs/base/common/observable'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { ITextModel, ITextSnapshot } from 'vs/editor/common/model'; import { IModelService } from 'vs/editor/common/services/model'; import { EditorModel } from 'vs/workbench/common/editor/editorModel'; -import { autorunHandleChanges, derivedObservable, IObservable, IReader, ITransaction, keepAlive, ObservableValue, transaction, waitForState } from 'vs/workbench/contrib/audioCues/browser/observable'; import { IDiffComputer } from 'vs/workbench/contrib/mergeEditor/browser/model/diffComputer'; import { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange'; import { DetailedLineRangeMapping, DocumentMapping, LineRangeMapping } from 'vs/workbench/contrib/mergeEditor/browser/model/mapping'; @@ -28,7 +28,7 @@ export class MergeEditorModel extends EditorModel { private readonly input2TextModelDiffs = this._register(new TextModelDiffs(this.base, this.input2, this.diffComputer)); private readonly resultTextModelDiffs = this._register(new TextModelDiffs(this.base, this.result, this.diffComputer)); - public readonly state = derivedObservable('state', reader => { + public readonly state = derived('state', reader => { const states = [ this.input1TextModelDiffs, this.input2TextModelDiffs, @@ -44,11 +44,11 @@ export class MergeEditorModel extends EditorModel { return MergeEditorModelState.upToDate; }); - public readonly isUpToDate = derivedObservable('isUpToDate', reader => this.state.read(reader) === MergeEditorModelState.upToDate); + public readonly isUpToDate = derived('isUpToDate', reader => this.state.read(reader) === MergeEditorModelState.upToDate); public readonly onInitialized = waitForState(this.state, state => state === MergeEditorModelState.upToDate); - public readonly modifiedBaseRanges = derivedObservable('modifiedBaseRanges', (reader) => { + public readonly modifiedBaseRanges = derived('modifiedBaseRanges', (reader) => { const input1Diffs = this.input1TextModelDiffs.diffs.read(reader); const input2Diffs = this.input2TextModelDiffs.diffs.read(reader); @@ -60,22 +60,22 @@ export class MergeEditorModel extends EditorModel { public readonly resultDiffs = this.resultTextModelDiffs.diffs; private readonly modifiedBaseRangeStateStores = - derivedObservable('modifiedBaseRangeStateStores', reader => { + derived('modifiedBaseRangeStateStores', reader => { const map = new Map( - this.modifiedBaseRanges.read(reader).map(s => ([s, new ObservableValue(ModifiedBaseRangeState.default, 'State')])) + this.modifiedBaseRanges.read(reader).map(s => ([s, observableValue('State', ModifiedBaseRangeState.default)])) ); return map; }); private readonly modifiedBaseRangeHandlingStateStores = - derivedObservable('modifiedBaseRangeHandlingStateStores', reader => { + derived('modifiedBaseRangeHandlingStateStores', reader => { const map = new Map( - this.modifiedBaseRanges.read(reader).map(s => ([s, new ObservableValue(false, 'State')])) + this.modifiedBaseRanges.read(reader).map(s => ([s, observableValue('State', false)])) ); return map; }); - public readonly unhandledConflictsCount = derivedObservable('unhandledConflictsCount', reader => { + public readonly unhandledConflictsCount = derived('unhandledConflictsCount', reader => { const map = this.modifiedBaseRangeHandlingStateStores.read(reader); let handledCount = 0; for (const [_key, value] of map) { @@ -86,7 +86,7 @@ export class MergeEditorModel extends EditorModel { public readonly hasUnhandledConflicts = this.unhandledConflictsCount.map(value => /** @description hasUnhandledConflicts */ value > 0); - public readonly input1ResultMapping = derivedObservable('input1ResultMapping', reader => { + public readonly input1ResultMapping = derived('input1ResultMapping', reader => { const resultDiffs = this.resultDiffs.read(reader); const modifiedBaseRanges = DocumentMapping.betweenOutputs(this.input1LinesDiffs.read(reader), resultDiffs, this.input1.getLineCount()); @@ -103,7 +103,7 @@ export class MergeEditorModel extends EditorModel { ); }); - public readonly input2ResultMapping = derivedObservable('input2ResultMapping', reader => { + public readonly input2ResultMapping = derived('input2ResultMapping', reader => { const resultDiffs = this.resultDiffs.read(reader); const modifiedBaseRanges = DocumentMapping.betweenOutputs(this.input2LinesDiffs.read(reader), resultDiffs, this.input2.getLineCount()); @@ -192,7 +192,7 @@ export class MergeEditorModel extends EditorModel { return this.resultTextModelDiffs.getResultRange(baseRange, reader); } - private recomputeState(resultDiffs: DetailedLineRangeMapping[], stores: Map>, tx: ITransaction): void { + private recomputeState(resultDiffs: DetailedLineRangeMapping[], stores: Map>, tx: ITransaction): void { const baseRangeWithStoreAndTouchingDiffs = leftJoin( stores, resultDiffs, diff --git a/src/vs/workbench/contrib/mergeEditor/browser/model/textModelDiffs.ts b/src/vs/workbench/contrib/mergeEditor/browser/model/textModelDiffs.ts index ed894cc7e25..af21adbebb5 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/model/textModelDiffs.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/model/textModelDiffs.ts @@ -7,17 +7,17 @@ import { compareBy, numberComparator } from 'vs/base/common/arrays'; import { BugIndicatingError } from 'vs/base/common/errors'; import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { ITextModel } from 'vs/editor/common/model'; -import { IObservable, IReader, ITransaction, ObservableValue, transaction } from 'vs/workbench/contrib/audioCues/browser/observable'; import { DetailedLineRangeMapping } from 'vs/workbench/contrib/mergeEditor/browser/model/mapping'; import { LineRangeEdit } from 'vs/workbench/contrib/mergeEditor/browser/model/editing'; import { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange'; import { ReentrancyBarrier } from 'vs/workbench/contrib/mergeEditor/browser/utils'; import { IDiffComputer } from './diffComputer'; +import { IObservable, IReader, ITransaction, observableValue, transaction } from 'vs/base/common/observable'; export class TextModelDiffs extends Disposable { private updateCount = 0; - private readonly _state = new ObservableValue(TextModelDiffState.initializing, 'LiveDiffState'); - private readonly _diffs = new ObservableValue([], 'LiveDiffs'); + private readonly _state = observableValue('LiveDiffState', TextModelDiffState.initializing); + private readonly _diffs = observableValue('LiveDiffs', []); private readonly barrier = new ReentrancyBarrier(); private isDisposed = false; diff --git a/src/vs/workbench/contrib/mergeEditor/browser/utils.ts b/src/vs/workbench/contrib/mergeEditor/browser/utils.ts index 3188a3b2e7a..7e92f970387 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/utils.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/utils.ts @@ -5,11 +5,10 @@ import { CompareResult, ArrayQueue } from 'vs/base/common/arrays'; import { BugIndicatingError } from 'vs/base/common/errors'; -import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; +import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IObservable, autorun } from 'vs/base/common/observable'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; import { IModelDeltaDecoration } from 'vs/editor/common/model'; -import { IObservable, autorun } from 'vs/workbench/contrib/audioCues/browser/observable'; -import { IDisposable } from 'xterm'; export class ReentrancyBarrier { private isActive = false; @@ -74,12 +73,12 @@ function toSize(value: number | string): string { export function applyObservableDecorations(editor: CodeEditorWidget, decorations: IObservable): IDisposable { const d = new DisposableStore(); let decorationIds: string[] = []; - d.add(autorun(reader => { + d.add(autorun(`Apply decorations from ${decorations.debugName}`, reader => { const d = decorations.read(reader); editor.changeDecorations(a => { decorationIds = a.deltaDecorations(decorationIds, d); }); - }, `Apply decorations from ${decorations.debugName}`)); + })); d.add({ dispose: () => { editor.changeDecorations(a => { diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts index 0a54f686ca4..7289cc61637 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts @@ -5,9 +5,8 @@ import { h } from 'vs/base/browser/dom'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; -import { observableSignalFromEvent } from 'vs/base/common/observable'; +import { autorun, IReader, observableFromEvent, observableSignalFromEvent } from 'vs/base/common/observable'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; -import { autorun, IReader, observableFromEvent } from 'vs/workbench/contrib/audioCues/browser/observable'; import { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange'; export class EditorGutter extends Disposable { @@ -36,11 +35,11 @@ export class EditorGutter extends D .root ); - this._register(autorun((reader) => { + this._register(autorun('update scroll decoration', (reader) => { scrollDecoration.className = this.isScrollTopZero.read(reader) ? '' : 'scroll-decoration'; - }, 'update scroll decoration')); + })); - this._register(autorun((reader) => this.render(reader), 'EditorGutter.Render')); + this._register(autorun('EditorGutter.Render', (reader) => this.render(reader))); } private readonly views = new Map(); diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts index f843553c33b..f6a409656f8 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts @@ -8,18 +8,18 @@ import { IView, IViewSize } from 'vs/base/browser/ui/grid/grid'; import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; +import { IObservable, observableFromEvent, observableValue, transaction } from 'vs/base/common/observable'; import { IEditorContributionDescription } from 'vs/editor/browser/editorExtensions'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { ITextModel } from 'vs/editor/common/model'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { DEFAULT_EDITOR_MAX_DIMENSIONS, DEFAULT_EDITOR_MIN_DIMENSIONS } from 'vs/workbench/browser/parts/editor/editor'; -import { IObservable, observableFromEvent, ObservableValue, transaction } from 'vs/workbench/contrib/audioCues/browser/observable'; import { setStyle } from 'vs/workbench/contrib/mergeEditor/browser/utils'; import { MergeEditorViewModel } from 'vs/workbench/contrib/mergeEditor/browser/view/viewModel'; export abstract class CodeEditorView extends Disposable { - private readonly _viewModel = new ObservableValue(undefined, 'viewModel'); + private readonly _viewModel = observableValue('viewModel', undefined); readonly viewModel: IObservable = this._viewModel; readonly model = this._viewModel.map(m => /** @description model */ m?.model); diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts index 476e5143570..abadef681ba 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts @@ -8,7 +8,7 @@ import { Toggle } from 'vs/base/browser/ui/toggle/toggle'; import { Action, IAction, Separator } from 'vs/base/common/actions'; import { Codicon } from 'vs/base/common/codicons'; import { Disposable } from 'vs/base/common/lifecycle'; -import { derived, ISettableObservable } from 'vs/base/common/observable'; +import { autorun, derived, IObservable, ISettableObservable, ITransaction, transaction, observableValue } from 'vs/base/common/observable'; import { noBreakWhitespace } from 'vs/base/common/strings'; import { isDefined } from 'vs/base/common/types'; import { EditorExtensionsRegistry, IEditorContributionDescription } from 'vs/editor/browser/editorExtensions'; @@ -19,7 +19,6 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { attachToggleStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { autorun, derivedObservable, IObservable, ITransaction, ObservableValue, transaction } from 'vs/workbench/contrib/audioCues/browser/observable'; import { InputState, ModifiedBaseRangeState } from 'vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange'; import { applyObservableDecorations, setFields } from 'vs/workbench/contrib/mergeEditor/browser/utils'; import { handledConflictMinimapOverViewRulerColor, unhandledConflictMinimapOverViewRulerColor } from 'vs/workbench/contrib/mergeEditor/browser/view/colors'; @@ -27,7 +26,7 @@ import { EditorGutter, IGutterItemInfo, IGutterItemView } from '../editorGutter' import { CodeEditorView } from './codeEditorView'; export class InputCodeEditorView extends CodeEditorView { - private readonly decorations = derivedObservable(`input${this.inputNumber}.decorations`, reader => { + private readonly decorations = derived(`input${this.inputNumber}.decorations`, reader => { const viewModel = this.viewModel.read(reader); if (!viewModel) { return []; @@ -112,7 +111,7 @@ export class InputCodeEditorView extends CodeEditorView { id: idx.toString(), range: baseRange.getInputRange(this.inputNumber), enabled: model.isUpToDate, - toggleState: derivedObservable('checkbox is checked', (reader) => { + toggleState: derived('checkbox is checked', (reader) => { const input = model .getState(baseRange) .read(reader) @@ -274,7 +273,7 @@ export class MergeConflictGutterItemView extends Disposable implements IGutterIt ) { super(); - this.item = new ObservableValue(item, 'item'); + this.item = observableValue('item', item); target.classList.add('merge-accept-gutter-marker'); @@ -309,7 +308,7 @@ export class MergeConflictGutterItemView extends Disposable implements IGutterIt checkBox.domNode.classList.add('accept-conflict-group'); this._register( - autorun((reader) => { + autorun('Update Checkbox', (reader) => { const item = this.item.read(reader)!; const value = item.toggleState.read(reader); const iconMap: Record = { @@ -326,7 +325,7 @@ export class MergeConflictGutterItemView extends Disposable implements IGutterIt } else { checkBox.enable(); } - }, 'Update Checkbox') + }) ); this._register(checkBox.onChange(() => { diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts index 0efc1d88247..e1557eb0c9a 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts @@ -4,17 +4,17 @@ *--------------------------------------------------------------------------------------------*/ import { CompareResult } from 'vs/base/common/arrays'; +import { autorun, derived } from 'vs/base/common/observable'; import { IModelDeltaDecoration, MinimapPosition, OverviewRulerLane } from 'vs/editor/common/model'; import { localize } from 'vs/nls'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { autorun, derivedObservable } from 'vs/workbench/contrib/audioCues/browser/observable'; import { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange'; import { applyObservableDecorations, join } from 'vs/workbench/contrib/mergeEditor/browser/utils'; import { handledConflictMinimapOverViewRulerColor, unhandledConflictMinimapOverViewRulerColor } from 'vs/workbench/contrib/mergeEditor/browser/view/colors'; import { CodeEditorView } from './codeEditorView'; export class ResultCodeEditorView extends CodeEditorView { - private readonly decorations = derivedObservable('result.decorations', reader => { + private readonly decorations = derived('result.decorations', reader => { const viewModel = this.viewModel.read(reader); if (!viewModel) { return []; @@ -107,7 +107,7 @@ export class ResultCodeEditorView extends CodeEditorView { this._register(applyObservableDecorations(this.editor, this.decorations)); - this._register(autorun(reader => { + this._register(autorun('update remainingConflicts label', reader => { const model = this.model.read(reader); if (!model) { return; @@ -126,6 +126,6 @@ export class ResultCodeEditorView extends CodeEditorView { count ); - }, 'update remainingConflicts label')); + })); } } diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts index 74629320cd2..544e07332cb 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts @@ -12,6 +12,7 @@ import { Color } from 'vs/base/common/color'; import { BugIndicatingError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import { DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; +import { autorunWithStore, IObservable } from 'vs/base/common/observable'; import { isEqual } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import 'vs/css!./media/mergeEditor'; @@ -37,7 +38,6 @@ import { AbstractTextEditor } from 'vs/workbench/browser/parts/editor/textEditor import { EditorInputWithOptions, EditorResourceAccessor, IEditorOpenContext } from 'vs/workbench/common/editor'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { applyTextEditorOptions } from 'vs/workbench/common/editor/editorOptions'; -import { autorunWithStore, IObservable } from 'vs/workbench/contrib/audioCues/browser/observable'; import { MergeEditorInput } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput'; import { DocumentMapping, getOppositeDirection, MappingDirection } from 'vs/workbench/contrib/mergeEditor/browser/model/mapping'; import { MergeEditorModel } from 'vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel'; diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts index 46c954fb2c3..de910cceaee 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import { findLast } from 'vs/base/common/arrays'; +import { derived, derivedObservableWithWritableCache, IReader, ITransaction, observableValue, transaction } from 'vs/base/common/observable'; import { ScrollType } from 'vs/editor/common/editorCommon'; -import { derivedObservable, derivedObservableWithWritableCache, IReader, ITransaction, ObservableValue, transaction } from 'vs/workbench/contrib/audioCues/browser/observable'; import { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange'; import { MergeEditorModel } from 'vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel'; import { ModifiedBaseRange, ModifiedBaseRangeState } from 'vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange'; @@ -25,9 +25,9 @@ export class MergeEditorViewModel { return editors.find((e) => e.isFocused.read(reader)) || lastValue; }); - private readonly manuallySetActiveModifiedBaseRange = new ObservableValue< + private readonly manuallySetActiveModifiedBaseRange = observableValue< ModifiedBaseRange | undefined - >(undefined, 'manuallySetActiveModifiedBaseRange'); + >('manuallySetActiveModifiedBaseRange', undefined); private getRange(editor: CodeEditorView, modifiedBaseRange: ModifiedBaseRange, reader: IReader | undefined): LineRange { if (editor === this.resultCodeEditorView) { @@ -38,7 +38,7 @@ export class MergeEditorViewModel { } } - public readonly activeModifiedBaseRange = derivedObservable( + public readonly activeModifiedBaseRange = derived( 'activeModifiedBaseRange', (reader) => { const focusedEditor = this.lastFocusedEditor.read(reader); diff --git a/src/vs/workbench/contrib/mergeEditor/test/browser/model.test.ts b/src/vs/workbench/contrib/mergeEditor/test/browser/model.test.ts index 9963829694f..ea1a9794545 100644 --- a/src/vs/workbench/contrib/mergeEditor/test/browser/model.test.ts +++ b/src/vs/workbench/contrib/mergeEditor/test/browser/model.test.ts @@ -5,13 +5,13 @@ import assert = require('assert'); import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { transaction } from 'vs/base/common/observable'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { Range } from 'vs/editor/common/core/range'; import { ITextModel } from 'vs/editor/common/model'; import { EditorSimpleWorker } from 'vs/editor/common/services/editorSimpleWorker'; import { createModelServices, createTextModel } from 'vs/editor/test/common/testTextModel'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { transaction } from 'vs/workbench/contrib/audioCues/browser/observable'; import { EditorWorkerServiceDiffComputer } from 'vs/workbench/contrib/mergeEditor/browser/model/diffComputer'; import { MergeEditorModel } from 'vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel'; -- cgit v1.2.3 From 32e10d588247a94af33afe5ef91f5e0e27a91c05 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Mon, 4 Jul 2022 16:36:21 +0200 Subject: SCM - Fix inconsistent outline for the commit action button (#154091) Fix inconsistent outline for the commit action button --- src/vs/base/browser/ui/button/button.css | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/vs') diff --git a/src/vs/base/browser/ui/button/button.css b/src/vs/base/browser/ui/button/button.css index ed4131eefd3..5327fb0e1e3 100644 --- a/src/vs/base/browser/ui/button/button.css +++ b/src/vs/base/browser/ui/button/button.css @@ -38,6 +38,10 @@ cursor: pointer; } +.monaco-button-dropdown > .monaco-button:focus { + outline-offset: -1px !important; +} + .monaco-button-dropdown > .monaco-dropdown-button { margin-left: 1px; } -- cgit v1.2.3 From 3fc0a6b2d1f9e1eb9a94e1820c667d67cda11c3e Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Mon, 4 Jul 2022 16:36:43 +0200 Subject: SCM - Fix commit action button dropdown title (#154088) Fix commit action button dropdown title --- src/vs/base/browser/ui/button/button.ts | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/vs') diff --git a/src/vs/base/browser/ui/button/button.ts b/src/vs/base/browser/ui/button/button.ts index a2349f9dc96..3187254843b 100644 --- a/src/vs/base/browser/ui/button/button.ts +++ b/src/vs/base/browser/ui/button/button.ts @@ -15,6 +15,7 @@ import { Emitter, Event as BaseEvent } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { mixin } from 'vs/base/common/objects'; +import { localize } from 'vs/nls'; import 'vs/css!./button'; export interface IButtonOptions extends IButtonStyles { @@ -263,6 +264,7 @@ export class ButtonWithDropdown extends Disposable implements IButton { this.action = this._register(new Action('primaryAction', this.button.label, undefined, true, async () => this._onDidClick.fire(undefined))); this.dropdownButton = this._register(new Button(this.element, { ...options, title: false, supportIcons: true })); + this.dropdownButton.element.title = localize("button dropdown more actions", 'More Actions...'); this.dropdownButton.element.classList.add('monaco-dropdown-button'); this.dropdownButton.icon = Codicon.dropDownButton; this._register(this.dropdownButton.onDidClick(e => { -- cgit v1.2.3 From 498ae4deadf15da690175d7c3a2bc848ec36928b Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Mon, 4 Jul 2022 16:47:06 +0200 Subject: Improves observable tests. --- src/vs/base/test/common/observable.test.ts | 169 ++++++++++++++++++----------- 1 file changed, 104 insertions(+), 65 deletions(-) (limited to 'src/vs') diff --git a/src/vs/base/test/common/observable.test.ts b/src/vs/base/test/common/observable.test.ts index 8adba720180..a3460dca22b 100644 --- a/src/vs/base/test/common/observable.test.ts +++ b/src/vs/base/test/common/observable.test.ts @@ -5,8 +5,8 @@ import * as assert from 'assert'; import { Emitter } from 'vs/base/common/event'; -import { autorun, derived, IObserver, ITransaction, observableFromEvent, observableValue, transaction } from 'vs/base/common/observable'; -import { BaseObservable } from 'vs/base/common/observableImpl/base'; +import { ISettableObservable, autorun, derived, ITransaction, observableFromEvent, observableValue, transaction } from 'vs/base/common/observable'; +import { BaseObservable, IObservable, IObserver } from 'vs/base/common/observableImpl/base'; suite('observable integration', () => { test('basic observable + autorun', () => { @@ -209,29 +209,41 @@ suite('observable integration', () => { ]); }); - test('transaction from autorun', () => { + test('self-disposing autorun', () => { const log = new Log(); - const observable1 = observableValue('MyObservableValue1', 0); - const observable2 = observableValue('MyObservableValue2', 0); - - const computed = derived('computed', (reader) => { - const value1 = observable1.read(reader); - const value2 = observable2.read(reader); - const sum = value1 + value2; - log.log(`recompute: ${value1} + ${value2} = ${sum}`); - return sum; - }); - - autorun('autorun', (reader) => { - log.log(`value: ${computed.read(reader)}`); - transaction(tx => { - - }); + const observable1 = new LoggingObservableValue('MyObservableValue1', 0, log); + const observable2 = new LoggingObservableValue('MyObservableValue2', 0, log); + const observable3 = new LoggingObservableValue('MyObservableValue3', 0, log); + const d = autorun('autorun', (reader) => { + if (observable1.read(reader) >= 2) { + observable2.read(reader); + d.dispose(); + observable3.read(reader); + } }); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'MyObservableValue1.firstObserverAdded', + 'MyObservableValue1.get', + ]); + observable1.set(1, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'MyObservableValue1.set (value 1)', + 'MyObservableValue1.get', + ]); + observable1.set(2, undefined); + assert.deepStrictEqual(log.getAndClearEntries(), [ + 'MyObservableValue1.set (value 2)', + 'MyObservableValue1.get', + 'MyObservableValue2.firstObserverAdded', + 'MyObservableValue2.get', + 'MyObservableValue1.lastObserverRemoved', + 'MyObservableValue2.lastObserverRemoved', + 'MyObservableValue3.get', + ]); }); test('from event', () => { @@ -382,47 +394,8 @@ suite('observable details', () => { test('1', () => { const log = new Log(); - class TrackedObservableValue extends BaseObservable { - private value: T; - - constructor(initialValue: T) { - super(); - this.value = initialValue; - } - - readonly debugName = 'TrackedObservableValue'; - - public override addObserver(observer: IObserver): void { - log.log(`observable.addObserver ${observer.toString()}`); - super.addObserver(observer); - } - - public override removeObserver(observer: IObserver): void { - log.log(`observable.removeObserver ${observer.toString()}`); - super.removeObserver(observer); - } - - public get(): T { - log.log('observable.get'); - return this.value; - } - - public set(value: T, tx: ITransaction): void { - log.log(`observable.set (value ${value})`); - - if (this.value === value) { - return; - } - this.value = value; - for (const observer of this.observers) { - tx.updateObserver(observer, this); - observer.handleChange(this, undefined); - } - } - } - const shouldReadObservable = observableValue('shouldReadObservable', true); - const observable = new TrackedObservableValue(0); + const observable = new LoggingObservableValue('observable', 0, log); const computed = derived('test', reader => { if (shouldReadObservable.read(reader)) { return observable.read(reader) * 2; @@ -434,11 +407,7 @@ suite('observable details', () => { log.log(`autorun: ${value}`); }); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'observable.addObserver LazyDerived', - 'observable.get', - 'autorun: 0', - ]); + assert.deepStrictEqual(log.getAndClearEntries(), (["observable.firstObserverAdded", "observable.get", "autorun: 0"])); transaction(tx => { observable.set(1, tx); @@ -448,12 +417,82 @@ suite('observable details', () => { assert.deepStrictEqual(log.getAndClearEntries(), ([])); computed.get(); - assert.deepStrictEqual(log.getAndClearEntries(), (["observable.removeObserver LazyDerived"])); + assert.deepStrictEqual(log.getAndClearEntries(), (["observable.lastObserverRemoved"])); }); assert.deepStrictEqual(log.getAndClearEntries(), (["autorun: 1"])); }); }); +export class LoggingObserver implements IObserver { + private count = 0; + + constructor(public readonly debugName: string, private readonly log: Log) { + } + + beginUpdate(observable: IObservable): void { + this.count++; + this.log.log(`${this.debugName}.beginUpdate (count ${this.count})`); + } + handleChange(observable: IObservable, change: TChange): void { + this.log.log(`${this.debugName}.handleChange (count ${this.count})`); + } + endUpdate(observable: IObservable): void { + this.log.log(`${this.debugName}.endUpdate (count ${this.count})`); + this.count--; + } +} + +export class LoggingObservableValue + extends BaseObservable + implements ISettableObservable +{ + private value: T; + + constructor(public readonly debugName: string, initialValue: T, private readonly log: Log) { + super(); + this.value = initialValue; + } + + protected override onFirstObserverAdded(): void { + this.log.log(`${this.debugName}.firstObserverAdded`); + } + + protected override onLastObserverRemoved(): void { + this.log.log(`${this.debugName}.lastObserverRemoved`); + } + + public get(): T { + this.log.log(`${this.debugName}.get`); + return this.value; + } + + public set(value: T, tx: ITransaction | undefined, change: TChange): void { + if (this.value === value) { + return; + } + + if (!tx) { + transaction((tx) => { + this.set(value, tx, change); + }, () => `Setting ${this.debugName}`); + return; + } + + this.log.log(`${this.debugName}.set (value ${value})`); + + this.value = value; + + for (const observer of this.observers) { + tx.updateObserver(observer, this); + observer.handleChange(this, change); + } + } + + override toString(): string { + return `${this.debugName}: ${this.value}`; + } +} + class Log { private readonly entries: string[] = []; public log(message: string): void { -- cgit v1.2.3 From 3032a1653a9e0707ffee91e631e920371499df03 Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Mon, 4 Jul 2022 20:50:09 -0400 Subject: Use DebounceEmitter --- .../editor/contrib/markdownRenderer/browser/markdownRenderer.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/vs') diff --git a/src/vs/editor/contrib/markdownRenderer/browser/markdownRenderer.ts b/src/vs/editor/contrib/markdownRenderer/browser/markdownRenderer.ts index 3956f8e4536..f72e2293aa7 100644 --- a/src/vs/editor/contrib/markdownRenderer/browser/markdownRenderer.ts +++ b/src/vs/editor/contrib/markdownRenderer/browser/markdownRenderer.ts @@ -10,7 +10,7 @@ import { ILanguageService } from 'vs/editor/common/languages/language'; import { onUnexpectedError } from 'vs/base/common/errors'; import { tokenizeToString } from 'vs/editor/common/languages/textToHtmlTokenizer'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { Emitter, Event } from 'vs/base/common/event'; +import { DebounceEmitter } from 'vs/base/common/event'; import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { applyFontInfo } from 'vs/editor/browser/config/domFontInfo'; @@ -38,8 +38,11 @@ export class MarkdownRenderer { } }); - private readonly _onDidRenderAsync = new Emitter(); - readonly onDidRenderAsync = Event.debounce(this._onDidRenderAsync.event, (_, e) => e, 50); + private readonly _onDidRenderAsync = new DebounceEmitter({ + delay: 50, + merge: arr => { } + }); + readonly onDidRenderAsync = this._onDidRenderAsync.event; constructor( private readonly _options: IMarkdownRendererOptions, -- cgit v1.2.3 From d529b0d77ce60cbc362c6a9e1e22ea076ae2329f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Jul 2022 08:57:02 +0200 Subject: macOS: adjust traffic lights when command center is visible #154131 (#154132) --- src/vs/platform/window/electron-main/window.ts | 2 - src/vs/platform/windows/electron-main/window.ts | 83 +++++++++++++--------- .../test/electron-main/windowsFinder.test.ts | 1 - src/vs/workbench/electron-sandbox/window.ts | 15 ++-- 4 files changed, 53 insertions(+), 48 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/window/electron-main/window.ts b/src/vs/platform/window/electron-main/window.ts index fdd9954a76a..e6f0513a76d 100644 --- a/src/vs/platform/window/electron-main/window.ts +++ b/src/vs/platform/window/electron-main/window.ts @@ -43,8 +43,6 @@ export interface ICodeWindow extends IDisposable { ready(): Promise; setReady(): void; - readonly hasHiddenTitleBarStyle: boolean; - addTabbedWindow(window: ICodeWindow): void; load(config: INativeWindowConfiguration, options?: { isReload?: boolean }): void; diff --git a/src/vs/platform/windows/electron-main/window.ts b/src/vs/platform/windows/electron-main/window.ts index bcc3711f7e8..f2a671d7b97 100644 --- a/src/vs/platform/windows/electron-main/window.ts +++ b/src/vs/platform/windows/electron-main/window.ts @@ -18,7 +18,7 @@ import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { ISerializableCommandAction } from 'vs/platform/action/common/action'; import { IBackupMainService } from 'vs/platform/backup/electron-main/backup'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IConfigurationChangeEvent, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService'; @@ -122,9 +122,6 @@ export class CodeWindow extends Disposable implements ICodeWindow { private _config: INativeWindowConfiguration | undefined; get config(): INativeWindowConfiguration | undefined { return this._config; } - private hiddenTitleBarStyle: boolean | undefined; - get hasHiddenTitleBarStyle(): boolean { return !!this.hiddenTitleBarStyle; } - get isExtensionDevelopmentHost(): boolean { return !!(this._config?.extensionDevelopmentPath); } get isExtensionTestHost(): boolean { return !!(this._config?.extensionTestsPath); } @@ -140,6 +137,8 @@ export class CodeWindow extends Disposable implements ICodeWindow { private representedFilename: string | undefined; private documentEdited: boolean | undefined; + private customTrafficLightPosition: boolean | undefined; + private readonly whenReadyCallbacks: { (window: ICodeWindow): void }[] = []; private readonly touchBarGroups: TouchBarSegmentedControl[] = []; @@ -251,19 +250,21 @@ export class CodeWindow extends Disposable implements ICodeWindow { const useCustomTitleStyle = getTitleBarStyle(this.configurationService) === 'custom'; if (useCustomTitleStyle) { options.titleBarStyle = 'hidden'; - this.hiddenTitleBarStyle = true; if (!isMacintosh) { options.frame = false; } if (useWindowControlsOverlay(this.configurationService, this.environmentMainService)) { - // This logic will not perfectly guess the right colors to use on initialization, - // but prefer to keep things simple as it is temporary and not noticeable + + // This logic will not perfectly guess the right colors + // to use on initialization, but prefer to keep things + // simple as it is temporary and not noticeable + const titleBarColor = this.themeMainService.getWindowSplash()?.colorInfo.titleBarBackground ?? this.themeMainService.getBackgroundColor(); const symbolColor = Color.fromHex(titleBarColor).isDarker() ? '#FFFFFF' : '#000000'; options.titleBarOverlay = { - height: 29, // The smallest size of the title bar on windows accounting for the border on windows 11 + height: 29, // the smallest size of the title bar on windows accounting for the border on windows 11 color: titleBarColor, symbolColor }; @@ -277,29 +278,8 @@ export class CodeWindow extends Disposable implements ICodeWindow { this._id = this._win.id; - // re-position traffic light if command center is visible - if (useCustomTitleStyle && isMacintosh) { - const ccConfigKey = 'window.commandCenter'; - const trafficLightUpdater = () => { - // temporarily disabled because of https://github.com/microsoft/vscode/pull/150272#issuecomment-1152218493 - // const on = this.configurationService.getValue(ccConfigKey); - // if (on) { - // this._win.setTrafficLightPosition({ x: 7, y: 9 }); - // } else { - // this._win.setTrafficLightPosition({ x: 7, y: 6 }); - // } - }; - trafficLightUpdater(); - this.configurationService.onDidChangeConfiguration(e => { - if (e.affectsConfiguration(ccConfigKey)) { - trafficLightUpdater(); - } - }, undefined, this._store); - } - - // Open devtools if instructed from command line args - if (this.environmentMainService.args['open-devtools'] === true) { - this._win.webContents.openDevTools(); + if (isMacintosh && useCustomTitleStyle) { + this.updateTrafficLightPosition(); // adjust traffic light position depending on command center } if (isMacintosh && useCustomTitleStyle) { @@ -348,6 +328,11 @@ export class CodeWindow extends Disposable implements ICodeWindow { } //#endregion + // Open devtools if instructed from command line args + if (this.environmentMainService.args['open-devtools'] === true) { + this._win.webContents.openDevTools(); + } + // respect configured menu bar visibility this.onConfigurationUpdated(); @@ -359,7 +344,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { } setRepresentedFilename(filename: string): void { - if (isMacintosh) { + if (isMacintosh && !this.customTrafficLightPosition) { // TODO@electron https://github.com/electron/electron/issues/34822 this._win.setRepresentedFilename(filename); } else { this.representedFilename = filename; @@ -367,7 +352,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { } getRepresentedFilename(): string | undefined { - if (isMacintosh) { + if (isMacintosh && !this.customTrafficLightPosition) { // TODO@electron https://github.com/electron/electron/issues/34822 return this._win.getRepresentedFilename(); } @@ -525,7 +510,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { }); // Handle configuration changes - this._register(this.configurationService.onDidChangeConfiguration(() => this.onConfigurationUpdated())); + this._register(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(e))); // Handle Workspace events this._register(this.workspacesManagementMainService.onDidDeleteUntitledWorkspace(e => this.onDidDeleteUntitledWorkspace(e))); @@ -735,7 +720,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { } } - private onConfigurationUpdated(): void { + private onConfigurationUpdated(e?: IConfigurationChangeEvent): void { // Menubar const newMenuBarVisibility = this.getMenuBarVisibility(); @@ -744,6 +729,9 @@ export class CodeWindow extends Disposable implements ICodeWindow { this.setMenuBarVisibility(newMenuBarVisibility); } + // Traffic Lights + this.updateTrafficLightPosition(e); + // Proxy let newHttpProxy = (this.configurationService.getValue('http.proxy') || '').trim() || (process.env['https_proxy'] || process.env['HTTPS_PROXY'] || process.env['http_proxy'] || process.env['HTTP_PROXY'] || '').trim() // Not standardized. @@ -1303,6 +1291,31 @@ export class CodeWindow extends Disposable implements ICodeWindow { } } + private updateTrafficLightPosition(e?: IConfigurationChangeEvent): void { + if (!isMacintosh) { + return; // only applies to macOS + } + + const commandCenterSettingKey = 'window.commandCenter'; + if (e && !e.affectsConfiguration(commandCenterSettingKey)) { + return; + } + + const useCustomTitleStyle = getTitleBarStyle(this.configurationService) === 'custom'; + if (!useCustomTitleStyle) { + return; // only applies with custom title bar + } + + const useCustomTrafficLightPosition = this.configurationService.getValue(commandCenterSettingKey); + if (useCustomTrafficLightPosition) { + this._win.setTrafficLightPosition({ x: 7, y: 9 }); + } else { + this._win.setTrafficLightPosition({ x: 7, y: 6 }); + } + + this.customTrafficLightPosition = useCustomTrafficLightPosition; + } + handleTitleDoubleClick(): void { // Respect system settings on mac with regards to title click on windows title diff --git a/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts b/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts index b17048b3ad2..827801bf891 100644 --- a/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts +++ b/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts @@ -49,7 +49,6 @@ suite('WindowsFinder', () => { lastFocusTime = options.lastFocusTime; isFullScreen = false; isReady = true; - hasHiddenTitleBarStyle = false; ready(): Promise { throw new Error('Method not implemented.'); } setReady(): void { throw new Error('Method not implemented.'); } diff --git a/src/vs/workbench/electron-sandbox/window.ts b/src/vs/workbench/electron-sandbox/window.ts index 571cd3a5f0f..af2e33d72d2 100644 --- a/src/vs/workbench/electron-sandbox/window.ts +++ b/src/vs/workbench/electron-sandbox/window.ts @@ -68,8 +68,6 @@ import { dirname } from 'vs/base/common/resources'; export class NativeWindow extends Disposable { - private static REMEMBER_PROXY_CREDENTIALS_KEY = 'window.rememberProxyCredentials'; - private touchBarMenu: IMenu | undefined; private readonly touchBarDisposables = this._register(new DisposableStore()); private lastInstalledTouchedBar: ICommandAction[][] | undefined; @@ -215,7 +213,8 @@ export class NativeWindow extends Disposable { // Proxy Login Dialog ipcRenderer.on('vscode:openProxyAuthenticationDialog', async (event: unknown, payload: { authInfo: AuthInfo; username?: string; password?: string; replyChannel: string }) => { - const rememberCredentials = this.storageService.getBoolean(NativeWindow.REMEMBER_PROXY_CREDENTIALS_KEY, StorageScope.APPLICATION); + const rememberCredentialsKey = 'window.rememberProxyCredentials'; + const rememberCredentials = this.storageService.getBoolean(rememberCredentialsKey, StorageScope.APPLICATION); const result = await this.dialogService.input(Severity.Warning, localize('proxyAuthRequired', "Proxy Authentication Required"), [ localize({ key: 'loginButton', comment: ['&& denotes a mnemonic'] }, "&&Log In"), @@ -245,9 +244,9 @@ export class NativeWindow extends Disposable { // Update state based on checkbox if (result.checkboxChecked) { - this.storageService.store(NativeWindow.REMEMBER_PROXY_CREDENTIALS_KEY, true, StorageScope.APPLICATION, StorageTarget.MACHINE); + this.storageService.store(rememberCredentialsKey, true, StorageScope.APPLICATION, StorageTarget.MACHINE); } else { - this.storageService.remove(NativeWindow.REMEMBER_PROXY_CREDENTIALS_KEY, StorageScope.APPLICATION); + this.storageService.remove(rememberCredentialsKey, StorageScope.APPLICATION); } // Reply back to main side with credentials @@ -286,7 +285,7 @@ export class NativeWindow extends Disposable { const file = EditorResourceAccessor.getOriginalUri(this.editorService.activeEditor, { supportSideBySide: SideBySideEditor.PRIMARY, filterByScheme: Schemas.file }); // Represented Filename - this.updateRepresentedFilename(file?.fsPath); + this.nativeHostService.setRepresentedFilename(file?.fsPath ?? ''); // Custom title menu this.provideCustomTitleContextMenu(file?.fsPath); @@ -573,10 +572,6 @@ export class NativeWindow extends Disposable { } } - private updateRepresentedFilename(filePath: string | undefined): void { - this.nativeHostService.setRepresentedFilename(filePath ? filePath : ''); - } - private provideCustomTitleContextMenu(filePath: string | undefined): void { // Clear old menu -- cgit v1.2.3 From 4f5d16a9ed9e6dc041a0fc299aa5d1132555697d Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Jul 2022 09:01:54 +0200 Subject: status bar - prevent default of key event (fix #154071) (#154130) --- src/vs/workbench/browser/parts/statusbar/statusbarItem.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts b/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts index 9d9c7e3e23a..6b4685f4901 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts @@ -12,7 +12,7 @@ import { IStatusbarEntry, ShowTooltipCommand } from 'vs/workbench/services/statu import { WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification } from 'vs/base/common/actions'; import { IThemeService, ThemeColor } from 'vs/platform/theme/common/themeService'; import { isThemeColor } from 'vs/editor/common/editorCommon'; -import { addDisposableListener, EventType, hide, show, append } from 'vs/base/browser/dom'; +import { addDisposableListener, EventType, hide, show, append, EventHelper } from 'vs/base/browser/dom'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { assertIsDefined } from 'vs/base/common/types'; import { Command } from 'vs/editor/common/languages'; @@ -129,6 +129,8 @@ export class StatusbarEntryItem extends Disposable { this.commandKeyboardListener.value = addDisposableListener(this.labelContainer, EventType.KEY_DOWN, e => { const event = new StandardKeyboardEvent(e); if (event.equals(KeyCode.Space) || event.equals(KeyCode.Enter)) { + EventHelper.stop(e); + this.executeCommand(command); } }); -- cgit v1.2.3 From ce7ced73adcd0ca8bdc2b957c56423e5a13666c0 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 5 Jul 2022 09:15:30 +0200 Subject: Fix #153663 (#154104) --- .../extensions/browser/extensionsActions.ts | 76 +++++++++++----------- 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 710e811a4f7..c6d34dc012f 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -1623,38 +1623,38 @@ export class SetColorThemeAction extends ExtensionAction { private static readonly EnabledClass = `${ExtensionAction.LABEL_ACTION_CLASS} theme`; private static readonly DisabledClass = `${SetColorThemeAction.EnabledClass} disabled`; - private colorThemes: IWorkbenchColorTheme[] = []; - constructor( @IExtensionService extensionService: IExtensionService, @IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService, @IQuickInputService private readonly quickInputService: IQuickInputService, + @IWorkbenchExtensionEnablementService private readonly extensionEnablementService: IWorkbenchExtensionEnablementService, ) { super(SetColorThemeAction.ID, SetColorThemeAction.TITLE.value, SetColorThemeAction.DisabledClass, false); this._register(Event.any(extensionService.onDidChangeExtensions, workbenchThemeService.onDidColorThemeChange)(() => this.update(), this)); - workbenchThemeService.getColorThemes().then(colorThemes => { - this.colorThemes = colorThemes; - this.update(); - }); this.update(); } update(): void { - this.enabled = !!this.extension && (this.extension.state === ExtensionState.Installed) && this.colorThemes.some(th => isThemeFromExtension(th, this.extension)); - this.class = this.enabled ? SetColorThemeAction.EnabledClass : SetColorThemeAction.DisabledClass; + this.workbenchThemeService.getColorThemes().then(colorThemes => { + this.enabled = this.computeEnablement(colorThemes); + this.class = this.enabled ? SetColorThemeAction.EnabledClass : SetColorThemeAction.DisabledClass; + }); + } + + private computeEnablement(colorThemes: IWorkbenchColorTheme[]): boolean { + return !!this.extension && this.extension.state === ExtensionState.Installed && this.extensionEnablementService.isEnabledEnablementState(this.extension.enablementState) && colorThemes.some(th => isThemeFromExtension(th, this.extension)); } override async run({ showCurrentTheme, ignoreFocusLost }: { showCurrentTheme: boolean; ignoreFocusLost: boolean } = { showCurrentTheme: false, ignoreFocusLost: false }): Promise { - this.colorThemes = await this.workbenchThemeService.getColorThemes(); + const colorThemes = await this.workbenchThemeService.getColorThemes(); - this.update(); - if (!this.enabled) { + if (!this.computeEnablement(colorThemes)) { return; } const currentTheme = this.workbenchThemeService.getColorTheme(); const delayer = new Delayer(100); - const picks = getQuickPickEntries(this.colorThemes, currentTheme, this.extension, showCurrentTheme); + const picks = getQuickPickEntries(colorThemes, currentTheme, this.extension, showCurrentTheme); const pickedTheme = await this.quickInputService.pick( picks, { @@ -1674,37 +1674,37 @@ export class SetFileIconThemeAction extends ExtensionAction { private static readonly EnabledClass = `${ExtensionAction.LABEL_ACTION_CLASS} theme`; private static readonly DisabledClass = `${SetFileIconThemeAction.EnabledClass} disabled`; - private fileIconThemes: IWorkbenchFileIconTheme[] = []; - constructor( @IExtensionService extensionService: IExtensionService, @IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService, - @IQuickInputService private readonly quickInputService: IQuickInputService + @IQuickInputService private readonly quickInputService: IQuickInputService, + @IWorkbenchExtensionEnablementService private readonly extensionEnablementService: IWorkbenchExtensionEnablementService, ) { super(SetFileIconThemeAction.ID, SetFileIconThemeAction.TITLE.value, SetFileIconThemeAction.DisabledClass, false); this._register(Event.any(extensionService.onDidChangeExtensions, workbenchThemeService.onDidFileIconThemeChange)(() => this.update(), this)); - workbenchThemeService.getFileIconThemes().then(fileIconThemes => { - this.fileIconThemes = fileIconThemes; - this.update(); - }); this.update(); } update(): void { - this.enabled = !!this.extension && (this.extension.state === ExtensionState.Installed) && this.fileIconThemes.some(th => isThemeFromExtension(th, this.extension)); - this.class = this.enabled ? SetFileIconThemeAction.EnabledClass : SetFileIconThemeAction.DisabledClass; + this.workbenchThemeService.getFileIconThemes().then(fileIconThemes => { + this.enabled = this.computeEnablement(fileIconThemes); + this.class = this.enabled ? SetFileIconThemeAction.EnabledClass : SetFileIconThemeAction.DisabledClass; + }); + } + + private computeEnablement(colorThemfileIconThemess: IWorkbenchFileIconTheme[]): boolean { + return !!this.extension && this.extension.state === ExtensionState.Installed && this.extensionEnablementService.isEnabledEnablementState(this.extension.enablementState) && colorThemfileIconThemess.some(th => isThemeFromExtension(th, this.extension)); } override async run({ showCurrentTheme, ignoreFocusLost }: { showCurrentTheme: boolean; ignoreFocusLost: boolean } = { showCurrentTheme: false, ignoreFocusLost: false }): Promise { - this.fileIconThemes = await this.workbenchThemeService.getFileIconThemes(); - this.update(); - if (!this.enabled) { + const fileIconThemes = await this.workbenchThemeService.getFileIconThemes(); + if (!this.computeEnablement(fileIconThemes)) { return; } const currentTheme = this.workbenchThemeService.getFileIconTheme(); const delayer = new Delayer(100); - const picks = getQuickPickEntries(this.fileIconThemes, currentTheme, this.extension, showCurrentTheme); + const picks = getQuickPickEntries(fileIconThemes, currentTheme, this.extension, showCurrentTheme); const pickedTheme = await this.quickInputService.pick( picks, { @@ -1724,38 +1724,38 @@ export class SetProductIconThemeAction extends ExtensionAction { private static readonly EnabledClass = `${ExtensionAction.LABEL_ACTION_CLASS} theme`; private static readonly DisabledClass = `${SetProductIconThemeAction.EnabledClass} disabled`; - private productIconThemes: IWorkbenchProductIconTheme[] = []; - constructor( @IExtensionService extensionService: IExtensionService, @IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService, - @IQuickInputService private readonly quickInputService: IQuickInputService + @IQuickInputService private readonly quickInputService: IQuickInputService, + @IWorkbenchExtensionEnablementService private readonly extensionEnablementService: IWorkbenchExtensionEnablementService, ) { super(SetProductIconThemeAction.ID, SetProductIconThemeAction.TITLE.value, SetProductIconThemeAction.DisabledClass, false); this._register(Event.any(extensionService.onDidChangeExtensions, workbenchThemeService.onDidProductIconThemeChange)(() => this.update(), this)); - workbenchThemeService.getProductIconThemes().then(productIconThemes => { - this.productIconThemes = productIconThemes; - this.update(); - }); this.update(); } update(): void { - this.enabled = !!this.extension && (this.extension.state === ExtensionState.Installed) && this.productIconThemes.some(th => isThemeFromExtension(th, this.extension)); - this.class = this.enabled ? SetProductIconThemeAction.EnabledClass : SetProductIconThemeAction.DisabledClass; + this.workbenchThemeService.getProductIconThemes().then(productIconThemes => { + this.enabled = this.computeEnablement(productIconThemes); + this.class = this.enabled ? SetProductIconThemeAction.EnabledClass : SetProductIconThemeAction.DisabledClass; + }); + } + + private computeEnablement(productIconThemes: IWorkbenchProductIconTheme[]): boolean { + return !!this.extension && this.extension.state === ExtensionState.Installed && this.extensionEnablementService.isEnabledEnablementState(this.extension.enablementState) && productIconThemes.some(th => isThemeFromExtension(th, this.extension)); } override async run({ showCurrentTheme, ignoreFocusLost }: { showCurrentTheme: boolean; ignoreFocusLost: boolean } = { showCurrentTheme: false, ignoreFocusLost: false }): Promise { - this.productIconThemes = await this.workbenchThemeService.getProductIconThemes(); - this.update(); - if (!this.enabled) { + const productIconThemes = await this.workbenchThemeService.getProductIconThemes(); + if (!this.computeEnablement(productIconThemes)) { return; } const currentTheme = this.workbenchThemeService.getProductIconTheme(); const delayer = new Delayer(100); - const picks = getQuickPickEntries(this.productIconThemes, currentTheme, this.extension, showCurrentTheme); + const picks = getQuickPickEntries(productIconThemes, currentTheme, this.extension, showCurrentTheme); const pickedTheme = await this.quickInputService.pick( picks, { -- cgit v1.2.3 From 866f22e2d17f5da33803b4f41dc681f5a5a3ef5f Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 5 Jul 2022 09:16:36 +0200 Subject: Adresses #153865 (#154100) --- .../mergeEditor/browser/commands/commands.ts | 110 +++++++++++++++------ .../mergeEditor/browser/commands/devCommands.ts | 16 ++- 2 files changed, 93 insertions(+), 33 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts b/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts index 375c202ea6a..7e100501342 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts @@ -6,6 +6,7 @@ import { Codicon } from 'vs/base/common/codicons'; import { URI, UriComponents } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; +import { ILocalizedString } from 'vs/platform/action/common/action'; import { Action2, MenuId } from 'vs/platform/actions/common/actions'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; @@ -19,7 +20,7 @@ export class OpenMergeEditor extends Action2 { constructor() { super({ id: '_open.mergeEditor', - title: localize('title', "Open Merge Editor"), + title: { value: localize('title', "Open Merge Editor"), original: 'Open Merge Editor' }, }); } run(accessor: ServicesAccessor, ...args: unknown[]): void { @@ -111,14 +112,19 @@ export class SetMixedLayout extends Action2 { constructor() { super({ id: 'merge.mixedLayout', - title: localize('layout.mixed', "Mixed Layout"), + title: { + value: localize('layout.mixed', 'Mixed Layout'), + original: 'Mixed Layout', + }, toggled: ctxMergeEditorLayout.isEqualTo('mixed'), - menu: [{ - id: MenuId.EditorTitle, - when: ctxIsMergeEditor, - group: '1_merge', - order: 9, - }], + menu: [ + { + id: MenuId.EditorTitle, + when: ctxIsMergeEditor, + group: '1_merge', + order: 9, + }, + ], precondition: ctxIsMergeEditor, }); } @@ -135,7 +141,7 @@ export class SetColumnLayout extends Action2 { constructor() { super({ id: 'merge.columnLayout', - title: localize('layout.column', "Column Layout"), + title: { value: localize('layout.column', "Column Layout"), original: 'Column Layout' }, toggled: ctxMergeEditorLayout.isEqualTo('columns'), menu: [{ id: MenuId.EditorTitle, @@ -155,18 +161,28 @@ export class SetColumnLayout extends Action2 { } } +const mergeEditorCategory: ILocalizedString = { + value: localize('mergeEditor', 'Merge Editor'), + original: 'Merge Editor', +}; + export class GoToNextConflict extends Action2 { constructor() { super({ id: 'merge.goToNextConflict', - category: localize('mergeEditor', "Merge Editor"), - title: localize('merge.goToNextConflict', "Go to Next Conflict"), + category: mergeEditorCategory, + title: { + value: localize('merge.goToNextConflict', 'Go to Next Conflict'), + original: 'Go to Next Conflict', + }, icon: Codicon.arrowDown, - menu: [{ - id: MenuId.EditorTitle, - when: ctxIsMergeEditor, - group: 'navigation', - }], + menu: [ + { + id: MenuId.EditorTitle, + when: ctxIsMergeEditor, + group: 'navigation', + }, + ], f1: true, precondition: ctxIsMergeEditor, }); @@ -184,14 +200,22 @@ export class GoToPreviousConflict extends Action2 { constructor() { super({ id: 'merge.goToPreviousConflict', - category: localize('mergeEditor', "Merge Editor"), - title: localize('merge.goToPreviousConflict', "Go to Previous Conflict"), + category: mergeEditorCategory, + title: { + value: localize( + 'merge.goToPreviousConflict', + 'Go to Previous Conflict' + ), + original: 'Go to Previous Conflict', + }, icon: Codicon.arrowUp, - menu: [{ - id: MenuId.EditorTitle, - when: ctxIsMergeEditor, - group: 'navigation', - }], + menu: [ + { + id: MenuId.EditorTitle, + when: ctxIsMergeEditor, + group: 'navigation', + }, + ], f1: true, precondition: ctxIsMergeEditor, }); @@ -209,8 +233,14 @@ export class ToggleActiveConflictInput1 extends Action2 { constructor() { super({ id: 'merge.toggleActiveConflictInput1', - category: localize('mergeEditor', "Merge Editor"), - title: localize('merge.toggleCurrentConflictFromLeft', "Toggle Current Conflict from Left"), + category: mergeEditorCategory, + title: { + value: localize( + 'merge.toggleCurrentConflictFromLeft', + 'Toggle Current Conflict from Left' + ), + original: 'Toggle Current Conflict from Left', + }, f1: true, precondition: ctxIsMergeEditor, }); @@ -232,8 +262,14 @@ export class ToggleActiveConflictInput2 extends Action2 { constructor() { super({ id: 'merge.toggleActiveConflictInput2', - category: localize('mergeEditor', "Merge Editor"), - title: localize('merge.toggleCurrentConflictFromRight', "Toggle Current Conflict from Right"), + category: mergeEditorCategory, + title: { + value: localize( + 'merge.toggleCurrentConflictFromRight', + 'Toggle Current Conflict from Right' + ), + original: 'Toggle Current Conflict from Right', + }, f1: true, precondition: ctxIsMergeEditor, }); @@ -255,8 +291,14 @@ export class CompareInput1WithBaseCommand extends Action2 { constructor() { super({ id: 'mergeEditor.compareInput1WithBase', - category: localize('mergeEditor', "Merge Editor"), - title: localize('mergeEditor.compareInput1WithBase', "Compare Input 1 With Base"), + category: mergeEditorCategory, + title: { + value: localize( + 'mergeEditor.compareInput1WithBase', + 'Compare Input 1 With Base' + ), + original: 'Compare Input 1 With Base', + }, f1: true, precondition: ctxIsMergeEditor, }); @@ -272,8 +314,14 @@ export class CompareInput2WithBaseCommand extends Action2 { constructor() { super({ id: 'mergeEditor.compareInput2WithBase', - category: localize('mergeEditor', "Merge Editor"), - title: localize('mergeEditor.compareInput2WithBase', "Compare Input 2 With Base"), + category: mergeEditorCategory, + title: { + value: localize( + 'mergeEditor.compareInput2WithBase', + 'Compare Input 2 With Base' + ), + original: 'Compare Input 2 With Base', + }, f1: true, precondition: ctxIsMergeEditor, }); diff --git a/src/vs/workbench/contrib/mergeEditor/browser/commands/devCommands.ts b/src/vs/workbench/contrib/mergeEditor/browser/commands/devCommands.ts index 83a458d15f5..aaf15c771da 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/commands/devCommands.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/commands/devCommands.ts @@ -34,7 +34,13 @@ export class MergeEditorCopyContentsToJSON extends Action2 { super({ id: 'merge.dev.copyContents', category: 'Merge Editor (Dev)', - title: localize('merge.dev.copyContents', "Copy Contents of Inputs, Base and Result as JSON"), + title: { + value: localize( + 'merge.dev.copyContents', + 'Copy Contents of Inputs, Base and Result as JSON' + ), + original: 'Copy Contents of Inputs, Base and Result as JSON', + }, icon: Codicon.layoutCentered, f1: true, precondition: ctxIsMergeEditor, @@ -80,7 +86,13 @@ export class MergeEditorOpenContents extends Action2 { super({ id: 'merge.dev.openContents', category: 'Merge Editor (Dev)', - title: localize('merge.dev.openContents', "Open Contents of Inputs, Base and Result from JSON"), + title: { + value: localize( + 'merge.dev.openContents', + 'Open Contents of Inputs, Base and Result from JSON' + ), + original: 'Open Contents of Inputs, Base and Result from JSON', + }, icon: Codicon.layoutCentered, f1: true, }); -- cgit v1.2.3 From f4f1b04d872a2b94d9a5105a1eefb81a213c07f2 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Jul 2022 09:54:28 +0200 Subject: Add a setting to enable `sandbox: true` for windows (#154062) * sandbox - allow enabled sandbox in a full build * sandbox - reduce `electron-browser` in workbench * sandbox - reduce `electron-browser` in platform * sandbox - add a setting to enable sandbox mode for window * fix lint * Revert "sandbox - reduce `electron-browser` in workbench" This reverts commit 36a5167cf9525e98a37137915f9f8c748ca47ae5. * Revert "sandbox - reduce `electron-browser` in platform" This reverts commit 6f49d704a5403dbf286e6eb30700387454e0d047. * fix layer issue * fix some js errors --- src/vs/base/parts/ipc/node/ipc.net.ts | 33 ++-- .../code/electron-browser/workbench/workbench.html | 19 -- .../code/electron-browser/workbench/workbench.js | 213 --------------------- .../code/electron-sandbox/workbench/workbench.js | 6 +- src/vs/platform/environment/common/argv.ts | 1 - .../electron-main/environmentMainService.ts | 4 - src/vs/platform/environment/node/argv.ts | 1 - src/vs/platform/window/common/window.ts | 1 + src/vs/platform/windows/electron-main/window.ts | 7 +- src/vs/workbench/browser/workbench.ts | 7 +- .../extensions/browser/extensions.contribution.ts | 3 +- .../relauncher/browser/relauncher.contribution.ts | 10 +- .../electron-sandbox/desktop.contribution.ts | 7 +- src/vs/workbench/electron-sandbox/desktop.main.ts | 20 +- .../electron-browser/nativeExtensionService.ts | 20 -- .../nativeLocalProcessExtensionHost.ts | 119 ------------ .../nativeLocalProcessExtensionHost.ts | 123 ++++++++++++ .../electron-sandbox/sandboxExtensionService.ts | 11 +- src/vs/workbench/workbench.desktop.main.ts | 176 +++++++++++++---- src/vs/workbench/workbench.desktop.sandbox.main.ts | 32 ---- src/vs/workbench/workbench.sandbox.main.ts | 159 --------------- 21 files changed, 324 insertions(+), 648 deletions(-) delete mode 100644 src/vs/code/electron-browser/workbench/workbench.html delete mode 100644 src/vs/code/electron-browser/workbench/workbench.js delete mode 100644 src/vs/workbench/services/extensions/electron-browser/nativeExtensionService.ts delete mode 100644 src/vs/workbench/services/extensions/electron-browser/nativeLocalProcessExtensionHost.ts create mode 100644 src/vs/workbench/services/extensions/electron-sandbox/nativeLocalProcessExtensionHost.ts delete mode 100644 src/vs/workbench/workbench.desktop.sandbox.main.ts delete mode 100644 src/vs/workbench/workbench.sandbox.main.ts (limited to 'src/vs') diff --git a/src/vs/base/parts/ipc/node/ipc.net.ts b/src/vs/base/parts/ipc/node/ipc.net.ts index 9831dcde97c..bff8e41d8e5 100644 --- a/src/vs/base/parts/ipc/node/ipc.net.ts +++ b/src/vs/base/parts/ipc/node/ipc.net.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { createHash } from 'crypto'; -import { createConnection, createServer, Server as NetServer, Socket } from 'net'; -import { tmpdir } from 'os'; +// import { createHash } from 'crypto'; +import type { Server as NetServer, Socket } from 'net'; +// import { tmpdir } from 'os'; +import type * as zlib from 'zlib'; import { VSBuffer } from 'vs/base/common/buffer'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; @@ -15,7 +16,16 @@ import { Platform, platform } from 'vs/base/common/platform'; import { generateUuid } from 'vs/base/common/uuid'; import { ClientConnectionEvent, IPCServer } from 'vs/base/parts/ipc/common/ipc'; import { ChunkStream, Client, ISocket, Protocol, SocketCloseEvent, SocketCloseEventType, SocketDiagnostics, SocketDiagnosticsEventType } from 'vs/base/parts/ipc/common/ipc.net'; -import * as zlib from 'zlib'; + +// TODO@bpasero remove me once electron utility process has landed +function getNodeDependencies() { + return { + crypto: (require.__$__nodeRequire('crypto') as any) as typeof import('crypto'), + zlib: (require.__$__nodeRequire('zlib') as any) as typeof import('zlib'), + net: (require.__$__nodeRequire('net') as any) as typeof import('net'), + os: (require.__$__nodeRequire('os') as any) as typeof import('os') + }; +} export class NodeSocket implements ISocket { @@ -580,7 +590,7 @@ class ZlibInflateStream extends Disposable { options: zlib.ZlibOptions ) { super(); - this._zlibInflate = zlib.createInflateRaw(options); + this._zlibInflate = getNodeDependencies().zlib.createInflateRaw(options); this._zlibInflate.on('error', (err) => { this._tracer.traceSocketEvent(SocketDiagnosticsEventType.zlibInflateError, { message: err?.message, code: (err)?.code }); this._onError.fire(err); @@ -631,7 +641,7 @@ class ZlibDeflateStream extends Disposable { ) { super(); - this._zlibDeflate = zlib.createDeflateRaw({ + this._zlibDeflate = getNodeDependencies().zlib.createDeflateRaw({ windowBits: 15 }); this._zlibDeflate.on('error', (err) => { @@ -692,7 +702,8 @@ function unmask(buffer: VSBuffer, mask: number): void { // Read this before there's any chance it is overwritten // Related to https://github.com/microsoft/vscode/issues/30624 -export const XDG_RUNTIME_DIR = process.env['XDG_RUNTIME_DIR']; +// TODO@bpasero revert me once electron utility process has landed +export const XDG_RUNTIME_DIR = typeof process !== 'undefined' ? process.env['XDG_RUNTIME_DIR'] : undefined; const safeIpcPathLengths: { [platform: number]: number } = { [Platform.Linux]: 107, @@ -713,7 +724,7 @@ export function createRandomIPCHandle(): string { if (XDG_RUNTIME_DIR) { result = join(XDG_RUNTIME_DIR, `vscode-ipc-${randomSuffix}.sock`); } else { - result = join(tmpdir(), `vscode-ipc-${randomSuffix}.sock`); + result = join(getNodeDependencies().os.tmpdir(), `vscode-ipc-${randomSuffix}.sock`); } // Validate length @@ -723,7 +734,7 @@ export function createRandomIPCHandle(): string { } export function createStaticIPCHandle(directoryPath: string, type: string, version: string): string { - const scope = createHash('md5').update(directoryPath).digest('hex'); + const scope = getNodeDependencies().crypto.createHash('md5').update(directoryPath).digest('hex'); // Windows: use named pipe if (process.platform === 'win32') { @@ -785,7 +796,7 @@ export function serve(port: number): Promise; export function serve(namedPipe: string): Promise; export function serve(hook: any): Promise { return new Promise((c, e) => { - const server = createServer(); + const server = getNodeDependencies().net.createServer(); server.on('error', e); server.listen(hook, () => { @@ -800,7 +811,7 @@ export function connect(port: number, clientId: string): Promise; export function connect(namedPipe: string, clientId: string): Promise; export function connect(hook: any, clientId: string): Promise { return new Promise((c, e) => { - const socket = createConnection(hook, () => { + const socket = getNodeDependencies().net.createConnection(hook, () => { socket.removeListener('error', e); c(Client.fromSocket(new NodeSocket(socket, `ipc-client${clientId}`), clientId)); }); diff --git a/src/vs/code/electron-browser/workbench/workbench.html b/src/vs/code/electron-browser/workbench/workbench.html deleted file mode 100644 index 47066f520be..00000000000 --- a/src/vs/code/electron-browser/workbench/workbench.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/src/vs/code/electron-browser/workbench/workbench.js b/src/vs/code/electron-browser/workbench/workbench.js deleted file mode 100644 index 7ceef489fcc..00000000000 --- a/src/vs/code/electron-browser/workbench/workbench.js +++ /dev/null @@ -1,213 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -/// - -//@ts-check -(function () { - 'use strict'; - - const bootstrapWindow = bootstrapWindowLib(); - - // Add a perf entry right from the top - performance.mark('code/didStartRenderer'); - - // Load workbench main JS, CSS and NLS all in parallel. This is an - // optimization to prevent a waterfall of loading to happen, because - // we know for a fact that workbench.desktop.main will depend on - // the related CSS and NLS counterparts. - bootstrapWindow.load([ - 'vs/workbench/workbench.desktop.main', - 'vs/nls!vs/workbench/workbench.desktop.main', - 'vs/css!vs/workbench/workbench.desktop.main' - ], - function (_, configuration) { - - // Mark start of workbench - performance.mark('code/didLoadWorkbenchMain'); - - // @ts-ignore - return require('vs/workbench/electron-sandbox/desktop.main').main(configuration); - }, - { - configureDeveloperSettings: function (windowConfig) { - return { - // disable automated devtools opening on error when running extension tests - // as this can lead to nondeterministic test execution (devtools steals focus) - forceDisableShowDevtoolsOnError: typeof windowConfig.extensionTestsPath === 'string', - // enable devtools keybindings in extension development window - forceEnableDeveloperKeybindings: Array.isArray(windowConfig.extensionDevelopmentPath) && windowConfig.extensionDevelopmentPath.length > 0, - removeDeveloperKeybindingsAfterLoad: true - }; - }, - canModifyDOM: function (windowConfig) { - showSplash(windowConfig); - }, - beforeLoaderConfig: function (loaderConfig) { - loaderConfig.recordStats = true; - }, - beforeRequire: function () { - performance.mark('code/willLoadWorkbenchMain'); - - // It looks like browsers only lazily enable - // the element when needed. Since we - // leverage canvas elements in our code in many - // locations, we try to help the browser to - // initialize canvas when it is idle, right - // before we wait for the scripts to be loaded. - // @ts-ignore - window.requestIdleCallback(() => { - const canvas = document.createElement('canvas'); - const context = canvas.getContext('2d'); - context.clearRect(0, 0, canvas.width, canvas.height); - canvas.remove(); - }, { timeout: 50 }); - } - } - ); - - //#region Helpers - - /** - * @typedef {import('../../../platform/window/common/window').INativeWindowConfiguration} INativeWindowConfiguration - * @typedef {import('../../../platform/environment/common/argv').NativeParsedArgs} NativeParsedArgs - * - * @returns {{ - * load: ( - * modules: string[], - * resultCallback: (result, configuration: INativeWindowConfiguration & NativeParsedArgs) => unknown, - * options?: { - * configureDeveloperSettings?: (config: INativeWindowConfiguration & NativeParsedArgs) => { - * forceDisableShowDevtoolsOnError?: boolean, - * forceEnableDeveloperKeybindings?: boolean, - * disallowReloadKeybinding?: boolean, - * removeDeveloperKeybindingsAfterLoad?: boolean - * }, - * canModifyDOM?: (config: INativeWindowConfiguration & NativeParsedArgs) => void, - * beforeLoaderConfig?: (loaderConfig: object) => void, - * beforeRequire?: () => void - * } - * ) => Promise - * }} - */ - function bootstrapWindowLib() { - // @ts-ignore (defined in bootstrap-window.js) - return window.MonacoBootstrapWindow; - } - - /** - * @param {INativeWindowConfiguration & NativeParsedArgs} configuration - */ - function showSplash(configuration) { - performance.mark('code/willShowPartsSplash'); - - let data = configuration.partsSplash; - - if (data) { - // high contrast mode has been turned by the OS -> ignore stored colors and layouts - if (configuration.autoDetectHighContrast && configuration.colorScheme.highContrast) { - if ((configuration.colorScheme.dark && data.baseTheme !== 'hc-black') || (!configuration.colorScheme.dark && data.baseTheme !== 'hc-light')) { - data = undefined; - } - } else if (configuration.autoDetectColorScheme) { - // OS color scheme is tracked and has changed - if ((configuration.colorScheme.dark && data.baseTheme !== 'vs-dark') || (!configuration.colorScheme.dark && data.baseTheme !== 'vs')) { - data = undefined; - } - } - } - - // developing an extension -> ignore stored layouts - if (data && configuration.extensionDevelopmentPath) { - data.layoutInfo = undefined; - } - - // minimal color configuration (works with or without persisted data) - let baseTheme, shellBackground, shellForeground; - if (data) { - baseTheme = data.baseTheme; - shellBackground = data.colorInfo.editorBackground; - shellForeground = data.colorInfo.foreground; - } else if (configuration.autoDetectHighContrast && configuration.colorScheme.highContrast) { - if (configuration.colorScheme.dark) { - baseTheme = 'hc-black'; - shellBackground = '#000000'; - shellForeground = '#FFFFFF'; - } else { - baseTheme = 'hc-light'; - shellBackground = '#FFFFFF'; - shellForeground = '#000000'; - } - } else if (configuration.autoDetectColorScheme) { - if (configuration.colorScheme.dark) { - baseTheme = 'vs-dark'; - shellBackground = '#1E1E1E'; - shellForeground = '#CCCCCC'; - } else { - baseTheme = 'vs'; - shellBackground = '#FFFFFF'; - shellForeground = '#000000'; - } - } - - const style = document.createElement('style'); - style.className = 'initialShellColors'; - document.head.appendChild(style); - style.textContent = `body { background-color: ${shellBackground}; color: ${shellForeground}; margin: 0; padding: 0; }`; - - // restore parts if possible (we might not always store layout info) - if (data?.layoutInfo) { - const { layoutInfo, colorInfo } = data; - - const splash = document.createElement('div'); - splash.id = 'monaco-parts-splash'; - splash.className = baseTheme; - - if (layoutInfo.windowBorder) { - splash.style.position = 'relative'; - splash.style.height = 'calc(100vh - 2px)'; - splash.style.width = 'calc(100vw - 2px)'; - splash.style.border = '1px solid var(--window-border-color)'; - splash.style.setProperty('--window-border-color', colorInfo.windowBorder); - - if (layoutInfo.windowBorderRadius) { - splash.style.borderRadius = layoutInfo.windowBorderRadius; - } - } - - // ensure there is enough space - layoutInfo.sideBarWidth = Math.min(layoutInfo.sideBarWidth, window.innerWidth - (layoutInfo.activityBarWidth + layoutInfo.editorPartMinWidth)); - - // part: title - const titleDiv = document.createElement('div'); - titleDiv.setAttribute('style', `position: absolute; width: 100%; left: 0; top: 0; height: ${layoutInfo.titleBarHeight}px; background-color: ${colorInfo.titleBarBackground}; -webkit-app-region: drag;`); - splash.appendChild(titleDiv); - - // part: activity bar - const activityDiv = document.createElement('div'); - activityDiv.setAttribute('style', `position: absolute; height: calc(100% - ${layoutInfo.titleBarHeight}px); top: ${layoutInfo.titleBarHeight}px; ${layoutInfo.sideBarSide}: 0; width: ${layoutInfo.activityBarWidth}px; background-color: ${colorInfo.activityBarBackground};`); - splash.appendChild(activityDiv); - - // part: side bar (only when opening workspace/folder) - // folder or workspace -> status bar color, sidebar - if (configuration.workspace) { - const sideDiv = document.createElement('div'); - sideDiv.setAttribute('style', `position: absolute; height: calc(100% - ${layoutInfo.titleBarHeight}px); top: ${layoutInfo.titleBarHeight}px; ${layoutInfo.sideBarSide}: ${layoutInfo.activityBarWidth}px; width: ${layoutInfo.sideBarWidth}px; background-color: ${colorInfo.sideBarBackground};`); - splash.appendChild(sideDiv); - } - - // part: statusbar - const statusDiv = document.createElement('div'); - statusDiv.setAttribute('style', `position: absolute; width: 100%; bottom: 0; left: 0; height: ${layoutInfo.statusBarHeight}px; background-color: ${configuration.workspace ? colorInfo.statusBarBackground : colorInfo.statusBarNoFolderBackground};`); - splash.appendChild(statusDiv); - - document.body.appendChild(splash); - } - - performance.mark('code/didShowPartsSplash'); - } - - //#endregion -}()); diff --git a/src/vs/code/electron-sandbox/workbench/workbench.js b/src/vs/code/electron-sandbox/workbench/workbench.js index e271fdf1bf4..0af36c6e1ac 100644 --- a/src/vs/code/electron-sandbox/workbench/workbench.js +++ b/src/vs/code/electron-sandbox/workbench/workbench.js @@ -16,10 +16,10 @@ // Load workbench main JS, CSS and NLS all in parallel. This is an // optimization to prevent a waterfall of loading to happen, because - // we know for a fact that workbench.desktop.sandbox.main will depend on + // we know for a fact that workbench.desktop.main will depend on // the related CSS and NLS counterparts. bootstrapWindow.load([ - 'vs/workbench/workbench.desktop.sandbox.main', + 'vs/workbench/workbench.desktop.main', 'vs/nls!vs/workbench/workbench.desktop.main', 'vs/css!vs/workbench/workbench.desktop.main' ], @@ -61,7 +61,7 @@ window.requestIdleCallback(() => { const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); - context.clearRect(0, 0, canvas.width, canvas.height); + context?.clearRect(0, 0, canvas.width, canvas.height); canvas.remove(); }, { timeout: 50 }); } diff --git a/src/vs/platform/environment/common/argv.ts b/src/vs/platform/environment/common/argv.ts index aa9c2407af0..0e8ccc14714 100644 --- a/src/vs/platform/environment/common/argv.ts +++ b/src/vs/platform/environment/common/argv.ts @@ -86,7 +86,6 @@ export interface NativeParsedArgs { 'force-user-env'?: boolean; 'force-disable-user-env'?: boolean; 'sync'?: 'on' | 'off'; - '__sandbox'?: boolean; 'logsPath'?: string; '__enable-file-policy'?: boolean; editSessionId?: string; diff --git a/src/vs/platform/environment/electron-main/environmentMainService.ts b/src/vs/platform/environment/electron-main/environmentMainService.ts index 6834b8115fe..53aabe4147c 100644 --- a/src/vs/platform/environment/electron-main/environmentMainService.ts +++ b/src/vs/platform/environment/electron-main/environmentMainService.ts @@ -34,7 +34,6 @@ export interface IEnvironmentMainService extends INativeEnvironmentService { mainLockfile: string; // --- config - sandbox: boolean; disableUpdates: boolean; } @@ -55,9 +54,6 @@ export class EnvironmentMainService extends NativeEnvironmentService implements @memoize get mainLockfile(): string { return join(this.userDataPath, 'code.lock'); } - @memoize - get sandbox(): boolean { return !!this.args['__sandbox']; } - @memoize get disableUpdates(): boolean { return !!this.args['disable-updates']; } diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index bb409289757..e27a89390c2 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -124,7 +124,6 @@ export const OPTIONS: OptionDescriptions> = { 'force-user-env': { type: 'boolean' }, 'force-disable-user-env': { type: 'boolean' }, 'open-devtools': { type: 'boolean' }, - '__sandbox': { type: 'boolean' }, 'logsPath': { type: 'string' }, '__enable-file-policy': { type: 'boolean' }, 'editSessionId': { type: 'string' }, diff --git a/src/vs/platform/window/common/window.ts b/src/vs/platform/window/common/window.ts index 1b68d3a166f..39b7fbba2c0 100644 --- a/src/vs/platform/window/common/window.ts +++ b/src/vs/platform/window/common/window.ts @@ -135,6 +135,7 @@ export interface IWindowSettings { readonly enableMenuBarMnemonics: boolean; readonly closeWhenEmpty: boolean; readonly clickThroughInactive: boolean; + readonly experimental?: { useSandbox: boolean }; } interface IWindowBorderColors { diff --git a/src/vs/platform/windows/electron-main/window.ts b/src/vs/platform/windows/electron-main/window.ts index f2a671d7b97..216d743026f 100644 --- a/src/vs/platform/windows/electron-main/window.ts +++ b/src/vs/platform/windows/electron-main/window.ts @@ -205,7 +205,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { // Enable experimental css highlight api https://chromestatus.com/feature/5436441440026624 // Refs https://github.com/microsoft/vscode/issues/140098 enableBlinkFeatures: 'HighlightAPI', - ...this.environmentMainService.sandbox ? + ...windowSettings?.experimental?.useSandbox ? // Sandbox { @@ -800,10 +800,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { this.readyState = ReadyState.NAVIGATING; // Load URL - this._win.loadURL(FileAccess.asBrowserUri(this.environmentMainService.sandbox ? - 'vs/code/electron-sandbox/workbench/workbench.html' : - 'vs/code/electron-browser/workbench/workbench.html', require - ).toString(true)); + this._win.loadURL(FileAccess.asBrowserUri('vs/code/electron-sandbox/workbench/workbench.html', require).toString(true)); // Remember that we did load const wasLoaded = this.wasLoaded; diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index 8094c87aca2..d505032b79a 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -188,11 +188,8 @@ export class Workbench extends Layout { // // NOTE: Please do NOT register services here. Use `registerSingleton()` // from `workbench.common.main.ts` if the service is shared between - // native and web or `workbench.sandbox.main.ts` if the service - // is native only. - // - // DO NOT add services to `workbench.desktop.main.ts`, always add - // to `workbench.sandbox.main.ts` to support our Electron sandbox + // desktop and web or `workbench.desktop.main.ts` if the service + // is desktop only. // // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index f64e267746c..b3c51e8a568 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -77,6 +77,7 @@ import { UnsupportedExtensionsMigrationContrib } from 'vs/workbench/contrib/exte import { isWeb } from 'vs/base/common/platform'; import { ExtensionStorageService } from 'vs/platform/extensionManagement/common/extensionStorage'; import { IStorageService } from 'vs/platform/storage/common/storage'; +import product from 'vs/platform/product/common/product'; // Singletons registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService); @@ -228,7 +229,7 @@ Registry.as(ConfigurationExtensions.Configuration) 'extensions.experimental.useUtilityProcess': { type: 'boolean', description: localize('extensionsUseUtilityProcess', "When enabled, the extension host will be launched using the new UtilityProcess Electron API."), - default: false + default: product.quality === 'stable' ? false : true // disabled by default in stable for now }, [WORKSPACE_TRUST_EXTENSION_SUPPORT]: { type: 'object', diff --git a/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts b/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts index 148c6c8d379..1680881aeb1 100644 --- a/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts +++ b/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts @@ -26,7 +26,7 @@ interface IConfiguration extends IWindowsConfiguration { debug?: { console?: { wordWrap?: boolean } }; editor?: { accessibilitySupport?: 'on' | 'off' | 'auto' }; security?: { workspace?: { trust?: { enabled?: boolean } } }; - window: IWindowSettings & { experimental?: { windowControlsOverlay?: { enabled?: boolean } } }; + window: IWindowSettings & { experimental?: { windowControlsOverlay?: { enabled?: boolean }; useSandbox?: boolean } }; workbench?: { experimental?: { settingsProfiles?: { enabled?: boolean } } }; } @@ -34,6 +34,7 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo private titleBarStyle: 'native' | 'custom' | undefined; private windowControlsOverlayEnabled: boolean | undefined; + private windowSandboxEnabled: boolean | undefined; private nativeTabs: boolean | undefined; private nativeFullScreen: boolean | undefined; private clickThroughInactive: boolean | undefined; @@ -66,11 +67,16 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo } // Windows: Window Controls Overlay - if (isWindows && typeof config.window?.experimental?.windowControlsOverlay?.enabled === 'boolean' && config.window?.experimental?.windowControlsOverlay?.enabled !== this.windowControlsOverlayEnabled) { + if (isWindows && typeof config.window?.experimental?.windowControlsOverlay?.enabled === 'boolean' && config.window.experimental.windowControlsOverlay.enabled !== this.windowControlsOverlayEnabled) { this.windowControlsOverlayEnabled = config.window.experimental.windowControlsOverlay.enabled; changed = true; } + // Windows: Sandbox + if (typeof config.window?.experimental?.useSandbox === 'boolean' && config.window.experimental.useSandbox !== this.windowSandboxEnabled) { + this.windowSandboxEnabled = config.window.experimental.useSandbox; + changed = true; + } // macOS: Native tabs if (isMacintosh && typeof config.window?.nativeTabs === 'boolean' && config.window.nativeTabs !== this.nativeTabs) { diff --git a/src/vs/workbench/electron-sandbox/desktop.contribution.ts b/src/vs/workbench/electron-sandbox/desktop.contribution.ts index 15bcde982e2..9e045e9638c 100644 --- a/src/vs/workbench/electron-sandbox/desktop.contribution.ts +++ b/src/vs/workbench/electron-sandbox/desktop.contribution.ts @@ -237,7 +237,12 @@ import { ModifierKeyEmitter } from 'vs/base/browser/dom'; 'scope': ConfigurationScope.APPLICATION, 'description': localize('window.clickThroughInactive', "If enabled, clicking on an inactive window will both activate the window and trigger the element under the mouse if it is clickable. If disabled, clicking anywhere on an inactive window will activate it only and a second click is required on the element."), 'included': isMacintosh - } + }, + 'window.experimental.useSandbox': { + type: 'boolean', + description: localize('experimentalUseSandbox', "Experimental: When enabled, the window will have sandbox mode enabled via Electron API."), + default: false + }, } }); diff --git a/src/vs/workbench/electron-sandbox/desktop.main.ts b/src/vs/workbench/electron-sandbox/desktop.main.ts index 86706f54945..706079b5ea7 100644 --- a/src/vs/workbench/electron-sandbox/desktop.main.ts +++ b/src/vs/workbench/electron-sandbox/desktop.main.ts @@ -148,12 +148,9 @@ export class DesktopMain extends Disposable { // // NOTE: Please do NOT register services here. Use `registerSingleton()` // from `workbench.common.main.ts` if the service is shared between - // desktop and web or `workbench.sandbox.main.ts` if the service + // desktop and web or `workbench.desktop.main.ts` if the service // is desktop only. // - // DO NOT add services to `workbench.desktop.main.ts`, always add - // to `workbench.sandbox.main.ts` to support our Electron sandbox - // // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -205,12 +202,9 @@ export class DesktopMain extends Disposable { // // NOTE: Please do NOT register services here. Use `registerSingleton()` // from `workbench.common.main.ts` if the service is shared between - // desktop and web or `workbench.sandbox.main.ts` if the service + // desktop and web or `workbench.desktop.main.ts` if the service // is desktop only. // - // DO NOT add services to `workbench.desktop.main.ts`, always add - // to `workbench.sandbox.main.ts` to support our Electron sandbox - // // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -250,12 +244,9 @@ export class DesktopMain extends Disposable { // // NOTE: Please do NOT register services here. Use `registerSingleton()` // from `workbench.common.main.ts` if the service is shared between - // desktop and web or `workbench.sandbox.main.ts` if the service + // desktop and web or `workbench.desktop.main.ts` if the service // is desktop only. // - // DO NOT add services to `workbench.desktop.main.ts`, always add - // to `workbench.sandbox.main.ts` to support our Electron sandbox - // // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -306,12 +297,9 @@ export class DesktopMain extends Disposable { // // NOTE: Please do NOT register services here. Use `registerSingleton()` // from `workbench.common.main.ts` if the service is shared between - // desktop and web or `workbench.sandbox.main.ts` if the service + // desktop and web or `workbench.desktop.main.ts` if the service // is desktop only. // - // DO NOT add services to `workbench.desktop.main.ts`, always add - // to `workbench.sandbox.main.ts` to support our Electron sandbox - // // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/src/vs/workbench/services/extensions/electron-browser/nativeExtensionService.ts b/src/vs/workbench/services/extensions/electron-browser/nativeExtensionService.ts deleted file mode 100644 index 2e4c745a9f8..00000000000 --- a/src/vs/workbench/services/extensions/electron-browser/nativeExtensionService.ts +++ /dev/null @@ -1,20 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { ExtensionHostKind, ExtensionRunningLocation, IExtensionHost, IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { NativeLocalProcessExtensionHost } from 'vs/workbench/services/extensions/electron-browser/nativeLocalProcessExtensionHost'; -import { ElectronExtensionService } from 'vs/workbench/services/extensions/electron-sandbox/electronExtensionService'; - -export class NativeExtensionService extends ElectronExtensionService { - protected override _createExtensionHost(runningLocation: ExtensionRunningLocation, isInitialStart: boolean): IExtensionHost | null { - if (runningLocation.kind === ExtensionHostKind.LocalProcess) { - return this._instantiationService.createInstance(NativeLocalProcessExtensionHost, runningLocation, this._createLocalExtensionHostDataProvider(isInitialStart, runningLocation)); - } - return super._createExtensionHost(runningLocation, isInitialStart); - } -} - -registerSingleton(IExtensionService, NativeExtensionService); diff --git a/src/vs/workbench/services/extensions/electron-browser/nativeLocalProcessExtensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/nativeLocalProcessExtensionHost.ts deleted file mode 100644 index 888db160609..00000000000 --- a/src/vs/workbench/services/extensions/electron-browser/nativeLocalProcessExtensionHost.ts +++ /dev/null @@ -1,119 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { createServer, Server } from 'net'; -import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; -import * as platform from 'vs/base/common/platform'; -import { StopWatch } from 'vs/base/common/stopwatch'; -import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; -import { PersistentProtocol } from 'vs/base/parts/ipc/common/ipc.net'; -import { createRandomIPCHandle, NodeSocket } from 'vs/base/parts/ipc/node/ipc.net'; -import { IExtensionHostProcessOptions } from 'vs/platform/extensions/common/extensionHostStarter'; -import { ILogService } from 'vs/platform/log/common/log'; -import { IPCExtHostConnection, writeExtHostConnection } from 'vs/workbench/services/extensions/common/extensionHostEnv'; -import { createMessageOfType, MessageType } from 'vs/workbench/services/extensions/common/extensionHostProtocol'; -import { ExtensionHostProcess, ExtHostMessagePortCommunication, IExtHostCommunication, SandboxLocalProcessExtensionHost } from 'vs/workbench/services/extensions/electron-sandbox/localProcessExtensionHost'; - -export class NativeLocalProcessExtensionHost extends SandboxLocalProcessExtensionHost { - protected override async _start(): Promise { - const canUseUtilityProcess = await this._extensionHostStarter.canUseUtilityProcess(); - if (canUseUtilityProcess && this._configurationService.getValue('extensions.experimental.useUtilityProcess')) { - const communication = this._toDispose.add(new ExtHostMessagePortCommunication(this._logService)); - return this._startWithCommunication(communication); - } else { - const communication = this._toDispose.add(new ExtHostNamedPipeCommunication(this._logService)); - return this._startWithCommunication(communication); - } - } -} - -interface INamedPipePreparedData { - pipeName: string; - namedPipeServer: Server; -} - -class ExtHostNamedPipeCommunication extends Disposable implements IExtHostCommunication { - - readonly useUtilityProcess = false; - - constructor( - @ILogService private readonly _logService: ILogService - ) { - super(); - } - - prepare(): Promise { - return new Promise<{ pipeName: string; namedPipeServer: Server }>((resolve, reject) => { - const pipeName = createRandomIPCHandle(); - - const namedPipeServer = createServer(); - namedPipeServer.on('error', reject); - namedPipeServer.listen(pipeName, () => { - namedPipeServer?.removeListener('error', reject); - resolve({ pipeName, namedPipeServer }); - }); - this._register(toDisposable(() => { - if (namedPipeServer.listening) { - namedPipeServer.close(); - } - })); - }); - } - - establishProtocol(prepared: INamedPipePreparedData, extensionHostProcess: ExtensionHostProcess, opts: IExtensionHostProcessOptions): Promise { - const { namedPipeServer, pipeName } = prepared; - - writeExtHostConnection(new IPCExtHostConnection(pipeName), opts.env); - - return new Promise((resolve, reject) => { - - // Wait for the extension host to connect to our named pipe - // and wrap the socket in the message passing protocol - const handle = setTimeout(() => { - if (namedPipeServer.listening) { - namedPipeServer.close(); - } - reject('The local extension host took longer than 60s to connect.'); - }, 60 * 1000); - - namedPipeServer.on('connection', (socket) => { - - clearTimeout(handle); - if (namedPipeServer.listening) { - namedPipeServer.close(); - } - - const nodeSocket = new NodeSocket(socket, 'renderer-exthost'); - const protocol = new PersistentProtocol(nodeSocket); - - this._register(toDisposable(() => { - // Send the extension host a request to terminate itself - // (graceful termination) - protocol.send(createMessageOfType(MessageType.Terminate)); - protocol.flush(); - - socket.end(); - nodeSocket.dispose(); - protocol.dispose(); - })); - - resolve(protocol); - }); - - // Now that the named pipe listener is installed, start the ext host process - const sw = StopWatch.create(false); - extensionHostProcess.start(opts).then(() => { - const duration = sw.elapsed(); - if (platform.isCI) { - this._logService.info(`IExtensionHostStarter.start() took ${duration} ms.`); - } - }, (err) => { - // Starting the ext host process resulted in an error - reject(err); - }); - - }); - } -} diff --git a/src/vs/workbench/services/extensions/electron-sandbox/nativeLocalProcessExtensionHost.ts b/src/vs/workbench/services/extensions/electron-sandbox/nativeLocalProcessExtensionHost.ts new file mode 100644 index 00000000000..35d0657b669 --- /dev/null +++ b/src/vs/workbench/services/extensions/electron-sandbox/nativeLocalProcessExtensionHost.ts @@ -0,0 +1,123 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +/* eslint-disable code-import-patterns */ +/* eslint-disable code-layering */ + +import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; +import * as platform from 'vs/base/common/platform'; +import { StopWatch } from 'vs/base/common/stopwatch'; +import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; +import { PersistentProtocol } from 'vs/base/parts/ipc/common/ipc.net'; +import { createRandomIPCHandle, NodeSocket } from 'vs/base/parts/ipc/node/ipc.net'; +import { IExtensionHostProcessOptions } from 'vs/platform/extensions/common/extensionHostStarter'; +import { ILogService } from 'vs/platform/log/common/log'; +import { IPCExtHostConnection, writeExtHostConnection } from 'vs/workbench/services/extensions/common/extensionHostEnv'; +import { createMessageOfType, MessageType } from 'vs/workbench/services/extensions/common/extensionHostProtocol'; +import { ExtensionHostProcess, ExtHostMessagePortCommunication, IExtHostCommunication, SandboxLocalProcessExtensionHost } from 'vs/workbench/services/extensions/electron-sandbox/localProcessExtensionHost'; +import { process } from 'vs/base/parts/sandbox/electron-sandbox/globals'; + +export class NativeLocalProcessExtensionHost extends SandboxLocalProcessExtensionHost { + protected override async _start(): Promise { + const canUseUtilityProcess = await this._extensionHostStarter.canUseUtilityProcess(); + if (canUseUtilityProcess && (this._configurationService.getValue('extensions.experimental.useUtilityProcess') || process.sandboxed)) { + const communication = this._toDispose.add(new ExtHostMessagePortCommunication(this._logService)); + return this._startWithCommunication(communication); + } else { + const communication = this._toDispose.add(new ExtHostNamedPipeCommunication(this._logService)); + return this._startWithCommunication(communication); + } + } +} + +interface INamedPipePreparedData { + pipeName: string; + namedPipeServer: import('net').Server; +} + +class ExtHostNamedPipeCommunication extends Disposable implements IExtHostCommunication { + + readonly useUtilityProcess = false; + + constructor( + @ILogService private readonly _logService: ILogService + ) { + super(); + } + + async prepare(): Promise { + const { createServer } = await import('net'); + return new Promise<{ pipeName: string; namedPipeServer: import('net').Server }>((resolve, reject) => { + const pipeName = createRandomIPCHandle(); + + const namedPipeServer = createServer(); + namedPipeServer.on('error', reject); + namedPipeServer.listen(pipeName, () => { + namedPipeServer?.removeListener('error', reject); + resolve({ pipeName, namedPipeServer }); + }); + this._register(toDisposable(() => { + if (namedPipeServer.listening) { + namedPipeServer.close(); + } + })); + }); + } + + establishProtocol(prepared: INamedPipePreparedData, extensionHostProcess: ExtensionHostProcess, opts: IExtensionHostProcessOptions): Promise { + const { namedPipeServer, pipeName } = prepared; + + writeExtHostConnection(new IPCExtHostConnection(pipeName), opts.env); + + return new Promise((resolve, reject) => { + + // Wait for the extension host to connect to our named pipe + // and wrap the socket in the message passing protocol + const handle = setTimeout(() => { + if (namedPipeServer.listening) { + namedPipeServer.close(); + } + reject('The local extension host took longer than 60s to connect.'); + }, 60 * 1000); + + namedPipeServer.on('connection', (socket) => { + + clearTimeout(handle); + if (namedPipeServer.listening) { + namedPipeServer.close(); + } + + const nodeSocket = new NodeSocket(socket, 'renderer-exthost'); + const protocol = new PersistentProtocol(nodeSocket); + + this._register(toDisposable(() => { + // Send the extension host a request to terminate itself + // (graceful termination) + protocol.send(createMessageOfType(MessageType.Terminate)); + protocol.flush(); + + socket.end(); + nodeSocket.dispose(); + protocol.dispose(); + })); + + resolve(protocol); + }); + + // Now that the named pipe listener is installed, start the ext host process + const sw = StopWatch.create(false); + extensionHostProcess.start(opts).then(() => { + const duration = sw.elapsed(); + if (platform.isCI) { + this._logService.info(`IExtensionHostStarter.start() took ${duration} ms.`); + } + }, (err) => { + // Starting the ext host process resulted in an error + reject(err); + }); + + }); + } +} diff --git a/src/vs/workbench/services/extensions/electron-sandbox/sandboxExtensionService.ts b/src/vs/workbench/services/extensions/electron-sandbox/sandboxExtensionService.ts index ea51d7abc8f..58e5c5bf71c 100644 --- a/src/vs/workbench/services/extensions/electron-sandbox/sandboxExtensionService.ts +++ b/src/vs/workbench/services/extensions/electron-sandbox/sandboxExtensionService.ts @@ -4,10 +4,19 @@ *--------------------------------------------------------------------------------------------*/ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { ExtensionHostKind, ExtensionRunningLocation, IExtensionHost, IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ElectronExtensionService } from 'vs/workbench/services/extensions/electron-sandbox/electronExtensionService'; +import { NativeLocalProcessExtensionHost } from 'vs/workbench/services/extensions/electron-sandbox/nativeLocalProcessExtensionHost'; +import { process } from 'vs/base/parts/sandbox/electron-sandbox/globals'; export class SandboxExtensionService extends ElectronExtensionService { + protected override _createExtensionHost(runningLocation: ExtensionRunningLocation, isInitialStart: boolean): IExtensionHost | null { + if (!process.sandboxed && runningLocation.kind === ExtensionHostKind.LocalProcess) { + // TODO@bpasero remove me once electron utility process has landed + return this._instantiationService.createInstance(NativeLocalProcessExtensionHost, runningLocation, this._createLocalExtensionHostDataProvider(isInitialStart, runningLocation)); + } + return super._createExtensionHost(runningLocation, isInitialStart); + } } registerSingleton(IExtensionService, SandboxExtensionService); diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index 6b7b44d4155..8831bf9469b 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -4,51 +4,157 @@ *--------------------------------------------------------------------------------------------*/ -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -// -// NOTE: Please do NOT register services here. Use `registerSingleton()` -// from `workbench.common.main.ts` if the service is shared between -// desktop and web or `workbench.sandbox.main.ts` if the service -// is desktop only. -// -// The `node` & `electron-browser` layer is deprecated for workbench! -// -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// ####################################################################### +// ### ### +// ### !!! PLEASE ADD COMMON IMPORTS INTO WORKBENCH.COMMON.MAIN.TS !!! ### +// ### ### +// ####################################################################### +//#region --- workbench common -//#region --- workbench common & sandbox +import 'vs/workbench/workbench.common.main'; -import 'vs/workbench/workbench.sandbox.main'; +//#endregion + + +//#region --- workbench (desktop main) + +import 'vs/workbench/electron-sandbox/desktop.main'; +import 'vs/workbench/electron-sandbox/desktop.contribution'; + +//#endregion + + +//#region --- workbench parts + +import 'vs/workbench/electron-sandbox/parts/dialogs/dialog.contribution'; //#endregion //#region --- workbench services +import 'vs/workbench/services/textfile/electron-sandbox/nativeTextFileService'; +import 'vs/workbench/services/dialogs/electron-sandbox/fileDialogService'; +import 'vs/workbench/services/workspaces/electron-sandbox/workspacesService'; +import 'vs/workbench/services/textMate/browser/nativeTextMateService'; +import 'vs/workbench/services/menubar/electron-sandbox/menubarService'; +import 'vs/workbench/services/issue/electron-sandbox/issueService'; +import 'vs/workbench/services/update/electron-sandbox/updateService'; +import 'vs/workbench/services/url/electron-sandbox/urlService'; +import 'vs/workbench/services/lifecycle/electron-sandbox/lifecycleService'; +import 'vs/workbench/services/title/electron-sandbox/titleService'; +import 'vs/workbench/services/host/electron-sandbox/nativeHostService'; +import 'vs/workbench/services/request/electron-sandbox/requestService'; +import 'vs/workbench/services/extensionResourceLoader/electron-sandbox/extensionResourceLoaderService'; +import 'vs/workbench/services/clipboard/electron-sandbox/clipboardService'; +import 'vs/workbench/services/contextmenu/electron-sandbox/contextmenuService'; +import 'vs/workbench/services/workspaces/electron-sandbox/workspaceEditingService'; +import 'vs/workbench/services/configurationResolver/electron-sandbox/configurationResolverService'; +import 'vs/workbench/services/accessibility/electron-sandbox/accessibilityService'; +import 'vs/workbench/services/path/electron-sandbox/pathService'; +import 'vs/workbench/services/themes/electron-sandbox/nativeHostColorSchemeService'; +import 'vs/workbench/services/extensionManagement/electron-sandbox/extensionManagementService'; +import 'vs/workbench/services/extensionManagement/electron-sandbox/extensionUrlTrustService'; +import 'vs/workbench/services/credentials/electron-sandbox/credentialsService'; +import 'vs/workbench/services/encryption/electron-sandbox/encryptionService'; +import 'vs/workbench/services/localization/electron-sandbox/languagePackService'; +import 'vs/workbench/services/telemetry/electron-sandbox/telemetryService'; +import 'vs/workbench/services/extensions/electron-sandbox/extensionHostStarter'; +import 'vs/platform/extensionManagement/electron-sandbox/extensionsScannerService'; +import 'vs/workbench/services/extensionManagement/electron-sandbox/extensionManagementServerService'; +import 'vs/workbench/services/extensionManagement/electron-sandbox/extensionTipsService'; +import 'vs/workbench/services/userDataSync/electron-sandbox/userDataSyncMachinesService'; +import 'vs/workbench/services/userDataSync/electron-sandbox/userDataSyncService'; +import 'vs/workbench/services/userDataSync/electron-sandbox/userDataSyncAccountService'; +import 'vs/workbench/services/userDataSync/electron-sandbox/userDataSyncStoreManagementService'; +import 'vs/workbench/services/userDataSync/electron-sandbox/userDataAutoSyncService'; +import 'vs/workbench/services/timer/electron-sandbox/timerService'; +import 'vs/workbench/services/environment/electron-sandbox/shellEnvironmentService'; +import 'vs/workbench/services/integrity/electron-sandbox/integrityService'; +import 'vs/workbench/services/workingCopy/electron-sandbox/workingCopyBackupService'; +import 'vs/workbench/services/checksum/electron-sandbox/checksumService'; +import 'vs/platform/remote/electron-sandbox/sharedProcessTunnelService'; +import 'vs/workbench/services/tunnel/electron-sandbox/tunnelService'; +import 'vs/platform/diagnostics/electron-sandbox/diagnosticsService'; +import 'vs/platform/profiling/electron-sandbox/profilingService'; +import 'vs/platform/telemetry/electron-sandbox/customEndpointTelemetryService'; +import 'vs/workbench/services/files/electron-sandbox/elevatedFileService'; +import 'vs/workbench/services/search/electron-sandbox/searchService'; +import 'vs/workbench/services/workingCopy/electron-sandbox/workingCopyHistoryService'; +import 'vs/workbench/services/userDataSync/browser/userDataSyncEnablementService'; +import 'vs/workbench/services/extensions/electron-sandbox/sandboxExtensionService'; + +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IUserDataInitializationService, UserDataInitializationService } from 'vs/workbench/services/userData/browser/userDataInit'; + +registerSingleton(IUserDataInitializationService, UserDataInitializationService); + +//#endregion + + +//#region --- workbench contributions + +// Logs +import 'vs/workbench/contrib/logs/electron-sandbox/logs.contribution'; + +// Localizations +import 'vs/workbench/contrib/localization/electron-sandbox/localization.contribution'; + +// Explorer +import 'vs/workbench/contrib/files/electron-sandbox/files.contribution'; +import 'vs/workbench/contrib/files/electron-sandbox/fileActions.contribution'; + +// CodeEditor Contributions +import 'vs/workbench/contrib/codeEditor/electron-sandbox/codeEditor.contribution'; + +// Debug +import 'vs/workbench/contrib/debug/electron-sandbox/extensionHostDebugService'; + +// Extensions Management +import 'vs/workbench/contrib/extensions/electron-sandbox/extensions.contribution'; + +// Issues +import 'vs/workbench/contrib/issue/electron-sandbox/issue.contribution'; + +// Remote +import 'vs/workbench/contrib/remote/electron-sandbox/remote.contribution'; + +// Configuration Exporter +import 'vs/workbench/contrib/configExporter/electron-sandbox/configurationExportHelper.contribution'; + +// Terminal +import 'vs/workbench/contrib/terminal/electron-sandbox/terminal.contribution'; + +// Themes Support +import 'vs/workbench/contrib/themes/browser/themes.test.contribution'; + +// User Data Sync +import 'vs/workbench/contrib/userDataSync/electron-sandbox/userDataSync.contribution'; + +// Output +import 'vs/workbench/contrib/output/electron-sandbox/outputChannelModelService'; + +// Tags +import 'vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService'; +import 'vs/workbench/contrib/tags/electron-sandbox/tags.contribution'; + +// Performance +import 'vs/workbench/contrib/performance/electron-sandbox/performance.contribution'; + +// Tasks +import 'vs/workbench/contrib/tasks/electron-sandbox/taskService'; + +// External terminal +import 'vs/workbench/contrib/externalTerminal/electron-sandbox/externalTerminal.contribution'; + +// Webview +import 'vs/workbench/contrib/webview/electron-sandbox/webview.contribution'; -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -// -// NOTE: Please do NOT register services here. Use `registerSingleton()` -// from `workbench.common.main.ts` if the service is shared between -// desktop and web or `workbench.sandbox.main.ts` if the service -// is desktop only. -// -// The `node` & `electron-browser` layer is deprecated for workbench! -// -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -import 'vs/workbench/services/extensions/electron-browser/nativeExtensionService'; - -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -// -// NOTE: Please do NOT register services here. Use `registerSingleton()` -// from `workbench.common.main.ts` if the service is shared between -// desktop and web or `workbench.sandbox.main.ts` if the service -// is desktop only. -// -// The `node` & `electron-browser` layer is deprecated for workbench! -// -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// Splash +import 'vs/workbench/contrib/splash/electron-sandbox/splash.contribution'; +// Local History +import 'vs/workbench/contrib/localHistory/electron-sandbox/localHistory.contribution'; //#endregion diff --git a/src/vs/workbench/workbench.desktop.sandbox.main.ts b/src/vs/workbench/workbench.desktop.sandbox.main.ts deleted file mode 100644 index 894e6785212..00000000000 --- a/src/vs/workbench/workbench.desktop.sandbox.main.ts +++ /dev/null @@ -1,32 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - - -// ####################################################################### -// ### ### -// ### !!! PLEASE ADD COMMON IMPORTS INTO WORKBENCH.COMMON.MAIN.TS !!! ### -// ### ### -// ####################################################################### - - -//#region --- workbench common & sandbox - -import 'vs/workbench/workbench.sandbox.main'; - -//#endregion - - -//#region --- workbench (desktop main) - -import 'vs/workbench/electron-sandbox/desktop.main'; - -//#endregion - - -//#region --- workbench services - -import 'vs/workbench/services/extensions/electron-sandbox/sandboxExtensionService'; - -//#endregion diff --git a/src/vs/workbench/workbench.sandbox.main.ts b/src/vs/workbench/workbench.sandbox.main.ts deleted file mode 100644 index dd9ddd715b1..00000000000 --- a/src/vs/workbench/workbench.sandbox.main.ts +++ /dev/null @@ -1,159 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - - -// ####################################################################### -// ### ### -// ### !!! PLEASE ADD COMMON IMPORTS INTO WORKBENCH.COMMON.MAIN.TS !!! ### -// ### ### -// ####################################################################### - -//#region --- workbench common - -import 'vs/workbench/workbench.common.main'; - -//#endregion - - -//#region --- workbench (desktop main) - -import 'vs/workbench/electron-sandbox/desktop.main'; -import 'vs/workbench/electron-sandbox/desktop.contribution'; - -//#endregion - - -//#region --- workbench parts - -import 'vs/workbench/electron-sandbox/parts/dialogs/dialog.contribution'; - -//#endregion - - -//#region --- workbench services - -import 'vs/workbench/services/textfile/electron-sandbox/nativeTextFileService'; -import 'vs/workbench/services/dialogs/electron-sandbox/fileDialogService'; -import 'vs/workbench/services/workspaces/electron-sandbox/workspacesService'; -import 'vs/workbench/services/textMate/browser/nativeTextMateService'; -import 'vs/workbench/services/menubar/electron-sandbox/menubarService'; -import 'vs/workbench/services/issue/electron-sandbox/issueService'; -import 'vs/workbench/services/update/electron-sandbox/updateService'; -import 'vs/workbench/services/url/electron-sandbox/urlService'; -import 'vs/workbench/services/lifecycle/electron-sandbox/lifecycleService'; -import 'vs/workbench/services/title/electron-sandbox/titleService'; -import 'vs/workbench/services/host/electron-sandbox/nativeHostService'; -import 'vs/workbench/services/request/electron-sandbox/requestService'; -import 'vs/workbench/services/extensionResourceLoader/electron-sandbox/extensionResourceLoaderService'; -import 'vs/workbench/services/clipboard/electron-sandbox/clipboardService'; -import 'vs/workbench/services/contextmenu/electron-sandbox/contextmenuService'; -import 'vs/workbench/services/workspaces/electron-sandbox/workspaceEditingService'; -import 'vs/workbench/services/configurationResolver/electron-sandbox/configurationResolverService'; -import 'vs/workbench/services/accessibility/electron-sandbox/accessibilityService'; -import 'vs/workbench/services/path/electron-sandbox/pathService'; -import 'vs/workbench/services/themes/electron-sandbox/nativeHostColorSchemeService'; -import 'vs/workbench/services/extensionManagement/electron-sandbox/extensionManagementService'; -import 'vs/workbench/services/extensionManagement/electron-sandbox/extensionUrlTrustService'; -import 'vs/workbench/services/credentials/electron-sandbox/credentialsService'; -import 'vs/workbench/services/encryption/electron-sandbox/encryptionService'; -import 'vs/workbench/services/localization/electron-sandbox/languagePackService'; -import 'vs/workbench/services/telemetry/electron-sandbox/telemetryService'; -import 'vs/workbench/services/extensions/electron-sandbox/extensionHostStarter'; -import 'vs/platform/extensionManagement/electron-sandbox/extensionsScannerService'; -import 'vs/workbench/services/extensionManagement/electron-sandbox/extensionManagementServerService'; -import 'vs/workbench/services/extensionManagement/electron-sandbox/extensionTipsService'; -import 'vs/workbench/services/userDataSync/electron-sandbox/userDataSyncMachinesService'; -import 'vs/workbench/services/userDataSync/electron-sandbox/userDataSyncService'; -import 'vs/workbench/services/userDataSync/electron-sandbox/userDataSyncAccountService'; -import 'vs/workbench/services/userDataSync/electron-sandbox/userDataSyncStoreManagementService'; -import 'vs/workbench/services/userDataSync/electron-sandbox/userDataAutoSyncService'; -import 'vs/workbench/services/timer/electron-sandbox/timerService'; -import 'vs/workbench/services/environment/electron-sandbox/shellEnvironmentService'; -import 'vs/workbench/services/integrity/electron-sandbox/integrityService'; -import 'vs/workbench/services/workingCopy/electron-sandbox/workingCopyBackupService'; -import 'vs/workbench/services/checksum/electron-sandbox/checksumService'; -import 'vs/platform/remote/electron-sandbox/sharedProcessTunnelService'; -import 'vs/workbench/services/tunnel/electron-sandbox/tunnelService'; -import 'vs/platform/diagnostics/electron-sandbox/diagnosticsService'; -import 'vs/platform/profiling/electron-sandbox/profilingService'; -import 'vs/platform/telemetry/electron-sandbox/customEndpointTelemetryService'; -import 'vs/workbench/services/files/electron-sandbox/elevatedFileService'; -import 'vs/workbench/services/search/electron-sandbox/searchService'; -import 'vs/workbench/services/workingCopy/electron-sandbox/workingCopyHistoryService'; -import 'vs/workbench/services/userDataSync/browser/userDataSyncEnablementService'; - -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IUserDataInitializationService, UserDataInitializationService } from 'vs/workbench/services/userData/browser/userDataInit'; - -registerSingleton(IUserDataInitializationService, UserDataInitializationService); - -//#endregion - - -//#region --- workbench contributions - -// Logs -import 'vs/workbench/contrib/logs/electron-sandbox/logs.contribution'; - -// Localizations -import 'vs/workbench/contrib/localization/electron-sandbox/localization.contribution'; - -// Explorer -import 'vs/workbench/contrib/files/electron-sandbox/files.contribution'; -import 'vs/workbench/contrib/files/electron-sandbox/fileActions.contribution'; - -// CodeEditor Contributions -import 'vs/workbench/contrib/codeEditor/electron-sandbox/codeEditor.contribution'; - -// Debug -import 'vs/workbench/contrib/debug/electron-sandbox/extensionHostDebugService'; - -// Extensions Management -import 'vs/workbench/contrib/extensions/electron-sandbox/extensions.contribution'; - -// Issues -import 'vs/workbench/contrib/issue/electron-sandbox/issue.contribution'; - -// Remote -import 'vs/workbench/contrib/remote/electron-sandbox/remote.contribution'; - -// Configuration Exporter -import 'vs/workbench/contrib/configExporter/electron-sandbox/configurationExportHelper.contribution'; - -// Terminal -import 'vs/workbench/contrib/terminal/electron-sandbox/terminal.contribution'; - -// Themes Support -import 'vs/workbench/contrib/themes/browser/themes.test.contribution'; - -// User Data Sync -import 'vs/workbench/contrib/userDataSync/electron-sandbox/userDataSync.contribution'; - -// Output -import 'vs/workbench/contrib/output/electron-sandbox/outputChannelModelService'; - -// Tags -import 'vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService'; -import 'vs/workbench/contrib/tags/electron-sandbox/tags.contribution'; - -// Performance -import 'vs/workbench/contrib/performance/electron-sandbox/performance.contribution'; - -// Tasks -import 'vs/workbench/contrib/tasks/electron-sandbox/taskService'; - -// External terminal -import 'vs/workbench/contrib/externalTerminal/electron-sandbox/externalTerminal.contribution'; - -// Webview -import 'vs/workbench/contrib/webview/electron-sandbox/webview.contribution'; - -// Splash -import 'vs/workbench/contrib/splash/electron-sandbox/splash.contribution'; - -// Local History -import 'vs/workbench/contrib/localHistory/electron-sandbox/localHistory.contribution'; - -//#endregion -- cgit v1.2.3 From a365f655a84e10f1377151bc2ea230e5d1037cc7 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 5 Jul 2022 11:33:56 +0200 Subject: Fix #151370 (#154144) --- .../platform/extensionManagement/common/extensionsScannerService.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/platform/extensionManagement/common/extensionsScannerService.ts b/src/vs/platform/extensionManagement/common/extensionsScannerService.ts index 29a0264d9cc..e166e75fd6e 100644 --- a/src/vs/platform/extensionManagement/common/extensionsScannerService.ts +++ b/src/vs/platform/extensionManagement/common/extensionsScannerService.ts @@ -512,7 +512,9 @@ class ExtensionsScanner extends Disposable { const extensionScannerInput = new ExtensionScannerInput(c.resource, input.mtime, input.applicationExtensionslocation, input.applicationExtensionslocationMtime, input.profile, input.type, input.excludeObsolete, input.validate, input.productVersion, input.productDate, input.productCommit, input.devMode, input.language, input.translations); return this.scanExtension(extensionScannerInput); })); - return coalesce(extensions); + return coalesce(extensions) + // Sort: Make sure extensions are in the same order always. Helps cache invalidation even if the order changes. + .sort((a, b) => a.location.path < b.location.path ? -1 : 1); } private async scanExtensionsFromProfile(input: ExtensionScannerInput): Promise { -- cgit v1.2.3 From d508c2c2e439995a557e98d30f4748c6155ac794 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 5 Jul 2022 11:54:31 +0200 Subject: Improves observable name. --- .../workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts b/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts index 6bf21e30d44..06a3dcbf827 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts @@ -62,7 +62,7 @@ export class MergeEditorModel extends EditorModel { private readonly modifiedBaseRangeStateStores = derived('modifiedBaseRangeStateStores', reader => { const map = new Map( - this.modifiedBaseRanges.read(reader).map(s => ([s, observableValue('State', ModifiedBaseRangeState.default)])) + this.modifiedBaseRanges.read(reader).map(s => ([s, observableValue(`BaseRangeState${s.baseRange}`, ModifiedBaseRangeState.default)])) ); return map; }); @@ -70,7 +70,7 @@ export class MergeEditorModel extends EditorModel { private readonly modifiedBaseRangeHandlingStateStores = derived('modifiedBaseRangeHandlingStateStores', reader => { const map = new Map( - this.modifiedBaseRanges.read(reader).map(s => ([s, observableValue('State', false)])) + this.modifiedBaseRanges.read(reader).map(s => ([s, observableValue(`BaseRangeHandledState${s.baseRange}`, false)])) ); return map; }); -- cgit v1.2.3 From c86b009309aaca9ab18d977df578949cac16bcec Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 5 Jul 2022 12:48:45 +0200 Subject: Fixes merge editor bug, improves testing infrastructure and adds test. --- .../mergeEditor/browser/commands/commands.ts | 28 +++++ .../mergeEditor/browser/commands/devCommands.ts | 9 +- .../browser/mergeEditor.contribution.ts | 3 +- .../mergeEditor/browser/mergeEditorInput.ts | 3 + .../mergeEditor/browser/model/mergeEditorModel.ts | 9 +- .../mergeEditor/browser/model/modifiedBaseRange.ts | 18 ++- .../contrib/mergeEditor/test/browser/model.test.ts | 132 ++++++++++++++++++--- 7 files changed, 172 insertions(+), 30 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts b/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts index 7e100501342..892febf378e 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts @@ -10,6 +10,7 @@ import { ILocalizedString } from 'vs/platform/action/common/action'; import { Action2, MenuId } from 'vs/platform/actions/common/actions'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; import { API_OPEN_DIFF_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands'; import { MergeEditorInput, MergeEditorInputData } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput'; import { MergeEditor } from 'vs/workbench/contrib/mergeEditor/browser/view/mergeEditor'; @@ -350,3 +351,30 @@ function mergeEditorCompare(editorService: IEditorService, commandService: IComm function openDiffEditor(commandService: ICommandService, left: URI, right: URI, label?: string) { commandService.executeCommand(API_OPEN_DIFF_EDITOR_COMMAND_ID, left, right, label); } + +export class OpenBaseFile extends Action2 { + constructor() { + super({ + id: 'merge.openBaseEditor', + category: mergeEditorCategory, + title: { + value: localize('merge.openBaseEditor', 'Open Base File'), + original: 'Open Base File', + }, + f1: true, + precondition: ctxIsMergeEditor, + }); + } + + run(accessor: ServicesAccessor): void { + const openerService = accessor.get(IOpenerService); + const { activeEditorPane } = accessor.get(IEditorService); + if (activeEditorPane instanceof MergeEditor) { + const vm = activeEditorPane.viewModel.get(); + if (!vm) { + return; + } + openerService.open(vm.model.base.uri); + } + } +} diff --git a/src/vs/workbench/contrib/mergeEditor/browser/commands/devCommands.ts b/src/vs/workbench/contrib/mergeEditor/browser/commands/devCommands.ts index aaf15c771da..6728dc93b1a 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/commands/devCommands.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/commands/devCommands.ts @@ -29,7 +29,6 @@ interface MergeEditorContents { } export class MergeEditorCopyContentsToJSON extends Action2 { - constructor() { super({ id: 'merge.dev.copyContents', @@ -81,7 +80,6 @@ export class MergeEditorCopyContentsToJSON extends Action2 { } export class MergeEditorOpenContents extends Action2 { - constructor() { super({ id: 'merge.dev.openContents', @@ -110,11 +108,14 @@ export class MergeEditorOpenContents extends Action2 { prompt: localize('mergeEditor.enterJSON', 'Enter JSON'), value: await clipboardService.readText(), }); - if (!result) { + if (result === undefined) { return; } - const content: MergeEditorContents = JSON.parse(result); + const content: MergeEditorContents = + result !== '' + ? JSON.parse(result) + : { base: '', input1: '', input2: '', result: '', languageId: 'plaintext' }; const scheme = 'merge-editor-dev'; diff --git a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution.ts b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution.ts index 136249c41fa..8dc07e6463f 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution.ts @@ -9,7 +9,7 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { Registry } from 'vs/platform/registry/common/platform'; import { EditorPaneDescriptor, IEditorPaneRegistry } from 'vs/workbench/browser/editor'; import { EditorExtensions, IEditorFactoryRegistry } from 'vs/workbench/common/editor'; -import { CompareInput1WithBaseCommand, CompareInput2WithBaseCommand, GoToNextConflict, GoToPreviousConflict, OpenMergeEditor, ToggleActiveConflictInput1, ToggleActiveConflictInput2, SetColumnLayout, SetMixedLayout } from 'vs/workbench/contrib/mergeEditor/browser/commands/commands'; +import { CompareInput1WithBaseCommand, CompareInput2WithBaseCommand, GoToNextConflict, GoToPreviousConflict, OpenMergeEditor, ToggleActiveConflictInput1, ToggleActiveConflictInput2, SetColumnLayout, SetMixedLayout, OpenBaseFile } from 'vs/workbench/contrib/mergeEditor/browser/commands/commands'; import { MergeEditorCopyContentsToJSON, MergeEditorOpenContents } from 'vs/workbench/contrib/mergeEditor/browser/commands/devCommands'; import { MergeEditorInput } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput'; import { MergeEditor } from 'vs/workbench/contrib/mergeEditor/browser/view/mergeEditor'; @@ -34,6 +34,7 @@ Registry.as(EditorExtensions.EditorFactory).registerEdit registerAction2(SetMixedLayout); registerAction2(SetColumnLayout); registerAction2(OpenMergeEditor); +registerAction2(OpenBaseFile); registerAction2(MergeEditorCopyContentsToJSON); registerAction2(MergeEditorOpenContents); diff --git a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts index 660d10cb487..053c7309754 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts @@ -113,6 +113,9 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements this.input2.description, result.object.textEditorModel, this._instaService.createInstance(EditorWorkerServiceDiffComputer), + { + resetUnknownOnInitialization: true + }, ); await this._model.onInitialized; diff --git a/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts b/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts index 06a3dcbf827..255615448d3 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts @@ -134,6 +134,7 @@ export class MergeEditorModel extends EditorModel { readonly input2Description: string | undefined, readonly result: ITextModel, private readonly diffComputer: IDiffComputer, + options: { resetUnknownOnInitialization: boolean }, @IModelService private readonly modelService: IModelService, @ILanguageService private readonly languageService: ILanguageService, ) { @@ -183,9 +184,11 @@ export class MergeEditorModel extends EditorModel { ) ); - this.onInitialized.then(() => { - this.resetUnknown(); - }); + if (options.resetUnknownOnInitialization) { + this.onInitialized.then(() => { + this.resetUnknown(); + }); + } } public getRangeInResult(baseRange: LineRange, reader?: IReader): LineRange { diff --git a/src/vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange.ts b/src/vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange.ts index 028b9afe986..2e6b6031382 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange.ts @@ -281,21 +281,29 @@ export class ModifiedBaseRangeState { } public toString(): string { - const arr: ('1' | '2')[] = []; + const arr: string[] = []; if (this.input1) { - arr.push('1'); + arr.push('1✓'); } if (this.input2) { - arr.push('2'); + arr.push('2✓'); } if (this.input2First) { arr.reverse(); } + if (this.conflicting) { + arr.push('conflicting'); + } return arr.join(','); } - equals(newState: ModifiedBaseRangeState): boolean { - return this.input1 === newState.input1 && this.input2 === newState.input2 && this.input2First === newState.input2First; + equals(other: ModifiedBaseRangeState): boolean { + return ( + this.input1 === other.input1 && + this.input2 === other.input2 && + this.input2First === other.input2First && + this.conflicting === other.conflicting + ); } } diff --git a/src/vs/workbench/contrib/mergeEditor/test/browser/model.test.ts b/src/vs/workbench/contrib/mergeEditor/test/browser/model.test.ts index ea1a9794545..ebef4581ab6 100644 --- a/src/vs/workbench/contrib/mergeEditor/test/browser/model.test.ts +++ b/src/vs/workbench/contrib/mergeEditor/test/browser/model.test.ts @@ -8,7 +8,7 @@ import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { transaction } from 'vs/base/common/observable'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { Range } from 'vs/editor/common/core/range'; -import { ITextModel } from 'vs/editor/common/model'; +import { EndOfLinePreference, ITextModel } from 'vs/editor/common/model'; import { EditorSimpleWorker } from 'vs/editor/common/services/editorSimpleWorker'; import { createModelServices, createTextModel } from 'vs/editor/test/common/testTextModel'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -29,9 +29,10 @@ suite('merge editor model', () => { }, model => { assert.deepStrictEqual(model.getProjections(), { - base: '⟦⟧₀line1\nline2', - input1: '⟦0\n⟧₀line1\nline2', - input2: '⟦0\n⟧₀line1\nline2', + base: ['⟦⟧₀line1', 'line2'], + input1: ['⟦0', '⟧₀line1', 'line2'], + input2: ['⟦0', '⟧₀line1', 'line2'], + result: ['⟦⟧{conflicting}₀'], }); model.toggleConflict(0, 1); @@ -59,7 +60,12 @@ suite('merge editor model', () => { "result": "" }, model => { - assert.deepStrictEqual(model.getProjections(), ({ base: "⟦⟧₀", input1: "⟦input1⟧₀", input2: "⟦input2⟧₀" })); + assert.deepStrictEqual(model.getProjections(), { + base: ['⟦⟧₀'], + input1: ['⟦input1⟧₀'], + input2: ['⟦input2⟧₀'], + result: ['⟦⟧{}₀'], + }); model.toggleConflict(0, 1); assert.deepStrictEqual( @@ -87,9 +93,10 @@ suite('merge editor model', () => { }, model => { assert.deepStrictEqual(model.getProjections(), { - base: '⟦hello⟧₀', - input1: '⟦hallo⟧₀', - input2: '⟦helloworld⟧₀', + base: ['⟦hello⟧₀'], + input1: ['⟦hallo⟧₀'], + input2: ['⟦helloworld⟧₀'], + result: ['⟦⟧{conflicting}₀'], }); model.toggleConflict(0, 1); @@ -115,11 +122,34 @@ suite('merge editor model', () => { }, model => { assert.deepStrictEqual(model.getProjections(), { - base: 'Zürich\nBern\n⟦Basel\n⟧₀Chur\n⟦⟧₁Genf\nThun⟦⟧₂', - input1: - 'Zürich\nBern\n⟦⟧₀Chur\n⟦Davos\n⟧₁Genf\nThun\n⟦function f(b:boolean) {}⟧₂', - input2: - 'Zürich\nBern\n⟦Basel (FCB)\n⟧₀Chur\n⟦⟧₁Genf\nThun\n⟦function f(a:number) {}⟧₂', + base: ['Zürich', 'Bern', '⟦Basel', '⟧₀Chur', '⟦⟧₁Genf', 'Thun⟦⟧₂'], + input1: [ + 'Zürich', + 'Bern', + '⟦⟧₀Chur', + '⟦Davos', + '⟧₁Genf', + 'Thun', + '⟦function f(b:boolean) {}⟧₂', + ], + input2: [ + 'Zürich', + 'Bern', + '⟦Basel (FCB)', + '⟧₀Chur', + '⟦⟧₁Genf', + 'Thun', + '⟦function f(a:number) {}⟧₂', + ], + result: [ + 'Zürich', + 'Bern', + '⟦Basel', + '⟧{}₀Chur', + '⟦Davos', + '⟧{1✓}₁Genf', + 'Thun⟦⟧{}₂', + ], }); model.toggleConflict(2, 1); @@ -135,6 +165,61 @@ suite('merge editor model', () => { } ); }); + + test('conflicts are reset', async () => { + await testMergeModel( + { + "languageId": "typescript", + "base": "import { h } from 'vs/base/browser/dom';\nimport { Disposable, IDisposable } from 'vs/base/common/lifecycle';\nimport { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';\nimport { EditorOption } from 'vs/editor/common/config/editorOptions';\nimport { autorun, IReader, observableFromEvent, ObservableValue } from 'vs/workbench/contrib/audioCues/browser/observable';\nimport { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange';\n", + "input1": "import { h } from 'vs/base/browser/dom';\nimport { Disposable, IDisposable } from 'vs/base/common/lifecycle';\nimport { observableSignalFromEvent } from 'vs/base/common/observable';\nimport { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';\nimport { autorun, IReader, observableFromEvent } from 'vs/workbench/contrib/audioCues/browser/observable';\nimport { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange';\n", + "input2": "import { h } from 'vs/base/browser/dom';\nimport { Disposable, IDisposable } from 'vs/base/common/lifecycle';\nimport { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';\nimport { autorun, IReader, observableFromEvent, ObservableValue } from 'vs/workbench/contrib/audioCues/browser/observable';\nimport { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange';\n", + "result": "import { h } from 'vs/base/browser/dom';\r\nimport { Disposable, IDisposable } from 'vs/base/common/lifecycle';\r\nimport { observableSignalFromEvent } from 'vs/base/common/observable';\r\nimport { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';\r\n<<<<<<< Updated upstream\r\nimport { autorun, IReader, observableFromEvent, ObservableValue } from 'vs/workbench/contrib/audioCues/browser/observable';\r\n=======\r\nimport { autorun, IReader, observableFromEvent } from 'vs/workbench/contrib/audioCues/browser/observable';\r\n>>>>>>> Stashed changes\r\nimport { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange';\r\n" + }, + model => { + assert.deepStrictEqual(model.getProjections(), { + base: [ + "import { h } from 'vs/base/browser/dom';", + "import { Disposable, IDisposable } from 'vs/base/common/lifecycle';", + "⟦⟧₀import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';", + "⟦import { EditorOption } from 'vs/editor/common/config/editorOptions';", + "import { autorun, IReader, observableFromEvent, ObservableValue } from 'vs/workbench/contrib/audioCues/browser/observable';", + "⟧₁import { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange';", + '', + ], + input1: [ + "import { h } from 'vs/base/browser/dom';", + "import { Disposable, IDisposable } from 'vs/base/common/lifecycle';", + "⟦import { observableSignalFromEvent } from 'vs/base/common/observable';", + "⟧₀import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';", + "⟦import { autorun, IReader, observableFromEvent } from 'vs/workbench/contrib/audioCues/browser/observable';", + "⟧₁import { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange';", + '', + ], + input2: [ + "import { h } from 'vs/base/browser/dom';", + "import { Disposable, IDisposable } from 'vs/base/common/lifecycle';", + "⟦⟧₀import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';", + "⟦import { autorun, IReader, observableFromEvent, ObservableValue } from 'vs/workbench/contrib/audioCues/browser/observable';", + "⟧₁import { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange';", + '', + ], + result: [ + "import { h } from 'vs/base/browser/dom';", + "import { Disposable, IDisposable } from 'vs/base/common/lifecycle';", + "⟦import { observableSignalFromEvent } from 'vs/base/common/observable';", + "⟧{1✓}₀import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';", + '⟦<<<<<<< Updated upstream', + "import { autorun, IReader, observableFromEvent, ObservableValue } from 'vs/workbench/contrib/audioCues/browser/observable';", + '=======', + "import { autorun, IReader, observableFromEvent } from 'vs/workbench/contrib/audioCues/browser/observable';", + '>>>>>>> Stashed changes', + "⟧{conflicting}₁import { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange';", + '', + ], + }); + } + ); + }); }); async function testMergeModel( @@ -197,7 +282,9 @@ class MergeModelInterface extends Disposable { ), }; }, - } + }, { + resetUnknownOnInitialization: false + } )); } @@ -241,14 +328,25 @@ class MergeModelInterface extends Disposable { })) ); + const resultTextModel = createTextModel(this.mergeModel.result.getValue()); + applyRanges( + resultTextModel, + baseRanges.map((r, idx) => ({ + range: this.mergeModel.getRangeInResult(r.baseRange).toRange(), + label: `{${this.mergeModel.getState(r).get()}}${toSmallNumbersDec(idx)}`, + })) + ); + const result = { - base: baseTextModel.getValue(), - input1: input1TextModel.getValue(), - input2: input2TextModel.getValue(), + base: baseTextModel.getValue(EndOfLinePreference.LF).split('\n'), + input1: input1TextModel.getValue(EndOfLinePreference.LF).split('\n'), + input2: input2TextModel.getValue(EndOfLinePreference.LF).split('\n'), + result: resultTextModel.getValue(EndOfLinePreference.LF).split('\n'), }; baseTextModel.dispose(); input1TextModel.dispose(); input2TextModel.dispose(); + resultTextModel.dispose(); return result; } -- cgit v1.2.3 From 1c5723822a33d7c40913f98d8a2f639b40e7f8ad Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 5 Jul 2022 14:51:34 +0200 Subject: Comments editor should respect autoClosingBrackets (#154154) Fixes #150003 --- src/vs/workbench/contrib/comments/browser/commentNode.ts | 2 +- src/vs/workbench/contrib/comments/browser/commentReply.ts | 4 +++- src/vs/workbench/contrib/comments/browser/simpleCommentEditor.ts | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/comments/browser/commentNode.ts b/src/vs/workbench/contrib/comments/browser/commentNode.ts index d1d118f5c15..450c76ae8ad 100644 --- a/src/vs/workbench/contrib/comments/browser/commentNode.ts +++ b/src/vs/workbench/contrib/comments/browser/commentNode.ts @@ -382,7 +382,7 @@ export class CommentNode extends Disposable { private createCommentEditor(editContainer: HTMLElement): void { const container = dom.append(editContainer, dom.$('.edit-textarea')); - this._commentEditor = this.instantiationService.createInstance(SimpleCommentEditor, container, SimpleCommentEditor.getEditorOptions(), this.parentThread); + this._commentEditor = this.instantiationService.createInstance(SimpleCommentEditor, container, SimpleCommentEditor.getEditorOptions(this.configurationService), this.parentThread); const resource = URI.parse(`comment:commentinput-${this.comment.uniqueIdInThread}-${Date.now()}.md`); this._commentEditorModel = this.modelService.createModel('', this.languageService.createByFilepathOrFirstLine(resource), resource, false); diff --git a/src/vs/workbench/contrib/comments/browser/commentReply.ts b/src/vs/workbench/contrib/comments/browser/commentReply.ts index 0905db307c3..8fe2a07420e 100644 --- a/src/vs/workbench/contrib/comments/browser/commentReply.ts +++ b/src/vs/workbench/contrib/comments/browser/commentReply.ts @@ -17,6 +17,7 @@ import { ILanguageService } from 'vs/editor/common/languages/language'; import { ITextModel } from 'vs/editor/common/model'; import { IModelService } from 'vs/editor/common/services/model'; import * as nls from 'vs/nls'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { editorForeground, resolveColorValue } from 'vs/platform/theme/common/colorRegistry'; @@ -58,11 +59,12 @@ export class CommentReply extends Disposable { @ILanguageService private languageService: ILanguageService, @IModelService private modelService: IModelService, @IThemeService private themeService: IThemeService, + @IConfigurationService configurationService: IConfigurationService ) { super(); this.form = dom.append(container, dom.$('.comment-form')); - this.commentEditor = this._register(this._scopedInstatiationService.createInstance(SimpleCommentEditor, this.form, SimpleCommentEditor.getEditorOptions(), this._parentThread)); + this.commentEditor = this._register(this._scopedInstatiationService.createInstance(SimpleCommentEditor, this.form, SimpleCommentEditor.getEditorOptions(configurationService), this._parentThread)); this.commentEditorIsEmpty = CommentContextKeys.commentIsEmpty.bindTo(this._contextKeyService); this.commentEditorIsEmpty.set(!this._pendingComment); diff --git a/src/vs/workbench/contrib/comments/browser/simpleCommentEditor.ts b/src/vs/workbench/contrib/comments/browser/simpleCommentEditor.ts index 4a69955fd4a..c4ec1bbf5e3 100644 --- a/src/vs/workbench/contrib/comments/browser/simpleCommentEditor.ts +++ b/src/vs/workbench/contrib/comments/browser/simpleCommentEditor.ts @@ -24,6 +24,7 @@ import { ICommentThreadWidget } from 'vs/workbench/contrib/comments/common/comme import { CommentContextKeys } from 'vs/workbench/contrib/comments/common/commentContextKeys'; import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export const ctxCommentEditorFocused = new RawContextKey('commentEditorFocused', false); @@ -79,7 +80,7 @@ export class SimpleCommentEditor extends CodeEditorWidget { return EditorExtensionsRegistry.getEditorActions(); } - public static getEditorOptions(): IEditorOptions { + public static getEditorOptions(configurationService: IConfigurationService): IEditorOptions { return { wordWrap: 'on', glyphMargin: false, @@ -103,6 +104,7 @@ export class SimpleCommentEditor extends CodeEditorWidget { minimap: { enabled: false }, + autoClosingBrackets: configurationService.getValue('editor.autoClosingBrackets'), quickSuggestions: false }; } -- cgit v1.2.3 From 25cf08709abc75b73db7732ff03800189ca9cff9 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 5 Jul 2022 06:38:02 -0700 Subject: Add ellipsis to recent command/dir commands Fixes #153905 --- src/vs/workbench/contrib/terminal/browser/terminalActions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index ed78d4a79e8..0c70784c0e3 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -307,7 +307,7 @@ export function registerTerminalActions() { constructor() { super({ id: TerminalCommandId.RunRecentCommand, - title: { value: localize('workbench.action.terminal.runRecentCommand', "Run Recent Command"), original: 'Run Recent Command' }, + title: { value: localize('workbench.action.terminal.runRecentCommand', "Run Recent Command..."), original: 'Run Recent Command...' }, f1: true, category, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) @@ -331,7 +331,7 @@ export function registerTerminalActions() { constructor() { super({ id: TerminalCommandId.GoToRecentDirectory, - title: { value: localize('workbench.action.terminal.goToRecentDirectory', "Go to Recent Directory"), original: 'Go to Recent Directory' }, + title: { value: localize('workbench.action.terminal.goToRecentDirectory', "Go to Recent Directory..."), original: 'Go to Recent Directory...' }, f1: true, category, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) -- cgit v1.2.3 From 406aa3e7e6a63f68e7ecd68d6ea628b8b0e740d9 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 5 Jul 2022 07:40:36 -0700 Subject: Enable auto shell integration by default Fixes #154161 --- src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index efe3aa79bd3..83a67239048 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -536,7 +536,7 @@ const terminalConfiguration: IConfigurationNode = { restricted: true, markdownDescription: localize('terminal.integrated.shellIntegration.enabled', "Enable features like enhanced command tracking and current working directory detection. \n\nShell integration works by injecting the shell with a startup script. The script gives VS Code insight into what is happening within the terminal.\n\nSupported shells:\n\n- Linux/macOS: bash, pwsh, zsh\n - Windows: pwsh\n\nThis setting applies only when terminals are created, so you will need to restart your terminals for it to take effect.\n\n Note that the script injection may not work if you have custom arguments defined in the terminal profile, a [complex bash `PROMPT_COMMAND`](https://code.visualstudio.com/docs/editor/integrated-terminal#_complex-bash-promptcommand), or other unsupported setup."), type: 'boolean', - default: false + default: true }, [TerminalSettingId.ShellIntegrationDecorationsEnabled]: { restricted: true, -- cgit v1.2.3 From 3fc3965c15b5e22014636a5be08f2cbdb7e05bec Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 5 Jul 2022 07:54:19 -0700 Subject: Support detecting eslint compact link format in term Fixes #154165 --- .../contrib/terminal/browser/links/terminalLocalLinkDetector.ts | 2 +- .../terminal/test/browser/links/terminalLocalLinkDetector.test.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/links/terminalLocalLinkDetector.ts b/src/vs/workbench/contrib/terminal/browser/links/terminalLocalLinkDetector.ts index 48e5c0659bc..19cab952add 100644 --- a/src/vs/workbench/contrib/terminal/browser/links/terminalLocalLinkDetector.ts +++ b/src/vs/workbench/contrib/terminal/browser/links/terminalLocalLinkDetector.ts @@ -52,7 +52,7 @@ export const lineAndColumnClause = [ '((\\S*)[\'"], line ((\\d+)( column (\\d+))?))', // "(file path)", line 45 [see #40468] '((\\S*)[\'"],((\\d+)(:(\\d+))?))', // "(file path)",45 [see #78205] '((\\S*) on line ((\\d+)(, column (\\d+))?))', // (file path) on line 8, column 13 - '((\\S*):line ((\\d+)(, column (\\d+))?))', // (file path):line 8, column 13 + '((\\S*):\\s?line ((\\d+)(, col(umn)? (\\d+))?))', // (file path):line 8, column 13, (file path): line 8, col 13 '(([^\\s\\(\\)]*)(\\s?[\\(\\[](\\d+)(,\\s?(\\d+))?)[\\)\\]])', // (file path)(45), (file path) (45), (file path)(45,18), (file path) (45,18), (file path)(45, 18), (file path) (45, 18), also with [] '(([^:\\s\\(\\)<>\'\"\\[\\]]*)(:(\\d+))?(:(\\d+))?)' // (file path):336, (file path):336:9 ].join('|').replace(/ /g, `[${'\u00A0'} ]`); diff --git a/src/vs/workbench/contrib/terminal/test/browser/links/terminalLocalLinkDetector.test.ts b/src/vs/workbench/contrib/terminal/test/browser/links/terminalLocalLinkDetector.test.ts index 8ac3607d6e8..9f72ece8c18 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/links/terminalLocalLinkDetector.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/links/terminalLocalLinkDetector.test.ts @@ -58,6 +58,8 @@ const supportedLinkFormats: LinkFormatInfo[] = [ { urlFormat: '{0} on line {1}, column {2}', line: '5', column: '3' }, { urlFormat: '{0}:line {1}', line: '5' }, { urlFormat: '{0}:line {1}, column {2}', line: '5', column: '3' }, + { urlFormat: '{0}: line {1}', line: '5' }, + { urlFormat: '{0}: line {1}, col {2}', line: '5', column: '3' }, { urlFormat: '{0}({1})', line: '5' }, { urlFormat: '{0} ({1})', line: '5' }, { urlFormat: '{0}({1},{2})', line: '5', column: '3' }, -- cgit v1.2.3 From 62a2b0509aa29d06f7220d8f3527e67d2b974f2b Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 5 Jul 2022 20:42:05 +0200 Subject: Clean up in profiles land (#154188) Clean up: - Move preserving data from existing profile to respective components --- .../common/extensionsScannerService.ts | 2 +- .../userDataProfile/common/userDataProfile.ts | 2 +- .../contrib/snippets/browser/snippetsService.ts | 7 +- .../configuration/browser/configurationService.ts | 22 +++--- .../common/extensionManagement.ts | 3 +- .../common/extensionManagementServerService.ts | 7 +- .../profileAwareExtensionManagementService.ts | 73 ------------------- .../common/webExtensionManagementService.ts | 6 +- .../extensionManagementServerService.ts | 10 +-- .../nativeExtensionManagementService.ts | 82 ++++++++++++++++++++++ .../remoteExtensionManagementService.ts | 15 ++-- .../keybinding/browser/keybindingService.ts | 15 ++-- .../browser/userDataProfileManagement.ts | 25 +------ 13 files changed, 135 insertions(+), 134 deletions(-) delete mode 100644 src/vs/workbench/services/extensionManagement/common/profileAwareExtensionManagementService.ts create mode 100644 src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts (limited to 'src/vs') diff --git a/src/vs/platform/extensionManagement/common/extensionsScannerService.ts b/src/vs/platform/extensionManagement/common/extensionsScannerService.ts index e166e75fd6e..823a0be2541 100644 --- a/src/vs/platform/extensionManagement/common/extensionsScannerService.ts +++ b/src/vs/platform/extensionManagement/common/extensionsScannerService.ts @@ -381,7 +381,7 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem private async createExtensionScannerInput(location: URI, profile: boolean, type: ExtensionType, excludeObsolete: boolean, language: string | undefined, validate: boolean = true): Promise { const translations = await this.getTranslations(language ?? platform.language); const mtime = await this.getMtime(location); - const applicationExtensionsLocation = this.userDataProfilesService.defaultProfile.extensionsResource; + const applicationExtensionsLocation = profile ? this.userDataProfilesService.defaultProfile.extensionsResource : undefined; const applicationExtensionsLocationMtime = applicationExtensionsLocation ? await this.getMtime(applicationExtensionsLocation) : undefined; return new ExtensionScannerInput( location, diff --git a/src/vs/platform/userDataProfile/common/userDataProfile.ts b/src/vs/platform/userDataProfile/common/userDataProfile.ts index 0705d48af4f..949133b32f5 100644 --- a/src/vs/platform/userDataProfile/common/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/common/userDataProfile.ts @@ -104,7 +104,7 @@ export const EXTENSIONS_RESOURCE_NAME = 'extensions.json'; export function toUserDataProfile(name: string, location: URI, useDefaultFlags?: UseDefaultProfileFlags): CustomUserDataProfile { return { - id: hash(location.toString()).toString(16), + id: hash(location.path).toString(16), name: name, location: location, isDefault: false, diff --git a/src/vs/workbench/contrib/snippets/browser/snippetsService.ts b/src/vs/workbench/contrib/snippets/browser/snippetsService.ts index 366ed64536b..abc007e863d 100644 --- a/src/vs/workbench/contrib/snippets/browser/snippetsService.ts +++ b/src/vs/workbench/contrib/snippets/browser/snippetsService.ts @@ -358,7 +358,12 @@ class SnippetsService implements ISnippetsService { await this._initFolderSnippets(SnippetSource.User, userSnippetsFolder, disposables); }; this._disposables.add(disposables); - this._disposables.add(this._userDataProfileService.onDidChangeCurrentProfile(() => this._pendingWork.push(updateUserSnippets()))); + this._disposables.add(this._userDataProfileService.onDidChangeCurrentProfile(e => e.join((async () => { + if (e.preserveData) { + await this._fileService.copy(e.previous.snippetsHome, e.profile.snippetsHome); + } + this._pendingWork.push(updateUserSnippets()); + })()))); await updateUserSnippets(); } diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index 72a1946338d..20b7ad38a9a 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -711,15 +711,21 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat } private onUserDataProfileChanged(e: DidChangeUserDataProfileEvent): void { - const promises: Promise[] = []; - promises.push(this.localUserConfiguration.reset(e.profile.settingsResource, e.profile.tasksResource, getLocalUserConfigurationScopes(e.profile, !!this.remoteUserConfiguration))); - if (e.previous.isDefault !== e.profile.isDefault) { - this.createApplicationConfiguration(); - if (this.applicationConfiguration) { - promises.push(this.reloadApplicationConfiguration(true)); - } - } e.join((async () => { + if (e.preserveData) { + await Promise.all([ + this.fileService.copy(e.previous.settingsResource, e.profile.settingsResource), + this.fileService.copy(e.previous.tasksResource, e.profile.tasksResource) + ]); + } + const promises: Promise[] = []; + promises.push(this.localUserConfiguration.reset(e.profile.settingsResource, e.profile.tasksResource, getLocalUserConfigurationScopes(e.profile, !!this.remoteUserConfiguration))); + if (e.previous.isDefault !== e.profile.isDefault) { + this.createApplicationConfiguration(); + if (this.applicationConfiguration) { + promises.push(this.reloadApplicationConfiguration(true)); + } + } const [localUser, application] = await Promise.all(promises); await this.loadConfiguration(application ?? this._configuration.applicationConfiguration, localUser, this._configuration.remoteUserConfiguration); })()); diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts index 5e3c46b1a5b..9c9683c1c3b 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts @@ -13,8 +13,7 @@ import { FileAccess } from 'vs/base/common/network'; export type DidChangeProfileExtensionsEvent = { readonly added: ILocalExtension[]; readonly removed: ILocalExtension[] }; export interface IProfileAwareExtensionManagementService extends IExtensionManagementService { - onDidChangeProfileExtensions: Event; - switchExtensionsProfile(extensionsProfileResource: URI | undefined): Promise; + readonly onDidChangeProfileExtensions: Event; } export interface IExtensionManagementServer { diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagementServerService.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagementServerService.ts index 233e0bc56c2..b16029ca565 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagementServerService.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagementServerService.ts @@ -7,6 +7,7 @@ import { localize } from 'vs/nls'; import { ExtensionInstallLocation, IExtensionManagementServer, IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { Schemas } from 'vs/base/common/network'; +import { Event } from 'vs/base/common/event'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ILabelService } from 'vs/platform/label/common/label'; @@ -14,7 +15,7 @@ import { isWeb } from 'vs/base/common/platform'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { WebExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/webExtensionManagementService'; import { IExtension } from 'vs/platform/extensions/common/extensions'; -import { NativeProfileAwareExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/profileAwareExtensionManagementService'; +import { ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc'; export class ExtensionManagementServerService implements IExtensionManagementServerService { @@ -31,7 +32,9 @@ export class ExtensionManagementServerService implements IExtensionManagementSer ) { const remoteAgentConnection = remoteAgentService.getConnection(); if (remoteAgentConnection) { - const extensionManagementService = instantiationService.createInstance(NativeProfileAwareExtensionManagementService, remoteAgentConnection.getChannel('extensions'), undefined); + const extensionManagementService = new class extends ExtensionManagementChannelClient { + readonly onDidChangeProfileExtensions = Event.None; + }(remoteAgentConnection.getChannel('extensions')); this.remoteExtensionManagementServer = { id: 'remote', extensionManagementService, diff --git a/src/vs/workbench/services/extensionManagement/common/profileAwareExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/profileAwareExtensionManagementService.ts deleted file mode 100644 index b8a639d4e9e..00000000000 --- a/src/vs/workbench/services/extensionManagement/common/profileAwareExtensionManagementService.ts +++ /dev/null @@ -1,73 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IChannel } from 'vs/base/parts/ipc/common/ipc'; -import { IProfileAwareExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; -import { ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc'; -import { URI } from 'vs/base/common/uri'; -import { IGalleryExtension, ILocalExtension, InstallOptions, InstallVSIXOptions, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { ExtensionIdentifier, ExtensionType } from 'vs/platform/extensions/common/extensions'; -import { Emitter, Event } from 'vs/base/common/event'; -import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { delta } from 'vs/base/common/arrays'; -import { compare } from 'vs/base/common/strings'; -import { DisposableStore } from 'vs/base/common/lifecycle'; - -export class NativeProfileAwareExtensionManagementService extends ExtensionManagementChannelClient implements IProfileAwareExtensionManagementService { - - private readonly disposables = this._register(new DisposableStore()); - - override get onInstallExtension() { return Event.filter(super.onInstallExtension, e => this.filterEvent(e), this.disposables); } - override get onDidInstallExtensions() { - return Event.filter( - Event.map(super.onDidInstallExtensions, results => results.filter(e => this.filterEvent(e)), this.disposables), - results => results.length > 0, this.disposables); - } - override get onUninstallExtension() { return Event.filter(super.onUninstallExtension, e => this.filterEvent(e), this.disposables); } - override get onDidUninstallExtension() { return Event.filter(super.onDidUninstallExtension, e => this.filterEvent(e), this.disposables); } - - private readonly _onDidChangeProfileExtensions = this._register(new Emitter<{ readonly added: ILocalExtension[]; readonly removed: ILocalExtension[] }>()); - readonly onDidChangeProfileExtensions = this._onDidChangeProfileExtensions.event; - - constructor(channel: IChannel, public extensionsProfileResource: URI | undefined, - @IUriIdentityService private readonly uriIdentityService: IUriIdentityService, - ) { - super(channel); - } - - private filterEvent({ profileLocation, applicationScoped }: { profileLocation?: URI; applicationScoped?: boolean }): boolean { - return applicationScoped || this.uriIdentityService.extUri.isEqual(this.extensionsProfileResource, profileLocation); - } - - override install(vsix: URI, options?: InstallVSIXOptions): Promise { - return super.install(vsix, { ...options, profileLocation: this.extensionsProfileResource }); - } - - override installFromGallery(extension: IGalleryExtension, installOptions?: InstallOptions): Promise { - return super.installFromGallery(extension, { ...installOptions, profileLocation: this.extensionsProfileResource }); - } - - override uninstall(extension: ILocalExtension, options?: UninstallOptions): Promise { - return super.uninstall(extension, { ...options, profileLocation: this.extensionsProfileResource }); - } - - override getInstalled(type: ExtensionType | null = null): Promise { - return super.getInstalled(type, this.extensionsProfileResource); - } - - async switchExtensionsProfile(extensionsProfileResource: URI | undefined): Promise { - if (this.uriIdentityService.extUri.isEqual(extensionsProfileResource, this.extensionsProfileResource)) { - return; - } - const oldExtensions = await this.getInstalled(ExtensionType.User); - this.extensionsProfileResource = extensionsProfileResource; - const newExtensions = await this.getInstalled(ExtensionType.User); - const { added, removed } = delta(oldExtensions, newExtensions, (a, b) => compare(`${ExtensionIdentifier.toKey(a.identifier.id)}@${a.manifest.version}`, `${ExtensionIdentifier.toKey(b.identifier.id)}@${b.manifest.version}`)); - if (added.length || removed.length) { - this._onDidChangeProfileExtensions.fire({ added, removed }); - } - } - -} diff --git a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts index 147936d4468..2c371645082 100644 --- a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { ExtensionType, IExtension, IExtensionIdentifier, IExtensionManifest, TargetPlatform } from 'vs/platform/extensions/common/extensions'; -import { IExtensionManagementService, ILocalExtension, IGalleryExtension, IGalleryMetadata, InstallOperation, IExtensionGalleryService, InstallOptions, Metadata, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { ILocalExtension, IGalleryExtension, IGalleryMetadata, InstallOperation, IExtensionGalleryService, InstallOptions, Metadata, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; import { URI } from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; import { areSameExtensions, getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; @@ -20,7 +20,7 @@ import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagemen import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -export class WebExtensionManagementService extends AbstractExtensionManagementService implements IExtensionManagementService, IProfileAwareExtensionManagementService { +export class WebExtensionManagementService extends AbstractExtensionManagementService implements IProfileAwareExtensionManagementService { declare readonly _serviceBrand: undefined; @@ -100,8 +100,6 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe return local; } - async switchExtensionsProfile(extensionsProfileResource: URI | undefined): Promise { } - protected createDefaultInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: InstallOptions): IInstallExtensionTask { return new InstallExtensionTask(manifest, extension, options, this.webExtensionsScannerService); } diff --git a/src/vs/workbench/services/extensionManagement/electron-sandbox/extensionManagementServerService.ts b/src/vs/workbench/services/extensionManagement/electron-sandbox/extensionManagementServerService.ts index 762987822ee..b6831100888 100644 --- a/src/vs/workbench/services/extensionManagement/electron-sandbox/extensionManagementServerService.ts +++ b/src/vs/workbench/services/extensionManagement/electron-sandbox/extensionManagementServerService.ts @@ -15,7 +15,7 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { IExtension } from 'vs/platform/extensions/common/extensions'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; -import { NativeProfileAwareExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/profileAwareExtensionManagementService'; +import { NativeExtensionManagementService } from 'vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService'; import { Disposable } from 'vs/base/common/lifecycle'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; @@ -36,14 +36,8 @@ export class ExtensionManagementServerService extends Disposable implements IExt @IInstantiationService instantiationService: IInstantiationService, ) { super(); - const localExtensionManagementService = this._register(instantiationService.createInstance(NativeProfileAwareExtensionManagementService, sharedProcessService.getChannel('extensions'), userDataProfileService.currentProfile.extensionsResource)); + const localExtensionManagementService = this._register(instantiationService.createInstance(NativeExtensionManagementService, sharedProcessService.getChannel('extensions'))); this.localExtensionManagementServer = { extensionManagementService: localExtensionManagementService, id: 'local', label: localize('local', "Local") }; - this._register(userDataProfilesService.onDidChangeProfiles(e => { - if (userDataProfileService.currentProfile.isDefault) { - localExtensionManagementService.extensionsProfileResource = userDataProfilesService.defaultProfile.extensionsResource; - } - })); - this._register(userDataProfileService.onDidChangeCurrentProfile(e => e.join(localExtensionManagementService.switchExtensionsProfile(e.profile.extensionsResource)))); const remoteAgentConnection = remoteAgentService.getConnection(); if (remoteAgentConnection) { const extensionManagementService = instantiationService.createInstance(NativeRemoteExtensionManagementService, remoteAgentConnection.getChannel('extensions'), this.localExtensionManagementServer); diff --git a/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts new file mode 100644 index 00000000000..3252281bf30 --- /dev/null +++ b/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts @@ -0,0 +1,82 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IProfileAwareExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc'; +import { URI } from 'vs/base/common/uri'; +import { IGalleryExtension, ILocalExtension, InstallOptions, InstallVSIXOptions, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { ExtensionIdentifier, ExtensionType } from 'vs/platform/extensions/common/extensions'; +import { Emitter, Event } from 'vs/base/common/event'; +import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { delta } from 'vs/base/common/arrays'; +import { compare } from 'vs/base/common/strings'; +import { DisposableStore } from 'vs/base/common/lifecycle'; +import { DidChangeUserDataProfileEvent, IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { EXTENSIONS_RESOURCE_NAME } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { joinPath } from 'vs/base/common/resources'; +import { IFileService } from 'vs/platform/files/common/files'; + +export class NativeExtensionManagementService extends ExtensionManagementChannelClient implements IProfileAwareExtensionManagementService { + + private readonly disposables = this._register(new DisposableStore()); + + override get onInstallExtension() { return Event.filter(super.onInstallExtension, e => this.filterEvent(e), this.disposables); } + override get onDidInstallExtensions() { + return Event.filter( + Event.map(super.onDidInstallExtensions, results => results.filter(e => this.filterEvent(e)), this.disposables), + results => results.length > 0, this.disposables); + } + override get onUninstallExtension() { return Event.filter(super.onUninstallExtension, e => this.filterEvent(e), this.disposables); } + override get onDidUninstallExtension() { return Event.filter(super.onDidUninstallExtension, e => this.filterEvent(e), this.disposables); } + + private readonly _onDidChangeProfileExtensions = this._register(new Emitter<{ readonly added: ILocalExtension[]; readonly removed: ILocalExtension[] }>()); + readonly onDidChangeProfileExtensions = this._onDidChangeProfileExtensions.event; + + constructor( + channel: IChannel, + @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, + @IFileService private readonly fileService: IFileService, + @IUriIdentityService private readonly uriIdentityService: IUriIdentityService, + ) { + super(channel); + this._register(userDataProfileService.onDidChangeCurrentProfile(e => e.join(this.whenProfileChanged(e)))); + } + + private filterEvent({ profileLocation, applicationScoped }: { profileLocation?: URI; applicationScoped?: boolean }): boolean { + return applicationScoped || this.uriIdentityService.extUri.isEqual(this.userDataProfileService.currentProfile.extensionsResource, profileLocation); + } + + override install(vsix: URI, options?: InstallVSIXOptions): Promise { + return super.install(vsix, { ...options, profileLocation: this.userDataProfileService.currentProfile.extensionsResource }); + } + + override installFromGallery(extension: IGalleryExtension, installOptions?: InstallOptions): Promise { + return super.installFromGallery(extension, { ...installOptions, profileLocation: this.userDataProfileService.currentProfile.extensionsResource }); + } + + override uninstall(extension: ILocalExtension, options?: UninstallOptions): Promise { + return super.uninstall(extension, { ...options, profileLocation: this.userDataProfileService.currentProfile.extensionsResource }); + } + + override getInstalled(type: ExtensionType | null = null): Promise { + return super.getInstalled(type, this.userDataProfileService.currentProfile.extensionsResource); + } + + private async whenProfileChanged(e: DidChangeUserDataProfileEvent): Promise { + const previousExtensionsResource = e.previous.extensionsResource ?? joinPath(e.previous.location, EXTENSIONS_RESOURCE_NAME); + if (e.preserveData) { + await this.fileService.copy(previousExtensionsResource, e.profile.extensionsResource!); + } else { + const oldExtensions = await super.getInstalled(ExtensionType.User, previousExtensionsResource); + const newExtensions = await this.getInstalled(ExtensionType.User); + const { added, removed } = delta(oldExtensions, newExtensions, (a, b) => compare(`${ExtensionIdentifier.toKey(a.identifier.id)}@${a.manifest.version}`, `${ExtensionIdentifier.toKey(b.identifier.id)}@${b.manifest.version}`)); + if (added.length || removed.length) { + this._onDidChangeProfileExtensions.fire({ added, removed }); + } + } + } + +} diff --git a/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts index 53c178a68f6..b9202112131 100644 --- a/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts @@ -4,7 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import { IChannel } from 'vs/base/parts/ipc/common/ipc'; -import { IExtensionManagementService, ILocalExtension, IGalleryExtension, IExtensionGalleryService, InstallOperation, InstallOptions, InstallVSIXOptions, ExtensionManagementError, ExtensionManagementErrorCode } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { Event } from 'vs/base/common/event'; +import { ILocalExtension, IGalleryExtension, IExtensionGalleryService, InstallOperation, InstallOptions, InstallVSIXOptions, ExtensionManagementError, ExtensionManagementErrorCode } from 'vs/platform/extensionManagement/common/extensionManagement'; import { URI } from 'vs/base/common/uri'; import { ExtensionType, IExtensionManifest } from 'vs/platform/extensions/common/extensions'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; @@ -17,14 +18,15 @@ import { IProductService } from 'vs/platform/product/common/productService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { generateUuid } from 'vs/base/common/uuid'; import { joinPath } from 'vs/base/common/resources'; -import { IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { IExtensionManagementServer, IProfileAwareExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService'; import { Promises } from 'vs/base/common/async'; import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService'; -import { NativeProfileAwareExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/profileAwareExtensionManagementService'; -import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc'; -export class NativeRemoteExtensionManagementService extends NativeProfileAwareExtensionManagementService implements IExtensionManagementService { +export class NativeRemoteExtensionManagementService extends ExtensionManagementChannelClient implements IProfileAwareExtensionManagementService { + + readonly onDidChangeProfileExtensions = Event.None; constructor( channel: IChannel, @@ -35,9 +37,8 @@ export class NativeRemoteExtensionManagementService extends NativeProfileAwareEx @IProductService private readonly productService: IProductService, @INativeWorkbenchEnvironmentService private readonly environmentService: INativeWorkbenchEnvironmentService, @IExtensionManifestPropertiesService private readonly extensionManifestPropertiesService: IExtensionManifestPropertiesService, - @IUriIdentityService uriIdentityService: IUriIdentityService, ) { - super(channel, undefined, uriIdentityService); + super(channel); } override async install(vsix: URI, options?: InstallVSIXOptions): Promise { diff --git a/src/vs/workbench/services/keybinding/browser/keybindingService.ts b/src/vs/workbench/services/keybinding/browser/keybindingService.ts index ccd362686a0..fe4650f771f 100644 --- a/src/vs/workbench/services/keybinding/browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/browser/keybindingService.ts @@ -50,7 +50,7 @@ import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { dirname } from 'vs/base/common/resources'; import { getAllUnboundCommands } from 'vs/workbench/services/keybinding/browser/unboundCommands'; import { UserSettingsLabelProvider } from 'vs/base/common/keybindingLabels'; -import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { DidChangeUserDataProfileEvent, IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; interface ContributedKeyBinding { command: string; @@ -738,10 +738,15 @@ class UserKeybindings extends Disposable { } })); - this._register(userDataProfileService.onDidChangeCurrentProfile(e => { - this.watch(); - this.reloadConfigurationScheduler.schedule(); - })); + this._register(userDataProfileService.onDidChangeCurrentProfile(e => e.join(this.whenCurrentProfieChanged(e)))); + } + + private async whenCurrentProfieChanged(e: DidChangeUserDataProfileEvent): Promise { + if (e.preserveData) { + await this.fileService.copy(e.previous.keybindingsResource, e.profile.keybindingsResource); + } + this.watch(); + this.reloadConfigurationScheduler.schedule(); } private watch(): void { diff --git a/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts b/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts index 2488577017b..ba46d3e24d7 100644 --- a/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts +++ b/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts @@ -41,17 +41,6 @@ export class UserDataProfileManagementService extends Disposable implements IUse this._register(userDataProfilesService.onDidChangeProfiles(e => this.onDidChangeProfiles(e))); } - private async checkAndCreateExtensionsProfileResource(): Promise { - if (this.userDataProfileService.currentProfile.extensionsResource) { - return this.userDataProfileService.currentProfile.extensionsResource; - } - if (!this.userDataProfilesService.defaultProfile.extensionsResource) { - // Extensions profile is not yet created for default profile, create it now - return this.createDefaultExtensionsProfile(joinPath(this.userDataProfilesService.defaultProfile.location, EXTENSIONS_RESOURCE_NAME)); - } - throw new Error('Invalid Profile'); - } - private onDidChangeProfiles(e: DidChangeProfilesEvent): void { if (e.removed.some(profile => profile.id === this.userDataProfileService.currentProfile.id)) { this.enterProfile(this.userDataProfilesService.defaultProfile, false, localize('reload message when removed', "The current profile has been removed. Please reload to switch back to default profile")); @@ -65,20 +54,12 @@ export class UserDataProfileManagementService extends Disposable implements IUse async createAndEnterProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, fromExisting?: boolean): Promise { const workspaceIdentifier = this.getWorkspaceIdentifier(); - const promises: Promise[] = []; const newProfile = this.userDataProfilesService.newProfile(name, useDefaultFlags); await this.fileService.createFolder(newProfile.location); - const extensionsProfileResourcePromise = this.checkAndCreateExtensionsProfileResource(); - promises.push(extensionsProfileResourcePromise); - if (fromExisting) { - // Storage copy is handled by storage service while entering profile - promises.push(this.fileService.copy(this.userDataProfileService.currentProfile.settingsResource, newProfile.settingsResource)); - promises.push((async () => this.fileService.copy(await extensionsProfileResourcePromise, newProfile.extensionsResource))()); - promises.push(this.fileService.copy(this.userDataProfileService.currentProfile.keybindingsResource, newProfile.keybindingsResource)); - promises.push(this.fileService.copy(this.userDataProfileService.currentProfile.tasksResource, newProfile.tasksResource)); - promises.push(this.fileService.copy(this.userDataProfileService.currentProfile.snippetsHome, newProfile.snippetsHome)); + if (!this.userDataProfilesService.defaultProfile.extensionsResource) { + // Extensions profile is not yet created for default profile, create it now + await this.createDefaultExtensionsProfile(joinPath(this.userDataProfilesService.defaultProfile.location, EXTENSIONS_RESOURCE_NAME)); } - await Promise.allSettled(promises); const createdProfile = await this.userDataProfilesService.createProfile(newProfile, workspaceIdentifier); await this.enterProfile(createdProfile, !!fromExisting); return createdProfile; -- cgit v1.2.3 From 510a74fc2cceae1461a26e958699c58c26ee573e Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Tue, 5 Jul 2022 14:42:46 -0400 Subject: Update UTC flags properly for 1DS (#154189) Update UTC flags properly for 1DS (#154187) Ensure internal flag isn't applied to non internal data --- .../electron-browser/sharedProcess/sharedProcessMain.ts | 2 +- src/vs/platform/telemetry/browser/1dsAppender.ts | 4 +++- src/vs/platform/telemetry/common/1dsAppender.ts | 17 +++++++++++------ src/vs/platform/telemetry/node/1dsAppender.ts | 4 +++- .../services/telemetry/browser/telemetryService.ts | 2 +- 5 files changed, 19 insertions(+), 10 deletions(-) (limited to 'src/vs') diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index 11116cc4cce..4d77d394a3a 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -283,7 +283,7 @@ class SharedProcessMain extends Disposable { const { installSourcePath } = environmentService; const internalTesting = configurationService.getValue('telemetry.internalTesting'); if (internalTesting && productService.aiConfig?.ariaKey) { - const collectorAppender = new OneDataSystemWebAppender('monacoworkbench', null, productService.aiConfig.ariaKey); + const collectorAppender = new OneDataSystemWebAppender(configurationService, 'monacoworkbench', null, productService.aiConfig.ariaKey); this._register(toDisposable(() => collectorAppender.flush())); // Ensure the 1DS appender is disposed so that it flushes remaining data appenders.push(collectorAppender); } else if (productService.aiConfig && productService.aiConfig.asimovKey) { diff --git a/src/vs/platform/telemetry/browser/1dsAppender.ts b/src/vs/platform/telemetry/browser/1dsAppender.ts index 93bf07cdbb6..96db1e7890b 100644 --- a/src/vs/platform/telemetry/browser/1dsAppender.ts +++ b/src/vs/platform/telemetry/browser/1dsAppender.ts @@ -4,16 +4,18 @@ *--------------------------------------------------------------------------------------------*/ import type { AppInsightsCore } from '@microsoft/1ds-core-js'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { AbstractOneDataSystemAppender } from 'vs/platform/telemetry/common/1dsAppender'; export class OneDataSystemWebAppender extends AbstractOneDataSystemAppender { constructor( + configurationService: IConfigurationService, eventPrefix: string, defaultData: { [key: string]: any } | null, iKeyOrClientFactory: string | (() => AppInsightsCore), // allow factory function for testing ) { - super(eventPrefix, defaultData, iKeyOrClientFactory); + super(configurationService, eventPrefix, defaultData, iKeyOrClientFactory); // If we cannot fetch the endpoint it means it is down and we should not send any telemetry. // This is most likely due to ad blockers diff --git a/src/vs/platform/telemetry/common/1dsAppender.ts b/src/vs/platform/telemetry/common/1dsAppender.ts index e2ea5b42fdc..8023931f50f 100644 --- a/src/vs/platform/telemetry/common/1dsAppender.ts +++ b/src/vs/platform/telemetry/common/1dsAppender.ts @@ -7,11 +7,12 @@ import type { AppInsightsCore, IExtendedConfiguration } from '@microsoft/1ds-cor import type { IChannelConfiguration, IXHROverride, PostChannel } from '@microsoft/1ds-post-js'; import { onUnexpectedError } from 'vs/base/common/errors'; import { mixin } from 'vs/base/common/objects'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ITelemetryAppender, validateTelemetryData } from 'vs/platform/telemetry/common/telemetryUtils'; const endpointUrl = 'https://mobile.events.data.microsoft.com/OneCollector/1.0'; -async function getClient(instrumentationKey: string, xhrOverride?: IXHROverride): Promise { +async function getClient(instrumentationKey: string, addInternalFlag?: boolean, xhrOverride?: IXHROverride): Promise { const oneDs = await import('@microsoft/1ds-core-js'); const postPlugin = await import('@microsoft/1ds-post-js'); const appInsightsCore = new oneDs.AppInsightsCore(); @@ -43,10 +44,12 @@ async function getClient(instrumentationKey: string, xhrOverride?: IXHROverride) appInsightsCore.initialize(coreConfig, []); appInsightsCore.addTelemetryInitializer((envelope) => { - envelope['ext'] = envelope['ext'] ?? {}; - envelope['ext']['utc'] = envelope['ext']['utc'] ?? {}; - // Sets it to be internal only based on Windows UTC flagging - envelope['ext']['utc']['flags'] = 0x0000811ECD; + if (addInternalFlag) { + envelope['ext'] = envelope['ext'] ?? {}; + envelope['ext']['utc'] = envelope['ext']['utc'] ?? {}; + // Sets it to be internal only based on Windows UTC flagging + envelope['ext']['utc']['flags'] = 0x0000811ECD; + } }); return appInsightsCore; @@ -60,6 +63,7 @@ export abstract class AbstractOneDataSystemAppender implements ITelemetryAppende protected readonly endPointUrl = endpointUrl; constructor( + private readonly _configurationService: IConfigurationService, private _eventPrefix: string, private _defaultData: { [key: string]: any } | null, iKeyOrClientFactory: string | (() => AppInsightsCore), // allow factory function for testing @@ -88,7 +92,8 @@ export abstract class AbstractOneDataSystemAppender implements ITelemetryAppende } if (!this._asyncAiCore) { - this._asyncAiCore = getClient(this._aiCoreOrKey, this._xhrOverride); + const isInternal = this._configurationService.getValue('telemetry.internalTesting'); + this._asyncAiCore = getClient(this._aiCoreOrKey, isInternal, this._xhrOverride); } this._asyncAiCore.then( diff --git a/src/vs/platform/telemetry/node/1dsAppender.ts b/src/vs/platform/telemetry/node/1dsAppender.ts index 5721843fac1..2e7b1b6f491 100644 --- a/src/vs/platform/telemetry/node/1dsAppender.ts +++ b/src/vs/platform/telemetry/node/1dsAppender.ts @@ -6,12 +6,14 @@ import type { AppInsightsCore } from '@microsoft/1ds-core-js'; import type { IPayloadData, IXHROverride } from '@microsoft/1ds-post-js'; import * as https from 'https'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { AbstractOneDataSystemAppender } from 'vs/platform/telemetry/common/1dsAppender'; export class OneDataSystemAppender extends AbstractOneDataSystemAppender { constructor( + configurationService: IConfigurationService, eventPrefix: string, defaultData: { [key: string]: any } | null, iKeyOrClientFactory: string | (() => AppInsightsCore), // allow factory function for testing @@ -46,6 +48,6 @@ export class OneDataSystemAppender extends AbstractOneDataSystemAppender { } }; - super(eventPrefix, defaultData, iKeyOrClientFactory, customHttpXHROverride); + super(configurationService, eventPrefix, defaultData, iKeyOrClientFactory, customHttpXHROverride); } } diff --git a/src/vs/workbench/services/telemetry/browser/telemetryService.ts b/src/vs/workbench/services/telemetry/browser/telemetryService.ts index 892f318d293..75701e1a088 100644 --- a/src/vs/workbench/services/telemetry/browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/browser/telemetryService.ts @@ -43,7 +43,7 @@ export class TelemetryService extends Disposable implements ITelemetryService { const internalTesting = configurationService.getValue('telemetry.internalTesting'); const appenders = []; if (internalTesting || productService.aiConfig?.preferAria) { - const telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new OneDataSystemWebAppender('monacoworkbench', null, productService.aiConfig?.ariaKey); + const telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new OneDataSystemWebAppender(configurationService, 'monacoworkbench', null, productService.aiConfig?.ariaKey); appenders.push(telemetryProvider); } else { const telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new WebAppInsightsAppender('monacoworkbench', productService.aiConfig?.asimovKey); -- cgit v1.2.3 From 71c221c532996c9976405f62bb888283c0cf6545 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 5 Jul 2022 21:30:01 +0200 Subject: joh/theoretical quokka (#154157) * add `SnippetController#apply(ISnippetEdit[])` This replaces the initial ugly trick with a more sound implementation of arbitrary snippet edits. A snippet edit can cover disconnected regions, each will be applied as separate text edit but everything will become a single `OneSnippet` instance * add integration test for SnippetString-text edit inside workspace edit --- .../contrib/snippet/browser/snippetController2.ts | 79 ++++------ .../contrib/snippet/browser/snippetParser.ts | 32 ++-- .../contrib/snippet/browser/snippetSession.ts | 95 ++++++++++-- .../test/browser/snippetController2.test.ts | 167 ++++++++++++++++++++- .../snippet/test/browser/snippetSession.test.ts | 32 ++++ .../contrib/bulkEdit/browser/bulkTextEdits.ts | 23 ++- 6 files changed, 343 insertions(+), 85 deletions(-) (limited to 'src/vs') diff --git a/src/vs/editor/contrib/snippet/browser/snippetController2.ts b/src/vs/editor/contrib/snippet/browser/snippetController2.ts index 43e72f6ce57..862f3a20493 100644 --- a/src/vs/editor/contrib/snippet/browser/snippetController2.ts +++ b/src/vs/editor/contrib/snippet/browser/snippetController2.ts @@ -5,25 +5,26 @@ import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { DisposableStore } from 'vs/base/common/lifecycle'; +import { assertType } from 'vs/base/common/types'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorCommand, registerEditorCommand, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; -import { ISelection } from 'vs/editor/common/core/selection'; +import { ISelection, Selection } from 'vs/editor/common/core/selection'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { CompletionItem, CompletionItemKind, CompletionItemProvider } from 'vs/editor/common/languages'; import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; import { ITextModel } from 'vs/editor/common/model'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; -import { Choice, SnippetParser } from 'vs/editor/contrib/snippet/browser/snippetParser'; +import { Choice } from 'vs/editor/contrib/snippet/browser/snippetParser'; import { showSimpleSuggestions } from 'vs/editor/contrib/suggest/browser/suggest'; import { OvertypingCapturer } from 'vs/editor/contrib/suggest/browser/suggestOvertypingCapturer'; import { localize } from 'vs/nls'; import { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { ILogService } from 'vs/platform/log/common/log'; -import { SnippetSession } from './snippetSession'; +import { ISnippetEdit, SnippetSession } from './snippetSession'; export interface ISnippetInsertOptions { overwriteBefore: number; @@ -88,6 +89,19 @@ export class SnippetController2 implements IEditorContribution { this._snippetListener.dispose(); } + apply(edits: ISnippetEdit[], opts?: Partial) { + try { + this._doInsert(edits, typeof opts === 'undefined' ? _defaultOptions : { ..._defaultOptions, ...opts }); + + } catch (e) { + this.cancel(); + this._logService.error(e); + this._logService.error('snippet_error'); + this._logService.error('insert_edits=', edits); + this._logService.error('existing_template=', this._session ? this._session._logInfo() : ''); + } + } + insert( template: string, opts?: Partial @@ -108,7 +122,7 @@ export class SnippetController2 implements IEditorContribution { } private _doInsert( - template: string, + template: string | ISnippetEdit[], opts: ISnippetInsertOptions ): void { if (!this._editor.hasModel()) { @@ -123,11 +137,17 @@ export class SnippetController2 implements IEditorContribution { this._editor.getModel().pushStackElement(); } + // don't merge + if (this._session && typeof template !== 'string') { + this.cancel(); + } + if (!this._session) { this._modelVersionId = this._editor.getModel().getAlternativeVersionId(); this._session = new SnippetSession(this._editor, template, opts, this._languageConfigurationService); this._session.insert(); } else { + assertType(typeof template === 'string'); this._session.merge(template, opts); } @@ -342,50 +362,11 @@ export function performSnippetEdit(editor: ICodeEditor, snippet: string, selecti return false; } editor.focus(); - editor.setSelections(selections ?? []); - controller.insert(snippet); - return controller.isInSnippet(); -} - - -export type ISnippetEdit = { - range: Range; - snippet: string; -}; - -// --- - -export function performSnippetEdits(editor: ICodeEditor, edits: ISnippetEdit[]) { - - if (!editor.hasModel()) { - return false; - } - if (edits.length === 0) { - return false; - } - - const model = editor.getModel(); - let newText = ''; - let last: ISnippetEdit | undefined; - edits.sort((a, b) => Range.compareRangesUsingStarts(a.range, b.range)); - - for (const item of edits) { - if (last) { - const between = Range.fromPositions(last.range.getEndPosition(), item.range.getStartPosition()); - const text = model.getValueInRange(between); - newText += SnippetParser.escape(text); - } - newText += item.snippet; - last = item; - } - - const controller = SnippetController2.get(editor); - if (!controller) { - return false; - } - model.pushStackElement(); - const range = Range.plusRange(edits[0].range, edits[edits.length - 1].range); - editor.setSelection(range); - controller.insert(newText, { undoStopBefore: false }); + controller.apply(selections.map(selection => { + return { + range: Selection.liftSelection(selection), + template: snippet + }; + })); return controller.isInSnippet(); } diff --git a/src/vs/editor/contrib/snippet/browser/snippetParser.ts b/src/vs/editor/contrib/snippet/browser/snippetParser.ts index 6faf65e0d4d..f68dcbfa953 100644 --- a/src/vs/editor/contrib/snippet/browser/snippetParser.ts +++ b/src/vs/editor/contrib/snippet/browser/snippetParser.ts @@ -613,11 +613,17 @@ export class SnippetParser { } parse(value: string, insertFinalTabstop?: boolean, enforceFinalTabstop?: boolean): TextmateSnippet { + const snippet = new TextmateSnippet(); + this.parseFragment(value, snippet); + this.ensureFinalTabstop(snippet, enforceFinalTabstop ?? false, insertFinalTabstop ?? false); + return snippet; + } + parseFragment(value: string, snippet: TextmateSnippet): readonly Marker[] { + + const offset = snippet.children.length; this._scanner.text(value); this._token = this._scanner.next(); - - const snippet = new TextmateSnippet(); while (this._parse(snippet)) { // nothing } @@ -626,10 +632,8 @@ export class SnippetParser { // that has a value defines the value for all placeholders with that index const placeholderDefaultValues = new Map(); const incompletePlaceholders: Placeholder[] = []; - let placeholderCount = 0; snippet.walk(marker => { if (marker instanceof Placeholder) { - placeholderCount += 1; if (marker.isFinalTabstop) { placeholderDefaultValues.set(0, undefined); } else if (!placeholderDefaultValues.has(marker.index) && marker.children.length > 0) { @@ -640,6 +644,7 @@ export class SnippetParser { } return true; }); + for (const placeholder of incompletePlaceholders) { const defaultValues = placeholderDefaultValues.get(placeholder.index); if (defaultValues) { @@ -652,17 +657,20 @@ export class SnippetParser { } } - if (!enforceFinalTabstop) { - enforceFinalTabstop = placeholderCount > 0 && insertFinalTabstop; - } + return snippet.children.slice(offset); + } - if (!placeholderDefaultValues.has(0) && enforceFinalTabstop) { - // the snippet uses placeholders but has no - // final tabstop defined -> insert at the end - snippet.appendChild(new Placeholder(0)); + ensureFinalTabstop(snippet: TextmateSnippet, enforceFinalTabstop: boolean, insertFinalTabstop: boolean) { + + if (enforceFinalTabstop || insertFinalTabstop && snippet.placeholders.length > 0) { + const finalTabstop = snippet.placeholders.find(p => p.index === 0); + if (!finalTabstop) { + // the snippet uses placeholders but has no + // final tabstop defined -> insert at the end + snippet.appendChild(new Placeholder(0)); + } } - return snippet; } private _accept(type?: TokenType): boolean; diff --git a/src/vs/editor/contrib/snippet/browser/snippetSession.ts b/src/vs/editor/contrib/snippet/browser/snippetSession.ts index 00e8268b0b6..74eaa5847f7 100644 --- a/src/vs/editor/contrib/snippet/browser/snippetSession.ts +++ b/src/vs/editor/contrib/snippet/browser/snippetSession.ts @@ -359,6 +359,11 @@ const _defaultOptions: ISnippetSessionInsertOptions = { overtypingCapturer: undefined }; +export interface ISnippetEdit { + range: Range; + template: string; +} + export class SnippetSession { static adjustWhitespace(model: ITextModel, position: IPosition, snippet: TextmateSnippet, adjustIndentation: boolean, adjustNewlines: boolean): string { @@ -434,7 +439,7 @@ export class SnippetSession { return selection; } - static createEditsAndSnippets(editor: IActiveCodeEditor, template: string, overwriteBefore: number, overwriteAfter: number, enforceFinalTabstop: boolean, adjustWhitespace: boolean, clipboardText: string | undefined, overtypingCapturer: OvertypingCapturer | undefined, languageConfigurationService: ILanguageConfigurationService): { edits: IIdentifiedSingleEditOperation[]; snippets: OneSnippet[] } { + static createEditsAndSnippetsFromSelections(editor: IActiveCodeEditor, template: string, overwriteBefore: number, overwriteAfter: number, enforceFinalTabstop: boolean, adjustWhitespace: boolean, clipboardText: string | undefined, overtypingCapturer: OvertypingCapturer | undefined, languageConfigurationService: ILanguageConfigurationService): { edits: IIdentifiedSingleEditOperation[]; snippets: OneSnippet[] } { const edits: IIdentifiedSingleEditOperation[] = []; const snippets: OneSnippet[] = []; @@ -518,22 +523,79 @@ export class SnippetSession { return { edits, snippets }; } - private readonly _editor: IActiveCodeEditor; - private readonly _template: string; - private readonly _templateMerges: [number, number, string][] = []; - private readonly _options: ISnippetSessionInsertOptions; + static createEditsAndSnippetsFromEdits(editor: IActiveCodeEditor, snippetEdits: ISnippetEdit[], enforceFinalTabstop: boolean, adjustWhitespace: boolean, clipboardText: string | undefined, overtypingCapturer: OvertypingCapturer | undefined, languageConfigurationService: ILanguageConfigurationService): { edits: IIdentifiedSingleEditOperation[]; snippets: OneSnippet[] } { + + if (!editor.hasModel() || snippetEdits.length === 0) { + return { edits: [], snippets: [] }; + } + + const edits: IIdentifiedSingleEditOperation[] = []; + const model = editor.getModel(); + + const parser = new SnippetParser(); + const snippet = new TextmateSnippet(); + + // + snippetEdits = snippetEdits.sort((a, b) => Range.compareRangesUsingStarts(a.range, b.range)); + let offset = 0; + for (let i = 0; i < snippetEdits.length; i++) { + + const { range, template } = snippetEdits[i]; + + // gaps between snippet edits are appended as text nodes. this + // ensures placeholder-offsets are later correct + if (i > 0) { + const lastRange = snippetEdits[i - 1].range; + const textRange = Range.fromPositions(lastRange.getEndPosition(), range.getStartPosition()); + const textNode = new Text(model.getValueInRange(textRange)); + snippet.appendChild(textNode); + offset += textNode.value.length; + } + + parser.parseFragment(template, snippet); + + const snippetText = snippet.toString(); + const snippetFragmentText = snippetText.slice(offset); + offset = snippetText.length; + + // make edit + const edit: IIdentifiedSingleEditOperation = EditOperation.replace(range, snippetFragmentText); + edit.identifier = { major: i, minor: 0 }; // mark the edit so only our undo edits will be used to generate end cursors + edit._isTracked = true; + edits.push(edit); + } + + // + parser.ensureFinalTabstop(snippet, enforceFinalTabstop, true); + + // snippet variables resolver + const resolver = new CompositeSnippetVariableResolver([ + editor.invokeWithinContext(accessor => new ModelBasedVariableResolver(accessor.get(ILabelService), model)), + new ClipboardBasedVariableResolver(() => clipboardText, 0, editor.getSelections().length, editor.getOption(EditorOption.multiCursorPaste) === 'spread'), + new SelectionBasedVariableResolver(model, editor.getSelection(), 0, overtypingCapturer), + new CommentBasedVariableResolver(model, editor.getSelection(), languageConfigurationService), + new TimeBasedVariableResolver, + new WorkspaceBasedVariableResolver(editor.invokeWithinContext(accessor => accessor.get(IWorkspaceContextService))), + new RandomBasedVariableResolver, + ]); + snippet.resolveVariables(resolver); + + + return { + edits, + snippets: [new OneSnippet(editor, snippet, '')] + }; + } + + private readonly _templateMerges: [number, number, string | ISnippetEdit[]][] = []; private _snippets: OneSnippet[] = []; constructor( - editor: IActiveCodeEditor, - template: string, - options: ISnippetSessionInsertOptions = _defaultOptions, + private readonly _editor: IActiveCodeEditor, + private readonly _template: string | ISnippetEdit[], + private readonly _options: ISnippetSessionInsertOptions = _defaultOptions, @ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService - ) { - this._editor = editor; - this._template = template; - this._options = options; - } + ) { } dispose(): void { dispose(this._snippets); @@ -549,7 +611,10 @@ export class SnippetSession { } // make insert edit and start with first selections - const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, this._template, this._options.overwriteBefore, this._options.overwriteAfter, false, this._options.adjustWhitespace, this._options.clipboardText, this._options.overtypingCapturer, this._languageConfigurationService); + const { edits, snippets } = typeof this._template === 'string' + ? SnippetSession.createEditsAndSnippetsFromSelections(this._editor, this._template, this._options.overwriteBefore, this._options.overwriteAfter, false, this._options.adjustWhitespace, this._options.clipboardText, this._options.overtypingCapturer, this._languageConfigurationService) + : SnippetSession.createEditsAndSnippetsFromEdits(this._editor, this._template, false, this._options.adjustWhitespace, this._options.clipboardText, this._options.overtypingCapturer, this._languageConfigurationService); + this._snippets = snippets; this._editor.executeEdits('snippet', edits, _undoEdits => { @@ -576,7 +641,7 @@ export class SnippetSession { return; } this._templateMerges.push([this._snippets[0]._nestingLevel, this._snippets[0]._placeholderGroupsIdx, template]); - const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, template, options.overwriteBefore, options.overwriteAfter, true, options.adjustWhitespace, options.clipboardText, options.overtypingCapturer, this._languageConfigurationService); + const { edits, snippets } = SnippetSession.createEditsAndSnippetsFromSelections(this._editor, template, options.overwriteBefore, options.overwriteAfter, true, options.adjustWhitespace, options.clipboardText, options.overtypingCapturer, this._languageConfigurationService); this._editor.executeEdits('snippet', edits, _undoEdits => { // Sometimes, the text buffer will remove automatic whitespace when doing any edits, diff --git a/src/vs/editor/contrib/snippet/test/browser/snippetController2.test.ts b/src/vs/editor/contrib/snippet/test/browser/snippetController2.test.ts index 3560a2c2be4..fce4d2c432b 100644 --- a/src/vs/editor/contrib/snippet/test/browser/snippetController2.test.ts +++ b/src/vs/editor/contrib/snippet/test/browser/snippetController2.test.ts @@ -7,6 +7,7 @@ import { mock } from 'vs/base/test/common/mock'; import { CoreEditingCommands } from 'vs/editor/browser/coreCommands'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { Selection } from 'vs/editor/common/core/selection'; +import { Range } from 'vs/editor/common/core/range'; import { Handler } from 'vs/editor/common/editorCommon'; import { TextModel } from 'vs/editor/common/model/textModel'; import { SnippetController2 } from 'vs/editor/contrib/snippet/browser/snippetController2'; @@ -23,6 +24,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace suite('SnippetController2', function () { + /** @deprecated */ function assertSelections(editor: ICodeEditor, ...s: Selection[]) { for (const selection of editor.getSelections()!) { const actual = s.shift()!; @@ -31,10 +33,20 @@ suite('SnippetController2', function () { assert.strictEqual(s.length, 0); } + /** @deprecated */ function assertContextKeys(service: MockContextKeyService, inSnippet: boolean, hasPrev: boolean, hasNext: boolean): void { - assert.strictEqual(SnippetController2.InSnippetMode.getValue(service), inSnippet, `inSnippetMode`); - assert.strictEqual(SnippetController2.HasPrevTabstop.getValue(service), hasPrev, `HasPrevTabstop`); - assert.strictEqual(SnippetController2.HasNextTabstop.getValue(service), hasNext, `HasNextTabstop`); + const state = getContextState(service); + assert.strictEqual(state.inSnippet, inSnippet, `inSnippetMode`); + assert.strictEqual(state.hasPrev, hasPrev, `HasPrevTabstop`); + assert.strictEqual(state.hasNext, hasNext, `HasNextTabstop`); + } + + function getContextState(service: MockContextKeyService = contextKeys) { + return { + inSnippet: SnippetController2.InSnippetMode.getValue(service), + hasPrev: SnippetController2.HasPrevTabstop.getValue(service), + hasNext: SnippetController2.HasNextTabstop.getValue(service), + }; } let editor: ICodeEditor; @@ -531,4 +543,153 @@ suite('SnippetController2', function () { assert.strictEqual(model.getValue(), `foo: number;\n\nfoo: 'number',`); // editor.trigger('test', 'type', { text: ';' }); }); + + suite('createEditsAndSnippetsFromEdits', function () { + + test('apply, tab, done', function () { + + const ctrl = instaService.createInstance(SnippetController2, editor); + + model.setValue('foo("bar")'); + + ctrl.apply([ + { range: new Range(1, 5, 1, 10), template: '$1' }, + { range: new Range(1, 1, 1, 1), template: 'const ${1:new_const} = "bar";\n' } + ]); + + assert.strictEqual(model.getValue(), "const new_const = \"bar\";\nfoo(new_const)"); + assertContextKeys(contextKeys, true, false, true); + assert.deepStrictEqual(editor.getSelections(), [new Selection(1, 7, 1, 16), new Selection(2, 5, 2, 14)]); + + ctrl.next(); + assertContextKeys(contextKeys, false, false, false); + assert.deepStrictEqual(editor.getSelections(), [new Selection(2, 14, 2, 14)]); + }); + + test('apply, tab, done with special final tabstop', function () { + + model.setValue('foo("bar")'); + + const ctrl = instaService.createInstance(SnippetController2, editor); + ctrl.apply([ + { range: new Range(1, 5, 1, 10), template: '$1' }, + { range: new Range(1, 1, 1, 1), template: 'const ${1:new_const}$0 = "bar";\n' } + ]); + + assert.strictEqual(model.getValue(), "const new_const = \"bar\";\nfoo(new_const)"); + assertContextKeys(contextKeys, true, false, true); + assert.deepStrictEqual(editor.getSelections(), [new Selection(1, 7, 1, 16), new Selection(2, 5, 2, 14)]); + + ctrl.next(); + assertContextKeys(contextKeys, false, false, false); + assert.deepStrictEqual(editor.getSelections(), [new Selection(1, 16, 1, 16)]); + }); + + test('apply, tab, tab, done', function () { + + model.setValue('foo\nbar'); + + const ctrl = instaService.createInstance(SnippetController2, editor); + ctrl.apply([ + { range: new Range(1, 4, 1, 4), template: '${3}' }, + { range: new Range(2, 4, 2, 4), template: '$3' }, + { range: new Range(1, 1, 1, 1), template: '### ${2:Header}\n' } + ]); + + assert.strictEqual(model.getValue(), "### Header\nfoo\nbar"); + assert.deepStrictEqual(getContextState(), { inSnippet: true, hasPrev: false, hasNext: true }); + assert.deepStrictEqual(editor.getSelections(), [new Selection(1, 5, 1, 11)]); + + ctrl.next(); + assert.deepStrictEqual(getContextState(), { inSnippet: true, hasPrev: true, hasNext: true }); + assert.deepStrictEqual(editor.getSelections(), [new Selection(2, 4, 2, 4), new Selection(3, 4, 3, 4)]); + + ctrl.next(); + assert.deepStrictEqual(getContextState(), { inSnippet: false, hasPrev: false, hasNext: false }); + assert.deepStrictEqual(editor.getSelections(), [new Selection(3, 4, 3, 4)]); + }); + + test('nested into apply works', function () { + + const ctrl = instaService.createInstance(SnippetController2, editor); + model.setValue('onetwo'); + + editor.setSelections([new Selection(1, 1, 1, 1), new Selection(2, 1, 2, 1)]); + + ctrl.apply([{ + range: new Range(1, 7, 1, 7), + template: '$0${1:three}' + }]); + + assert.strictEqual(model.getValue(), 'onetwothree'); + assert.deepStrictEqual(getContextState(), { inSnippet: true, hasPrev: false, hasNext: true }); + assert.deepStrictEqual(editor.getSelections(), [new Selection(1, 7, 1, 12)]); + + ctrl.insert('foo$1bar$1'); + assert.strictEqual(model.getValue(), 'onetwofoobar'); + assert.deepStrictEqual(editor.getSelections(), [new Selection(1, 10, 1, 10), new Selection(1, 13, 1, 13)]); + assert.deepStrictEqual(getContextState(), ({ inSnippet: true, hasPrev: false, hasNext: true })); + + ctrl.next(); + assert.deepStrictEqual(getContextState(), ({ inSnippet: true, hasPrev: true, hasNext: true })); + assert.deepStrictEqual(editor.getSelections(), [new Selection(1, 13, 1, 13)]); + + ctrl.next(); + assert.deepStrictEqual(getContextState(), { inSnippet: false, hasPrev: false, hasNext: false }); + assert.deepStrictEqual(editor.getSelections(), [new Selection(1, 7, 1, 7)]); + + }); + + test('nested into insert abort "outer" snippet', function () { + + const ctrl = instaService.createInstance(SnippetController2, editor); + model.setValue('one\ntwo'); + + editor.setSelections([new Selection(1, 1, 1, 1), new Selection(2, 1, 2, 1)]); + + ctrl.insert('foo${1:bar}bazz${1:bang}'); + assert.deepStrictEqual(editor.getSelections(), [new Selection(1, 4, 1, 7), new Selection(1, 11, 1, 14), new Selection(2, 4, 2, 7), new Selection(2, 11, 2, 14)]); + assert.deepStrictEqual(getContextState(), { inSnippet: true, hasPrev: false, hasNext: true }); + + ctrl.apply([{ + range: new Range(1, 4, 1, 7), + template: '$0A' + }]); + + assert.strictEqual(model.getValue(), 'fooAbazzbarone\nfoobarbazzbartwo'); + assert.deepStrictEqual(getContextState(), { inSnippet: false, hasPrev: false, hasNext: false }); + assert.deepStrictEqual(editor.getSelections(), [new Selection(1, 4, 1, 4)]); + }); + + test('nested into "insert" abort "outer" snippet (2)', function () { + + const ctrl = instaService.createInstance(SnippetController2, editor); + model.setValue('one\ntwo'); + + editor.setSelections([new Selection(1, 1, 1, 1), new Selection(2, 1, 2, 1)]); + + ctrl.insert('foo${1:bar}bazz${1:bang}'); + assert.deepStrictEqual(editor.getSelections(), [new Selection(1, 4, 1, 7), new Selection(1, 11, 1, 14), new Selection(2, 4, 2, 7), new Selection(2, 11, 2, 14)]); + assert.deepStrictEqual(getContextState(), { inSnippet: true, hasPrev: false, hasNext: true }); + + const edits = [{ + range: new Range(1, 4, 1, 7), + template: 'A' + }, { + range: new Range(1, 11, 1, 14), + template: 'B' + }, { + range: new Range(2, 4, 2, 7), + template: 'C' + }, { + range: new Range(2, 11, 2, 14), + template: 'D' + }]; + ctrl.apply(edits); + + assert.strictEqual(model.getValue(), "fooAbazzBone\nfooCbazzDtwo"); + assert.deepStrictEqual(getContextState(), { inSnippet: false, hasPrev: false, hasNext: false }); + assert.deepStrictEqual(editor.getSelections(), [new Selection(1, 5, 1, 5), new Selection(1, 10, 1, 10), new Selection(2, 5, 2, 5), new Selection(2, 10, 2, 10)]); + }); + }); }); diff --git a/src/vs/editor/contrib/snippet/test/browser/snippetSession.test.ts b/src/vs/editor/contrib/snippet/test/browser/snippetSession.test.ts index 7ce812e34ee..c9b7d0f2aa1 100644 --- a/src/vs/editor/contrib/snippet/test/browser/snippetSession.test.ts +++ b/src/vs/editor/contrib/snippet/test/browser/snippetSession.test.ts @@ -743,4 +743,36 @@ suite('SnippetSession', function () { '}', ].join('\n')); }); + + + suite('createEditsAndSnippetsFromEdits', function () { + + test('empty', function () { + + const result = SnippetSession.createEditsAndSnippetsFromEdits(editor, [], true, true, undefined, undefined, languageConfigurationService); + + assert.deepStrictEqual(result.edits, []); + assert.deepStrictEqual(result.snippets, []); + }); + + test('basic', function () { + + editor.getModel().setValue('foo("bar")'); + + const result = SnippetSession.createEditsAndSnippetsFromEdits( + editor, + [{ range: new Range(1, 5, 1, 9), template: '$1' }, { range: new Range(1, 1, 1, 1), template: 'const ${1:new_const} = "bar"' }], + true, true, undefined, undefined, languageConfigurationService + ); + + assert.strictEqual(result.edits.length, 2); + assert.deepStrictEqual(result.edits[0].range, new Range(1, 1, 1, 1)); + assert.deepStrictEqual(result.edits[0].text, 'const new_const = "bar"'); + assert.deepStrictEqual(result.edits[1].range, new Range(1, 5, 1, 9)); + assert.deepStrictEqual(result.edits[1].text, 'new_const'); + + assert.strictEqual(result.snippets.length, 1); + assert.strictEqual(result.snippets[0].isTrivialSnippet, false); + }); + }); }); diff --git a/src/vs/workbench/contrib/bulkEdit/browser/bulkTextEdits.ts b/src/vs/workbench/contrib/bulkEdit/browser/bulkTextEdits.ts index f69e60201f2..b07897a513a 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/bulkTextEdits.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/bulkTextEdits.ts @@ -19,8 +19,9 @@ import { ResourceMap } from 'vs/base/common/map'; import { IModelService } from 'vs/editor/common/services/model'; import { ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { performSnippetEdits } from 'vs/editor/contrib/snippet/browser/snippetController2'; +import { SnippetController2 } from 'vs/editor/contrib/snippet/browser/snippetController2'; import { SnippetParser } from 'vs/editor/contrib/snippet/browser/snippetParser'; +import { ISnippetEdit } from 'vs/editor/contrib/snippet/browser/snippetSession'; type ValidationResult = { canApply: true } | { canApply: false; reason: URI }; @@ -141,14 +142,24 @@ class EditorEditTask extends ModelEditTask { super.apply(); return; } - if (this._edits.length > 0) { - const insertAsSnippet = this._edits.every(edit => edit.insertAsSnippet); - if (insertAsSnippet) { - // todo@jrieken what ABOUT EOL? - performSnippetEdits(this._editor, this._edits.map(edit => ({ range: Range.lift(edit.range!), snippet: edit.text! }))); + if (this._edits.length > 0) { + const snippetCtrl = SnippetController2.get(this._editor); + if (snippetCtrl && this._edits.some(edit => edit.insertAsSnippet)) { + // some edit is a snippet edit -> use snippet controller and ISnippetEdits + const snippetEdits: ISnippetEdit[] = []; + for (const edit of this._edits) { + if (edit.range && edit.text !== null) { + snippetEdits.push({ + range: Range.lift(edit.range), + template: edit.insertAsSnippet ? edit.text : SnippetParser.escape(edit.text) + }); + } + } + snippetCtrl.apply(snippetEdits); } else { + // normal edit this._edits = this._edits .map(this._transformSnippetStringToInsertText, this) // mixed edits (snippet and normal) -> no snippet mode .sort((a, b) => Range.compareRangesUsingStarts(a.range, b.range)); -- cgit v1.2.3 From 2c7201670f8bb71c43b3e448a0df6ac7b3720d61 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Jul 2022 12:51:28 -0700 Subject: Remove use of forEach (#154196) For #154195 --- .../workbench/api/test/browser/extHostTypeConverter.test.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/api/test/browser/extHostTypeConverter.test.ts b/src/vs/workbench/api/test/browser/extHostTypeConverter.test.ts index a7a0b914279..650c28eb667 100644 --- a/src/vs/workbench/api/test/browser/extHostTypeConverter.test.ts +++ b/src/vs/workbench/api/test/browser/extHostTypeConverter.test.ts @@ -8,7 +8,6 @@ import * as assert from 'assert'; import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; import { MarkdownString, NotebookCellOutputItem, NotebookData, LanguageSelector } from 'vs/workbench/api/common/extHostTypeConverters'; import { isEmptyObject } from 'vs/base/common/types'; -import { forEach } from 'vs/base/common/collections'; import { LogLevel as _MainLogLevel } from 'vs/platform/log/common/log'; import { URI } from 'vs/base/common/uri'; @@ -74,13 +73,13 @@ suite('ExtHostTypeConverter', function () { const data = MarkdownString.from('*hello* [click](command:npm.runScriptFromHover?%7B%22documentUri%22%3A%7B%22%24mid%22%3A1%2C%22external%22%3A%22file%3A%2F%2F%2Fc%253A%2Ffoo%2Fbaz.ex%22%2C%22path%22%3A%22%2Fc%3A%2Ffoo%2Fbaz.ex%22%2C%22scheme%22%3A%22file%22%7D%2C%22script%22%3A%22dev%22%7D)'); // assert that both uri get extracted but that the latter is only decoded once... assert.strictEqual(size(data.uris!), 2); - forEach(data.uris!, entry => { - if (entry.value.scheme === 'file') { - assert.ok(URI.revive(entry.value).toString().indexOf('file:///c%3A') === 0); + for (const value of Object.values(data.uris!)) { + if (value.scheme === 'file') { + assert.ok(URI.revive(value).toString().indexOf('file:///c%3A') === 0); } else { - assert.strictEqual(entry.value.scheme, 'command'); + assert.strictEqual(value.scheme, 'command'); } - }); + } }); test('Notebook metadata is ignored when using Notebook Serializer #125716', function () { -- cgit v1.2.3 From 3e59037fa15db36fd2dca02b1546f8e8ac2e6d80 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Tue, 5 Jul 2022 12:54:14 -0700 Subject: Debt - Add dedicated Edit Sessions output channel (#154190) * Create a separate log channel for edit sessions * Move edit sessions services into contrib since they are not accessed from outside the contrib * Remove redundant log message prefix * Update test --- src/vs/platform/environment/common/environment.ts | 1 + .../environment/common/environmentService.ts | 3 + .../workbench/contrib/logs/common/logConstants.ts | 1 + .../contrib/logs/common/logs.contribution.ts | 1 + .../browser/sessionSync.contribution.ts | 41 +-- .../browser/sessionSyncWorkbenchService.ts | 358 ++++++++++++++++++++ .../sessionSync/common/editSessionsLogService.ts | 50 +++ .../contrib/sessionSync/common/sessionSync.ts | 67 ++++ .../sessionSync/test/browser/sessionSync.test.ts | 6 +- .../environment/browser/environmentService.ts | 3 + .../browser/sessionSyncWorkbenchService.ts | 359 --------------------- .../services/sessionSync/common/sessionSync.ts | 63 ---- 12 files changed, 509 insertions(+), 444 deletions(-) create mode 100644 src/vs/workbench/contrib/sessionSync/browser/sessionSyncWorkbenchService.ts create mode 100644 src/vs/workbench/contrib/sessionSync/common/editSessionsLogService.ts create mode 100644 src/vs/workbench/contrib/sessionSync/common/sessionSync.ts delete mode 100644 src/vs/workbench/services/sessionSync/browser/sessionSyncWorkbenchService.ts delete mode 100644 src/vs/workbench/services/sessionSync/common/sessionSync.ts (limited to 'src/vs') diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 5ed69a092ef..32fcb903d4c 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -66,6 +66,7 @@ export interface IEnvironmentService { // --- continue edit session editSessionId?: string; + editSessionsLogResource: URI; // --- extension development debugExtensionHost: IExtensionHostDebugParams; diff --git a/src/vs/platform/environment/common/environmentService.ts b/src/vs/platform/environment/common/environmentService.ts index 992c7ed9a96..90b24b9c924 100644 --- a/src/vs/platform/environment/common/environmentService.ts +++ b/src/vs/platform/environment/common/environmentService.ts @@ -80,6 +80,9 @@ export abstract class AbstractNativeEnvironmentService implements INativeEnviron @memoize get userDataSyncLogResource(): URI { return URI.file(join(this.logsPath, 'userDataSync.log')); } + @memoize + get editSessionsLogResource(): URI { return URI.file(join(this.logsPath, 'editSessions.log')); } + @memoize get sync(): 'on' | 'off' | undefined { return this.args.sync; } diff --git a/src/vs/workbench/contrib/logs/common/logConstants.ts b/src/vs/workbench/contrib/logs/common/logConstants.ts index 9ba3e7aa0ee..4342dd4a740 100644 --- a/src/vs/workbench/contrib/logs/common/logConstants.ts +++ b/src/vs/workbench/contrib/logs/common/logConstants.ts @@ -9,5 +9,6 @@ export const rendererLogChannelId = 'rendererLog'; export const extHostLogChannelId = 'extHostLog'; export const telemetryLogChannelId = 'telemetryLog'; export const userDataSyncLogChannelId = 'userDataSyncLog'; +export const editSessionsLogChannelId = 'editSessionsSyncLog'; export const showWindowLogActionId = 'workbench.action.showWindowLog'; diff --git a/src/vs/workbench/contrib/logs/common/logs.contribution.ts b/src/vs/workbench/contrib/logs/common/logs.contribution.ts index 5e533149305..f45fe793b09 100644 --- a/src/vs/workbench/contrib/logs/common/logs.contribution.ts +++ b/src/vs/workbench/contrib/logs/common/logs.contribution.ts @@ -38,6 +38,7 @@ class LogOutputChannels extends Disposable implements IWorkbenchContribution { private registerCommonContributions(): void { this.registerLogChannel(Constants.userDataSyncLogChannelId, nls.localize('userDataSyncLog', "Settings Sync"), this.environmentService.userDataSyncLogResource); + this.registerLogChannel(Constants.editSessionsLogChannelId, nls.localize('editSessionsLog', "Edit Sessions"), this.environmentService.editSessionsLogResource); this.registerLogChannel(Constants.rendererLogChannelId, nls.localize('rendererLog', "Window"), this.environmentService.logFile); const registerTelemetryChannel = () => { diff --git a/src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts b/src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts index 08381fc3d9c..642ab0ce273 100644 --- a/src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts +++ b/src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts @@ -10,7 +10,7 @@ import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { localize } from 'vs/nls'; -import { ISessionSyncWorkbenchService, Change, ChangeType, Folder, EditSession, FileType, EDIT_SESSION_SYNC_CATEGORY, EditSessionSchemaVersion } from 'vs/workbench/services/sessionSync/common/sessionSync'; +import { ISessionSyncWorkbenchService, Change, ChangeType, Folder, EditSession, FileType, EDIT_SESSION_SYNC_CATEGORY, EditSessionSchemaVersion, IEditSessionsLogService } from 'vs/workbench/contrib/sessionSync/common/sessionSync'; import { ISCMRepository, ISCMService } from 'vs/workbench/contrib/scm/common/scm'; import { IFileService } from 'vs/platform/files/common/files'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; @@ -19,13 +19,12 @@ import { joinPath, relativePath } from 'vs/base/common/resources'; import { VSBuffer } from 'vs/base/common/buffer'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress'; -import { SessionSyncWorkbenchService } from 'vs/workbench/services/sessionSync/browser/sessionSyncWorkbenchService'; +import { SessionSyncWorkbenchService } from 'vs/workbench/contrib/sessionSync/browser/sessionSyncWorkbenchService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { UserDataSyncErrorCode, UserDataSyncStoreError } from 'vs/platform/userDataSync/common/userDataSync'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IDialogService, IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; -import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -39,7 +38,9 @@ import { getVirtualWorkspaceLocation } from 'vs/platform/workspace/common/virtua import { Schemas } from 'vs/base/common/network'; import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys'; import { isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; +import { EditSessionsLogService } from 'vs/workbench/contrib/sessionSync/common/editSessionsLogService'; +registerSingleton(IEditSessionsLogService, EditSessionsLogService); registerSingleton(ISessionSyncWorkbenchService, SessionSyncWorkbenchService); const resumeLatestCommand = { @@ -61,6 +62,7 @@ const openLocalFolderCommand = { title: { value: localize('continue edit session in local folder', "Open In Local Folder"), original: 'Open In Local Folder' }, }; const queryParamName = 'editSessionId'; +const experimentalSettingName = 'workbench.experimental.editSessions.enabled'; export class SessionSyncContribution extends Disposable implements IWorkbenchContribution { @@ -76,7 +78,7 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon @ISCMService private readonly scmService: ISCMService, @INotificationService private readonly notificationService: INotificationService, @IDialogService private readonly dialogService: IDialogService, - @ILogService private readonly logService: ILogService, + @IEditSessionsLogService private readonly logService: IEditSessionsLogService, @IEnvironmentService private readonly environmentService: IEnvironmentService, @IProductService private readonly productService: IProductService, @IConfigurationService private configurationService: IConfigurationService, @@ -93,7 +95,7 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon } this.configurationService.onDidChangeConfiguration((e) => { - if (e.affectsConfiguration('workbench.experimental.editSessions.enabled')) { + if (e.affectsConfiguration(experimentalSettingName)) { this.registerActions(); } }); @@ -129,7 +131,8 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon } private registerActions() { - if (this.registered || this.configurationService.getValue('workbench.experimental.editSessions.enabled') !== true) { + if (this.registered || this.configurationService.getValue(experimentalSettingName) !== true) { + this.logService.info(`Skipping registering edit sessions actions as edit sessions are currently disabled. Set ${experimentalSettingName} to enable edit sessions.`); return; } @@ -167,11 +170,11 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon query: uri.query.length > 0 ? (uri + `&${queryParamName}=${encodedRef}`) : `${queryParamName}=${encodedRef}` }); } else { - that.logService.warn(`Edit Sessions: Failed to store edit session when invoking ${continueEditSessionCommand.id}.`); + that.logService.warn(`Failed to store edit session when invoking ${continueEditSessionCommand.id}.`); } // Open the URI - that.logService.info(`Edit Sessions: opening ${uri.toString()}`); + that.logService.info(`Opening ${uri.toString()}`); await that.openerService.open(uri, { openExternal: true }); } })); @@ -221,7 +224,7 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon async applyEditSession(ref?: string): Promise { if (ref !== undefined) { - this.logService.info(`Edit Sessions: Applying edit session with ref ${ref}.`); + this.logService.info(`Applying edit session with ref ${ref}.`); } const data = await this.sessionSyncWorkbenchService.read(ref); @@ -231,7 +234,7 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon } else { this.notificationService.warn(localize('no edit session content for ref', 'Could not apply edit session contents for ID {0}.', ref)); } - this.logService.info(`Edit Sessions: Aborting applying edit session as no edit session content is available to be applied from ref ${ref}.`); + this.logService.info(`Aborting applying edit session as no edit session content is available to be applied from ref ${ref}.`); return; } const editSession = data.editSession; @@ -249,7 +252,7 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon for (const folder of editSession.folders) { const folderRoot = this.contextService.getWorkspace().folders.find((f) => f.name === folder.name); if (!folderRoot) { - this.logService.info(`Edit Sessions: Skipping applying ${folder.workingChanges.length} changes from edit session with ref ${ref} as no corresponding workspace folder named ${folder.name} is currently open.`); + this.logService.info(`Skipping applying ${folder.workingChanges.length} changes from edit session with ref ${ref} as no corresponding workspace folder named ${folder.name} is currently open.`); continue; } @@ -289,11 +292,11 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon } } - this.logService.info(`Edit Sessions: Deleting edit session with ref ${ref} after successfully applying it to current workspace...`); + this.logService.info(`Deleting edit session with ref ${ref} after successfully applying it to current workspace...`); await this.sessionSyncWorkbenchService.delete(ref); - this.logService.info(`Edit Sessions: Deleted edit session with ref ${ref}.`); + this.logService.info(`Deleted edit session with ref ${ref}.`); } catch (ex) { - this.logService.error('Edit Sessions: Failed to apply edit session, reason: ', (ex as Error).toString()); + this.logService.error('Failed to apply edit session, reason: ', (ex as Error).toString()); this.notificationService.error(localize('apply failed', "Failed to apply your edit session.")); } } @@ -312,7 +315,7 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon for (const uri of trackedUris) { const workspaceFolder = this.contextService.getWorkspaceFolder(uri); if (!workspaceFolder) { - this.logService.info(`Edit Sessions: Skipping working change ${uri.toString()} as no associated workspace folder was found.`); + this.logService.info(`Skipping working change ${uri.toString()} as no associated workspace folder was found.`); continue; } @@ -341,7 +344,7 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon } if (!hasEdits) { - this.logService.info('Edit Sessions: Skipping storing edit session as there are no edits to store.'); + this.logService.info('Skipping storing edit session as there are no edits to store.'); if (fromStoreCommand) { this.notificationService.info(localize('no edits to store', 'Skipped storing edit session as there are no edits to store.')); } @@ -351,12 +354,12 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon const data: EditSession = { folders, version: 1 }; try { - this.logService.info(`Edit Sessions: Storing edit session...`); + this.logService.info(`Storing edit session...`); const ref = await this.sessionSyncWorkbenchService.write(data); - this.logService.info(`Edit Sessions: Stored edit session with ref ${ref}.`); + this.logService.info(`Stored edit session with ref ${ref}.`); return ref; } catch (ex) { - this.logService.error(`Edit Sessions: Failed to store edit session, reason: `, (ex as Error).toString()); + this.logService.error(`Failed to store edit session, reason: `, (ex as Error).toString()); type UploadFailedEvent = { reason: string }; type UploadFailedClassification = { diff --git a/src/vs/workbench/contrib/sessionSync/browser/sessionSyncWorkbenchService.ts b/src/vs/workbench/contrib/sessionSync/browser/sessionSyncWorkbenchService.ts new file mode 100644 index 00000000000..1df0ecc3d28 --- /dev/null +++ b/src/vs/workbench/contrib/sessionSync/browser/sessionSyncWorkbenchService.ts @@ -0,0 +1,358 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable } from 'vs/base/common/lifecycle'; +import { URI } from 'vs/base/common/uri'; +import { localize } from 'vs/nls'; +import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; +import { ContextKeyExpr, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IFileService } from 'vs/platform/files/common/files'; +import { IProductService } from 'vs/platform/product/common/productService'; +import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; +import { IRequestService } from 'vs/platform/request/common/request'; +import { IStorageService, IStorageValueChangeEvent, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; +import { IAuthenticationProvider } from 'vs/platform/userDataSync/common/userDataSync'; +import { UserDataSyncStoreClient } from 'vs/platform/userDataSync/common/userDataSyncStoreService'; +import { AuthenticationSession, AuthenticationSessionsChangeEvent, IAuthenticationService } from 'vs/workbench/services/authentication/common/authentication'; +import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { EDIT_SESSIONS_SIGNED_IN, EditSession, EDIT_SESSION_SYNC_CATEGORY, ISessionSyncWorkbenchService, EDIT_SESSIONS_SIGNED_IN_KEY, IEditSessionsLogService } from 'vs/workbench/contrib/sessionSync/common/sessionSync'; + +type ExistingSession = IQuickPickItem & { session: AuthenticationSession & { providerId: string } }; +type AuthenticationProviderOption = IQuickPickItem & { provider: IAuthenticationProvider }; + +export class SessionSyncWorkbenchService extends Disposable implements ISessionSyncWorkbenchService { + + _serviceBrand = undefined; + + private serverConfiguration = this.productService['sessionSync.store']; + private storeClient: UserDataSyncStoreClient | undefined; + + #authenticationInfo: { sessionId: string; token: string; providerId: string } | undefined; + private static CACHED_SESSION_STORAGE_KEY = 'editSessionSyncAccountPreference'; + + private initialized = false; + private readonly signedInContext: IContextKey; + + constructor( + @IFileService private readonly fileService: IFileService, + @IStorageService private readonly storageService: IStorageService, + @IQuickInputService private readonly quickInputService: IQuickInputService, + @IAuthenticationService private readonly authenticationService: IAuthenticationService, + @IExtensionService private readonly extensionService: IExtensionService, + @IEnvironmentService private readonly environmentService: IEnvironmentService, + @IEditSessionsLogService private readonly logService: IEditSessionsLogService, + @IProductService private readonly productService: IProductService, + @IContextKeyService private readonly contextKeyService: IContextKeyService, + @IRequestService private readonly requestService: IRequestService, + ) { + super(); + + // If the user signs out of the current session, reset our cached auth state in memory and on disk + this._register(this.authenticationService.onDidChangeSessions((e) => this.onDidChangeSessions(e.event))); + + // If another window changes the preferred session storage, reset our cached auth state in memory + this._register(this.storageService.onDidChangeValue(e => this.onDidChangeStorage(e))); + + this.registerResetAuthenticationAction(); + + this.signedInContext = EDIT_SESSIONS_SIGNED_IN.bindTo(this.contextKeyService); + this.signedInContext.set(this.existingSessionId !== undefined); + } + + /** + * + * @param editSession An object representing edit session state to be restored. + * @returns The ref of the stored edit session state. + */ + async write(editSession: EditSession): Promise { + await this.initialize(); + if (!this.initialized) { + throw new Error('Please sign in to store your edit session.'); + } + + return this.storeClient!.write('editSessions', JSON.stringify(editSession), null); + } + + /** + * @param ref: A specific content ref to retrieve content for, if it exists. + * If undefined, this method will return the latest saved edit session, if any. + * + * @returns An object representing the requested or latest edit session state, if any. + */ + async read(ref: string | undefined): Promise<{ ref: string; editSession: EditSession } | undefined> { + await this.initialize(); + if (!this.initialized) { + throw new Error('Please sign in to apply your latest edit session.'); + } + + let content: string | undefined | null; + try { + if (ref !== undefined) { + content = await this.storeClient?.resolveContent('editSessions', ref); + } else { + const result = await this.storeClient?.read('editSessions', null); + content = result?.content; + ref = result?.ref; + } + } catch (ex) { + this.logService.error(ex); + } + + // TODO@joyceerhl Validate session data, check schema version + return (content !== undefined && content !== null && ref !== undefined) ? { ref: ref, editSession: JSON.parse(content) } : undefined; + } + + async delete(ref: string) { + await this.initialize(); + if (!this.initialized) { + throw new Error(`Unable to delete edit session with ref ${ref}.`); + } + + try { + await this.storeClient?.delete('editSessions', ref); + } catch (ex) { + this.logService.error(ex); + } + } + + private async initialize() { + if (this.initialized) { + return; + } + this.initialized = await this.doInitialize(); + this.signedInContext.set(this.initialized); + } + + /** + * + * Ensures that the store client is initialized, + * meaning that authentication is configured and it + * can be used to communicate with the remote storage service + */ + private async doInitialize(): Promise { + // Wait for authentication extensions to be registered + await this.extensionService.whenInstalledExtensionsRegistered(); + + if (!this.serverConfiguration?.url) { + throw new Error('Unable to initialize sessions sync as session sync preference is not configured in product.json.'); + } + + if (!this.storeClient) { + this.storeClient = new UserDataSyncStoreClient(URI.parse(this.serverConfiguration.url), this.productService, this.requestService, this.logService, this.environmentService, this.fileService, this.storageService); + this._register(this.storeClient.onTokenFailed(() => { + this.logService.info('Clearing edit sessions authentication preference because of successive token failures.'); + this.clearAuthenticationPreference(); + })); + } + + // If we already have an existing auth session in memory, use that + if (this.#authenticationInfo !== undefined) { + return true; + } + + // If the user signed in previously and the session is still available, reuse that without prompting the user again + const existingSessionId = this.existingSessionId; + if (existingSessionId) { + this.logService.trace(`Searching for existing authentication session with ID ${existingSessionId}`); + const existing = await this.getExistingSession(); + if (existing !== undefined) { + this.logService.trace(`Found existing authentication session with ID ${existingSessionId}`); + this.#authenticationInfo = { sessionId: existing.session.id, token: existing.session.accessToken, providerId: existing.session.providerId }; + this.storeClient.setAuthToken(this.#authenticationInfo.token, this.#authenticationInfo.providerId); + return true; + } + } + + // Ask the user to pick a preferred account + const session = await this.getAccountPreference(); + if (session !== undefined) { + this.#authenticationInfo = { sessionId: session.id, token: session.accessToken, providerId: session.providerId }; + this.storeClient.setAuthToken(this.#authenticationInfo.token, this.#authenticationInfo.providerId); + this.existingSessionId = session.id; + this.logService.trace(`Saving authentication session preference for ID ${session.id}.`); + return true; + } + + return false; + } + + /** + * + * Prompts the user to pick an authentication option for storing and getting edit sessions. + */ + private async getAccountPreference(): Promise { + const quickpick = this.quickInputService.createQuickPick(); + quickpick.title = localize('account preference', 'Sign In to Use Edit Sessions'); + quickpick.ok = false; + quickpick.placeholder = localize('choose account placeholder', "Select an account to sign in"); + quickpick.ignoreFocusOut = true; + quickpick.items = await this.createQuickpickItems(); + + return new Promise((resolve, reject) => { + quickpick.onDidHide((e) => { + resolve(undefined); + quickpick.dispose(); + }); + + quickpick.onDidAccept(async (e) => { + const selection = quickpick.selectedItems[0]; + const session = 'provider' in selection ? { ...await this.authenticationService.createSession(selection.provider.id, selection.provider.scopes), providerId: selection.provider.id } : selection.session; + resolve(session); + quickpick.hide(); + }); + + quickpick.show(); + }); + } + + private async createQuickpickItems(): Promise<(ExistingSession | AuthenticationProviderOption | IQuickPickSeparator)[]> { + const options: (ExistingSession | AuthenticationProviderOption | IQuickPickSeparator)[] = []; + + options.push({ type: 'separator', label: localize('signed in', "Signed In") }); + + const sessions = await this.getAllSessions(); + options.push(...sessions); + + options.push({ type: 'separator', label: localize('others', "Others") }); + + for (const authenticationProvider of (await this.getAuthenticationProviders())) { + const signedInForProvider = sessions.some(account => account.session.providerId === authenticationProvider.id); + if (!signedInForProvider || this.authenticationService.supportsMultipleAccounts(authenticationProvider.id)) { + const providerName = this.authenticationService.getLabel(authenticationProvider.id); + options.push({ label: localize('sign in using account', "Sign in with {0}", providerName), provider: authenticationProvider }); + } + } + + return options; + } + + /** + * + * Returns all authentication sessions available from {@link getAuthenticationProviders}. + */ + private async getAllSessions() { + const authenticationProviders = await this.getAuthenticationProviders(); + const accounts = new Map(); + let currentSession: ExistingSession | undefined; + + for (const provider of authenticationProviders) { + const sessions = await this.authenticationService.getSessions(provider.id, provider.scopes); + + for (const session of sessions) { + const item = { + label: session.account.label, + description: this.authenticationService.getLabel(provider.id), + session: { ...session, providerId: provider.id } + }; + accounts.set(item.session.account.id, item); + if (this.existingSessionId === session.id) { + currentSession = item; + } + } + } + + if (currentSession !== undefined) { + accounts.set(currentSession.session.account.id, currentSession); + } + + return [...accounts.values()]; + } + + /** + * + * Returns all authentication providers which can be used to authenticate + * to the remote storage service, based on product.json configuration + * and registered authentication providers. + */ + private async getAuthenticationProviders() { + if (!this.serverConfiguration) { + throw new Error('Unable to get configured authentication providers as session sync preference is not configured in product.json.'); + } + + // Get the list of authentication providers configured in product.json + const authenticationProviders = this.serverConfiguration.authenticationProviders; + const configuredAuthenticationProviders = Object.keys(authenticationProviders).reduce((result, id) => { + result.push({ id, scopes: authenticationProviders[id].scopes }); + return result; + }, []); + + // Filter out anything that isn't currently available through the authenticationService + const availableAuthenticationProviders = this.authenticationService.declaredProviders; + + return configuredAuthenticationProviders.filter(({ id }) => availableAuthenticationProviders.some(provider => provider.id === id)); + } + + private get existingSessionId() { + return this.storageService.get(SessionSyncWorkbenchService.CACHED_SESSION_STORAGE_KEY, StorageScope.APPLICATION); + } + + private set existingSessionId(sessionId: string | undefined) { + if (sessionId === undefined) { + this.storageService.remove(SessionSyncWorkbenchService.CACHED_SESSION_STORAGE_KEY, StorageScope.APPLICATION); + } else { + this.storageService.store(SessionSyncWorkbenchService.CACHED_SESSION_STORAGE_KEY, sessionId, StorageScope.APPLICATION, StorageTarget.MACHINE); + } + } + + private async getExistingSession() { + const accounts = await this.getAllSessions(); + return accounts.find((account) => account.session.id === this.existingSessionId); + } + + private async onDidChangeStorage(e: IStorageValueChangeEvent): Promise { + if (e.key === SessionSyncWorkbenchService.CACHED_SESSION_STORAGE_KEY + && e.scope === StorageScope.APPLICATION + ) { + const newSessionId = this.existingSessionId; + const previousSessionId = this.#authenticationInfo?.sessionId; + + if (previousSessionId !== newSessionId) { + this.logService.trace(`Resetting authentication state because authentication session ID preference changed from ${previousSessionId} to ${newSessionId}.`); + this.#authenticationInfo = undefined; + this.initialized = false; + } + } + } + + private clearAuthenticationPreference(): void { + this.#authenticationInfo = undefined; + this.initialized = false; + this.existingSessionId = undefined; + this.signedInContext.set(false); + } + + private onDidChangeSessions(e: AuthenticationSessionsChangeEvent): void { + if (this.#authenticationInfo?.sessionId && e.removed.find(session => session.id === this.#authenticationInfo?.sessionId)) { + this.clearAuthenticationPreference(); + } + } + + private registerResetAuthenticationAction() { + const that = this; + this._register(registerAction2(class ResetEditSessionAuthenticationAction extends Action2 { + constructor() { + super({ + id: 'workbench.sessionSync.actions.resetAuth', + title: localize('reset auth', 'Sign Out'), + category: EDIT_SESSION_SYNC_CATEGORY, + precondition: ContextKeyExpr.equals(EDIT_SESSIONS_SIGNED_IN_KEY, true), + menu: [{ + id: MenuId.CommandPalette, + }, + { + id: MenuId.AccountsContext, + group: '2_editSessions', + when: ContextKeyExpr.equals(EDIT_SESSIONS_SIGNED_IN_KEY, true), + }] + }); + } + + run() { + that.clearAuthenticationPreference(); + } + })); + } +} diff --git a/src/vs/workbench/contrib/sessionSync/common/editSessionsLogService.ts b/src/vs/workbench/contrib/sessionSync/common/editSessionsLogService.ts new file mode 100644 index 00000000000..2b3b6bca671 --- /dev/null +++ b/src/vs/workbench/contrib/sessionSync/common/editSessionsLogService.ts @@ -0,0 +1,50 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { AbstractLogger, ILogger, ILoggerService } from 'vs/platform/log/common/log'; +import { IEditSessionsLogService } from 'vs/workbench/contrib/sessionSync/common/sessionSync'; + +export class EditSessionsLogService extends AbstractLogger implements IEditSessionsLogService { + + declare readonly _serviceBrand: undefined; + private readonly logger: ILogger; + + constructor( + @ILoggerService loggerService: ILoggerService, + @IEnvironmentService environmentService: IEnvironmentService + ) { + super(); + this.logger = this._register(loggerService.createLogger(environmentService.editSessionsLogResource, { name: 'editsessions' })); + } + + trace(message: string, ...args: any[]): void { + this.logger.trace(message, ...args); + } + + debug(message: string, ...args: any[]): void { + this.logger.debug(message, ...args); + } + + info(message: string, ...args: any[]): void { + this.logger.info(message, ...args); + } + + warn(message: string, ...args: any[]): void { + this.logger.warn(message, ...args); + } + + error(message: string | Error, ...args: any[]): void { + this.logger.error(message, ...args); + } + + critical(message: string | Error, ...args: any[]): void { + this.logger.critical(message, ...args); + } + + flush(): void { + this.logger.flush(); + } +} diff --git a/src/vs/workbench/contrib/sessionSync/common/sessionSync.ts b/src/vs/workbench/contrib/sessionSync/common/sessionSync.ts new file mode 100644 index 00000000000..538a54a6444 --- /dev/null +++ b/src/vs/workbench/contrib/sessionSync/common/sessionSync.ts @@ -0,0 +1,67 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize } from 'vs/nls'; +import { ILocalizedString } from 'vs/platform/action/common/action'; +import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { ILogService } from 'vs/platform/log/common/log'; + +export const EDIT_SESSION_SYNC_CATEGORY: ILocalizedString = { + original: 'Edit Sessions', + value: localize('session sync', 'Edit Sessions') +}; + +export const ISessionSyncWorkbenchService = createDecorator('ISessionSyncWorkbenchService'); +export interface ISessionSyncWorkbenchService { + _serviceBrand: undefined; + + read(ref: string | undefined): Promise<{ ref: string; editSession: EditSession } | undefined>; + write(editSession: EditSession): Promise; + delete(ref: string): Promise; +} + +export const IEditSessionsLogService = createDecorator('IEditSessionsLogService'); +export interface IEditSessionsLogService extends ILogService { } + +export enum ChangeType { + Addition = 1, + Deletion = 2, +} + +export enum FileType { + File = 1, +} + +interface Addition { + relativeFilePath: string; + fileType: FileType.File; + contents: string; + type: ChangeType.Addition; +} + +interface Deletion { + relativeFilePath: string; + fileType: FileType.File; + contents: undefined; + type: ChangeType.Deletion; +} + +export type Change = Addition | Deletion; + +export interface Folder { + name: string; + workingChanges: Change[]; +} + +export const EditSessionSchemaVersion = 1; + +export interface EditSession { + version: number; + folders: Folder[]; +} + +export const EDIT_SESSIONS_SIGNED_IN_KEY = 'editSessionsSignedIn'; +export const EDIT_SESSIONS_SIGNED_IN = new RawContextKey(EDIT_SESSIONS_SIGNED_IN_KEY, false); diff --git a/src/vs/workbench/contrib/sessionSync/test/browser/sessionSync.test.ts b/src/vs/workbench/contrib/sessionSync/test/browser/sessionSync.test.ts index 5c29394116b..140c068d5d0 100644 --- a/src/vs/workbench/contrib/sessionSync/test/browser/sessionSync.test.ts +++ b/src/vs/workbench/contrib/sessionSync/test/browser/sessionSync.test.ts @@ -9,7 +9,7 @@ import { FileService } from 'vs/platform/files/common/fileService'; import { Schemas } from 'vs/base/common/network'; import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; -import { NullLogService, ILogService } from 'vs/platform/log/common/log'; +import { NullLogService } from 'vs/platform/log/common/log'; import { SessionSyncContribution } from 'vs/workbench/contrib/sessionSync/browser/sessionSync.contribution'; import { ProgressService } from 'vs/workbench/services/progress/browser/progressService'; import { IProgressService } from 'vs/platform/progress/common/progress'; @@ -21,7 +21,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace import { mock } from 'vs/base/test/common/mock'; import * as sinon from 'sinon'; import * as assert from 'assert'; -import { ChangeType, FileType, ISessionSyncWorkbenchService } from 'vs/workbench/services/sessionSync/common/sessionSync'; +import { ChangeType, FileType, IEditSessionsLogService, ISessionSyncWorkbenchService } from 'vs/workbench/contrib/sessionSync/common/sessionSync'; import { URI } from 'vs/base/common/uri'; import { joinPath } from 'vs/base/common/resources'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -52,7 +52,7 @@ suite('Edit session sync', () => { fileService.registerProvider(Schemas.file, fileSystemProvider); // Stub out all services - instantiationService.stub(ILogService, logService); + instantiationService.stub(IEditSessionsLogService, logService); instantiationService.stub(IFileService, fileService); instantiationService.stub(INotificationService, new TestNotificationService()); instantiationService.stub(ISessionSyncWorkbenchService, new class extends mock() { }); diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index 631b3db439e..82a2541576a 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -83,6 +83,9 @@ export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvi @memoize get userDataSyncLogResource(): URI { return joinPath(this.logsHome, 'userDataSync.log'); } + @memoize + get editSessionsLogResource(): URI { return joinPath(this.logsHome, 'editSessions.log'); } + @memoize get sync(): 'on' | 'off' | undefined { return undefined; } diff --git a/src/vs/workbench/services/sessionSync/browser/sessionSyncWorkbenchService.ts b/src/vs/workbench/services/sessionSync/browser/sessionSyncWorkbenchService.ts deleted file mode 100644 index 4274c62031d..00000000000 --- a/src/vs/workbench/services/sessionSync/browser/sessionSyncWorkbenchService.ts +++ /dev/null @@ -1,359 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Disposable } from 'vs/base/common/lifecycle'; -import { URI } from 'vs/base/common/uri'; -import { localize } from 'vs/nls'; -import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; -import { ContextKeyExpr, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IFileService } from 'vs/platform/files/common/files'; -import { ILogService } from 'vs/platform/log/common/log'; -import { IProductService } from 'vs/platform/product/common/productService'; -import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; -import { IRequestService } from 'vs/platform/request/common/request'; -import { IStorageService, IStorageValueChangeEvent, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; -import { IAuthenticationProvider } from 'vs/platform/userDataSync/common/userDataSync'; -import { UserDataSyncStoreClient } from 'vs/platform/userDataSync/common/userDataSyncStoreService'; -import { AuthenticationSession, AuthenticationSessionsChangeEvent, IAuthenticationService } from 'vs/workbench/services/authentication/common/authentication'; -import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { EDIT_SESSIONS_SIGNED_IN, EditSession, EDIT_SESSION_SYNC_CATEGORY, ISessionSyncWorkbenchService, EDIT_SESSIONS_SIGNED_IN_KEY } from 'vs/workbench/services/sessionSync/common/sessionSync'; - -type ExistingSession = IQuickPickItem & { session: AuthenticationSession & { providerId: string } }; -type AuthenticationProviderOption = IQuickPickItem & { provider: IAuthenticationProvider }; - -export class SessionSyncWorkbenchService extends Disposable implements ISessionSyncWorkbenchService { - - _serviceBrand = undefined; - - private serverConfiguration = this.productService['sessionSync.store']; - private storeClient: UserDataSyncStoreClient | undefined; - - #authenticationInfo: { sessionId: string; token: string; providerId: string } | undefined; - private static CACHED_SESSION_STORAGE_KEY = 'editSessionSyncAccountPreference'; - - private initialized = false; - private readonly signedInContext: IContextKey; - - constructor( - @IFileService private readonly fileService: IFileService, - @IStorageService private readonly storageService: IStorageService, - @IQuickInputService private readonly quickInputService: IQuickInputService, - @IAuthenticationService private readonly authenticationService: IAuthenticationService, - @IExtensionService private readonly extensionService: IExtensionService, - @IEnvironmentService private readonly environmentService: IEnvironmentService, - @ILogService private readonly logService: ILogService, - @IProductService private readonly productService: IProductService, - @IContextKeyService private readonly contextKeyService: IContextKeyService, - @IRequestService private readonly requestService: IRequestService, - ) { - super(); - - // If the user signs out of the current session, reset our cached auth state in memory and on disk - this._register(this.authenticationService.onDidChangeSessions((e) => this.onDidChangeSessions(e.event))); - - // If another window changes the preferred session storage, reset our cached auth state in memory - this._register(this.storageService.onDidChangeValue(e => this.onDidChangeStorage(e))); - - this.registerResetAuthenticationAction(); - - this.signedInContext = EDIT_SESSIONS_SIGNED_IN.bindTo(this.contextKeyService); - this.signedInContext.set(this.existingSessionId !== undefined); - } - - /** - * - * @param editSession An object representing edit session state to be restored. - * @returns The ref of the stored edit session state. - */ - async write(editSession: EditSession): Promise { - await this.initialize(); - if (!this.initialized) { - throw new Error('Please sign in to store your edit session.'); - } - - return this.storeClient!.write('editSessions', JSON.stringify(editSession), null); - } - - /** - * @param ref: A specific content ref to retrieve content for, if it exists. - * If undefined, this method will return the latest saved edit session, if any. - * - * @returns An object representing the requested or latest edit session state, if any. - */ - async read(ref: string | undefined): Promise<{ ref: string; editSession: EditSession } | undefined> { - await this.initialize(); - if (!this.initialized) { - throw new Error('Please sign in to apply your latest edit session.'); - } - - let content: string | undefined | null; - try { - if (ref !== undefined) { - content = await this.storeClient?.resolveContent('editSessions', ref); - } else { - const result = await this.storeClient?.read('editSessions', null); - content = result?.content; - ref = result?.ref; - } - } catch (ex) { - this.logService.error(ex); - } - - // TODO@joyceerhl Validate session data, check schema version - return (content !== undefined && content !== null && ref !== undefined) ? { ref: ref, editSession: JSON.parse(content) } : undefined; - } - - async delete(ref: string) { - await this.initialize(); - if (!this.initialized) { - throw new Error(`Unable to delete edit session with ref ${ref}.`); - } - - try { - await this.storeClient?.delete('editSessions', ref); - } catch (ex) { - this.logService.error(ex); - } - } - - private async initialize() { - if (this.initialized) { - return; - } - this.initialized = await this.doInitialize(); - this.signedInContext.set(this.initialized); - } - - /** - * - * Ensures that the store client is initialized, - * meaning that authentication is configured and it - * can be used to communicate with the remote storage service - */ - private async doInitialize(): Promise { - // Wait for authentication extensions to be registered - await this.extensionService.whenInstalledExtensionsRegistered(); - - if (!this.serverConfiguration?.url) { - throw new Error('Unable to initialize sessions sync as session sync preference is not configured in product.json.'); - } - - if (!this.storeClient) { - this.storeClient = new UserDataSyncStoreClient(URI.parse(this.serverConfiguration.url), this.productService, this.requestService, this.logService, this.environmentService, this.fileService, this.storageService); - this._register(this.storeClient.onTokenFailed(() => { - this.logService.info('Edit Sessions: clearing edit sessions authentication preference because of successive token failures.'); - this.clearAuthenticationPreference(); - })); - } - - // If we already have an existing auth session in memory, use that - if (this.#authenticationInfo !== undefined) { - return true; - } - - // If the user signed in previously and the session is still available, reuse that without prompting the user again - const existingSessionId = this.existingSessionId; - if (existingSessionId) { - this.logService.trace(`Edit Sessions: Searching for existing authentication session with ID ${existingSessionId}`); - const existing = await this.getExistingSession(); - if (existing !== undefined) { - this.logService.trace(`Edit Sessions: Found existing authentication session with ID ${existingSessionId}`); - this.#authenticationInfo = { sessionId: existing.session.id, token: existing.session.accessToken, providerId: existing.session.providerId }; - this.storeClient.setAuthToken(this.#authenticationInfo.token, this.#authenticationInfo.providerId); - return true; - } - } - - // Ask the user to pick a preferred account - const session = await this.getAccountPreference(); - if (session !== undefined) { - this.#authenticationInfo = { sessionId: session.id, token: session.accessToken, providerId: session.providerId }; - this.storeClient.setAuthToken(this.#authenticationInfo.token, this.#authenticationInfo.providerId); - this.existingSessionId = session.id; - this.logService.trace(`Edit Sessions: Saving authentication session preference for ID ${session.id}.`); - return true; - } - - return false; - } - - /** - * - * Prompts the user to pick an authentication option for storing and getting edit sessions. - */ - private async getAccountPreference(): Promise { - const quickpick = this.quickInputService.createQuickPick(); - quickpick.title = localize('account preference', 'Sign In to Use Edit Sessions'); - quickpick.ok = false; - quickpick.placeholder = localize('choose account placeholder', "Select an account to sign in"); - quickpick.ignoreFocusOut = true; - quickpick.items = await this.createQuickpickItems(); - - return new Promise((resolve, reject) => { - quickpick.onDidHide((e) => { - resolve(undefined); - quickpick.dispose(); - }); - - quickpick.onDidAccept(async (e) => { - const selection = quickpick.selectedItems[0]; - const session = 'provider' in selection ? { ...await this.authenticationService.createSession(selection.provider.id, selection.provider.scopes), providerId: selection.provider.id } : selection.session; - resolve(session); - quickpick.hide(); - }); - - quickpick.show(); - }); - } - - private async createQuickpickItems(): Promise<(ExistingSession | AuthenticationProviderOption | IQuickPickSeparator)[]> { - const options: (ExistingSession | AuthenticationProviderOption | IQuickPickSeparator)[] = []; - - options.push({ type: 'separator', label: localize('signed in', "Signed In") }); - - const sessions = await this.getAllSessions(); - options.push(...sessions); - - options.push({ type: 'separator', label: localize('others', "Others") }); - - for (const authenticationProvider of (await this.getAuthenticationProviders())) { - const signedInForProvider = sessions.some(account => account.session.providerId === authenticationProvider.id); - if (!signedInForProvider || this.authenticationService.supportsMultipleAccounts(authenticationProvider.id)) { - const providerName = this.authenticationService.getLabel(authenticationProvider.id); - options.push({ label: localize('sign in using account', "Sign in with {0}", providerName), provider: authenticationProvider }); - } - } - - return options; - } - - /** - * - * Returns all authentication sessions available from {@link getAuthenticationProviders}. - */ - private async getAllSessions() { - const authenticationProviders = await this.getAuthenticationProviders(); - const accounts = new Map(); - let currentSession: ExistingSession | undefined; - - for (const provider of authenticationProviders) { - const sessions = await this.authenticationService.getSessions(provider.id, provider.scopes); - - for (const session of sessions) { - const item = { - label: session.account.label, - description: this.authenticationService.getLabel(provider.id), - session: { ...session, providerId: provider.id } - }; - accounts.set(item.session.account.id, item); - if (this.existingSessionId === session.id) { - currentSession = item; - } - } - } - - if (currentSession !== undefined) { - accounts.set(currentSession.session.account.id, currentSession); - } - - return [...accounts.values()]; - } - - /** - * - * Returns all authentication providers which can be used to authenticate - * to the remote storage service, based on product.json configuration - * and registered authentication providers. - */ - private async getAuthenticationProviders() { - if (!this.serverConfiguration) { - throw new Error('Unable to get configured authentication providers as session sync preference is not configured in product.json.'); - } - - // Get the list of authentication providers configured in product.json - const authenticationProviders = this.serverConfiguration.authenticationProviders; - const configuredAuthenticationProviders = Object.keys(authenticationProviders).reduce((result, id) => { - result.push({ id, scopes: authenticationProviders[id].scopes }); - return result; - }, []); - - // Filter out anything that isn't currently available through the authenticationService - const availableAuthenticationProviders = this.authenticationService.declaredProviders; - - return configuredAuthenticationProviders.filter(({ id }) => availableAuthenticationProviders.some(provider => provider.id === id)); - } - - private get existingSessionId() { - return this.storageService.get(SessionSyncWorkbenchService.CACHED_SESSION_STORAGE_KEY, StorageScope.APPLICATION); - } - - private set existingSessionId(sessionId: string | undefined) { - if (sessionId === undefined) { - this.storageService.remove(SessionSyncWorkbenchService.CACHED_SESSION_STORAGE_KEY, StorageScope.APPLICATION); - } else { - this.storageService.store(SessionSyncWorkbenchService.CACHED_SESSION_STORAGE_KEY, sessionId, StorageScope.APPLICATION, StorageTarget.MACHINE); - } - } - - private async getExistingSession() { - const accounts = await this.getAllSessions(); - return accounts.find((account) => account.session.id === this.existingSessionId); - } - - private async onDidChangeStorage(e: IStorageValueChangeEvent): Promise { - if (e.key === SessionSyncWorkbenchService.CACHED_SESSION_STORAGE_KEY - && e.scope === StorageScope.APPLICATION - ) { - const newSessionId = this.existingSessionId; - const previousSessionId = this.#authenticationInfo?.sessionId; - - if (previousSessionId !== newSessionId) { - this.logService.trace(`Edit Sessions: resetting authentication state because authentication session ID preference changed from ${previousSessionId} to ${newSessionId}.`); - this.#authenticationInfo = undefined; - this.initialized = false; - } - } - } - - private clearAuthenticationPreference(): void { - this.#authenticationInfo = undefined; - this.initialized = false; - this.existingSessionId = undefined; - this.signedInContext.set(false); - } - - private onDidChangeSessions(e: AuthenticationSessionsChangeEvent): void { - if (this.#authenticationInfo?.sessionId && e.removed.find(session => session.id === this.#authenticationInfo?.sessionId)) { - this.clearAuthenticationPreference(); - } - } - - private registerResetAuthenticationAction() { - const that = this; - this._register(registerAction2(class ResetEditSessionAuthenticationAction extends Action2 { - constructor() { - super({ - id: 'workbench.sessionSync.actions.resetAuth', - title: localize('reset auth', 'Sign Out'), - category: EDIT_SESSION_SYNC_CATEGORY, - precondition: ContextKeyExpr.equals(EDIT_SESSIONS_SIGNED_IN_KEY, true), - menu: [{ - id: MenuId.CommandPalette, - }, - { - id: MenuId.AccountsContext, - group: '2_editSessions', - when: ContextKeyExpr.equals(EDIT_SESSIONS_SIGNED_IN_KEY, true), - }] - }); - } - - run() { - that.clearAuthenticationPreference(); - } - })); - } -} diff --git a/src/vs/workbench/services/sessionSync/common/sessionSync.ts b/src/vs/workbench/services/sessionSync/common/sessionSync.ts deleted file mode 100644 index c671ae2aeab..00000000000 --- a/src/vs/workbench/services/sessionSync/common/sessionSync.ts +++ /dev/null @@ -1,63 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { localize } from 'vs/nls'; -import { ILocalizedString } from 'vs/platform/action/common/action'; -import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; - -export const EDIT_SESSION_SYNC_CATEGORY: ILocalizedString = { - original: 'Edit Sessions', - value: localize('session sync', 'Edit Sessions') -}; - -export const ISessionSyncWorkbenchService = createDecorator('ISessionSyncWorkbenchService'); -export interface ISessionSyncWorkbenchService { - _serviceBrand: undefined; - - read(ref: string | undefined): Promise<{ ref: string; editSession: EditSession } | undefined>; - write(editSession: EditSession): Promise; - delete(ref: string): Promise; -} - -export enum ChangeType { - Addition = 1, - Deletion = 2, -} - -export enum FileType { - File = 1, -} - -interface Addition { - relativeFilePath: string; - fileType: FileType.File; - contents: string; - type: ChangeType.Addition; -} - -interface Deletion { - relativeFilePath: string; - fileType: FileType.File; - contents: undefined; - type: ChangeType.Deletion; -} - -export type Change = Addition | Deletion; - -export interface Folder { - name: string; - workingChanges: Change[]; -} - -export const EditSessionSchemaVersion = 1; - -export interface EditSession { - version: number; - folders: Folder[]; -} - -export const EDIT_SESSIONS_SIGNED_IN_KEY = 'editSessionsSignedIn'; -export const EDIT_SESSIONS_SIGNED_IN = new RawContextKey(EDIT_SESSIONS_SIGNED_IN_KEY, false); -- cgit v1.2.3 From a08b7bb4d7f0427d515963d71beb50fc493cc0da Mon Sep 17 00:00:00 2001 From: Tomer Chachamu Date: Tue, 5 Jul 2022 22:53:02 +0100 Subject: Fix test error not showing when expanded (#153994) --- .../contrib/testing/browser/explorerProjections/nodeHelper.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/testing/browser/explorerProjections/nodeHelper.ts b/src/vs/workbench/contrib/testing/browser/explorerProjections/nodeHelper.ts index 0f0d26be6b4..6a74365ede4 100644 --- a/src/vs/workbench/contrib/testing/browser/explorerProjections/nodeHelper.ts +++ b/src/vs/workbench/contrib/testing/browser/explorerProjections/nodeHelper.ts @@ -6,11 +6,11 @@ import { IIdentityProvider } from 'vs/base/browser/ui/list/list'; import { ObjectTree } from 'vs/base/browser/ui/tree/objectTree'; import { ITreeElement } from 'vs/base/browser/ui/tree/tree'; -import { IActionableTestTreeElement, TestExplorerTreeElement, TestItemTreeElement } from 'vs/workbench/contrib/testing/browser/explorerProjections/index'; +import { IActionableTestTreeElement, TestExplorerTreeElement, TestItemTreeElement, TestTreeErrorMessage } from 'vs/workbench/contrib/testing/browser/explorerProjections/index'; -export const testIdentityProvider: IIdentityProvider = { +export const testIdentityProvider: IIdentityProvider = { getId(element) { - return element.treeId + '\0' + element.test.expand; + return element.treeId + '\0' + (element instanceof TestTreeErrorMessage ? 'error' : element.test.expand); } }; -- cgit v1.2.3 From 3862aa876e95b4fe76922349e8c440092dc4bf6c Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Tue, 5 Jul 2022 14:57:52 -0700 Subject: Debt - clean up edit session action option declaration (#154202) Debt - clean up action option declaration --- .../browser/sessionSync.contribution.ts | 46 ++++++++-------------- 1 file changed, 17 insertions(+), 29 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts b/src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts index 642ab0ce273..a4cf8be1f5f 100644 --- a/src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts +++ b/src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts @@ -7,7 +7,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { Registry } from 'vs/platform/registry/common/platform'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; -import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; +import { Action2, IAction2Options, registerAction2 } from 'vs/platform/actions/common/actions'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { localize } from 'vs/nls'; import { ISessionSyncWorkbenchService, Change, ChangeType, Folder, EditSession, FileType, EDIT_SESSION_SYNC_CATEGORY, EditSessionSchemaVersion, IEditSessionsLogService } from 'vs/workbench/contrib/sessionSync/common/sessionSync'; @@ -43,23 +43,17 @@ import { EditSessionsLogService } from 'vs/workbench/contrib/sessionSync/common/ registerSingleton(IEditSessionsLogService, EditSessionsLogService); registerSingleton(ISessionSyncWorkbenchService, SessionSyncWorkbenchService); -const resumeLatestCommand = { - id: 'workbench.experimental.editSessions.actions.resumeLatest', - title: { value: localize('resume latest', "Resume Latest Edit Session"), original: 'Resume Latest Edit Session' }, - category: EDIT_SESSION_SYNC_CATEGORY, -}; -const storeCurrentCommand = { - id: 'workbench.experimental.editSessions.actions.storeCurrent', - title: { value: localize('store current', "Store Current Edit Session"), original: 'Store Current Edit Session' }, - category: EDIT_SESSION_SYNC_CATEGORY, -}; -const continueEditSessionCommand = { +const continueEditSessionCommand: IAction2Options = { id: '_workbench.experimental.editSessions.actions.continueEditSession', title: { value: localize('continue edit session', "Continue Edit Session..."), original: 'Continue Edit Session...' }, + category: EDIT_SESSION_SYNC_CATEGORY, + f1: true }; -const openLocalFolderCommand = { +const openLocalFolderCommand: IAction2Options = { id: '_workbench.experimental.editSessions.actions.continueEditSession.openLocalFolder', title: { value: localize('continue edit session in local folder', "Open In Local Folder"), original: 'Open In Local Folder' }, + category: EDIT_SESSION_SYNC_CATEGORY, + precondition: IsWebContext }; const queryParamName = 'editSessionId'; const experimentalSettingName = 'workbench.experimental.editSessions.enabled'; @@ -150,10 +144,7 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon const that = this; this._register(registerAction2(class ContinueEditSessionAction extends Action2 { constructor() { - super({ - ...continueEditSessionCommand, - f1: true - }); + super(continueEditSessionCommand); } async run(accessor: ServicesAccessor, workspaceUri: URI | undefined): Promise { @@ -185,10 +176,10 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon this._register(registerAction2(class ApplyLatestEditSessionAction extends Action2 { constructor() { super({ - ...resumeLatestCommand, - menu: { - id: MenuId.CommandPalette, - } + id: 'workbench.experimental.editSessions.actions.resumeLatest', + title: { value: localize('resume latest.v2', "Resume Latest Edit Session"), original: 'Resume Latest Edit Session' }, + category: EDIT_SESSION_SYNC_CATEGORY, + f1: true, }); } @@ -206,10 +197,10 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon this._register(registerAction2(class StoreLatestEditSessionAction extends Action2 { constructor() { super({ - ...storeCurrentCommand, - menu: { - id: MenuId.CommandPalette, - } + id: 'workbench.experimental.editSessions.actions.storeCurrent', + title: { value: localize('store current.v2', "Store Current Edit Session"), original: 'Store Current Edit Session' }, + category: EDIT_SESSION_SYNC_CATEGORY, + f1: true, }); } @@ -400,10 +391,7 @@ export class SessionSyncContribution extends Disposable implements IWorkbenchCon const that = this; this._register(registerAction2(class ContinueInLocalFolderAction extends Action2 { constructor() { - super({ - ...openLocalFolderCommand, - precondition: IsWebContext - }); + super(openLocalFolderCommand); } async run(accessor: ServicesAccessor): Promise { -- cgit v1.2.3 From 9c5408c04a614e641d7a69680686cb9346e0d7a8 Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Tue, 5 Jul 2022 20:39:22 -0400 Subject: Detect terminal links with space, then line:col (#153957) --- .../contrib/terminal/browser/links/terminalLocalLinkDetector.ts | 1 + .../terminal/test/browser/links/terminalLocalLinkDetector.test.ts | 1 + 2 files changed, 2 insertions(+) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/links/terminalLocalLinkDetector.ts b/src/vs/workbench/contrib/terminal/browser/links/terminalLocalLinkDetector.ts index 19cab952add..cec80cf90b1 100644 --- a/src/vs/workbench/contrib/terminal/browser/links/terminalLocalLinkDetector.ts +++ b/src/vs/workbench/contrib/terminal/browser/links/terminalLocalLinkDetector.ts @@ -49,6 +49,7 @@ export const winLocalLinkClause = '((' + winPathPrefix + '|(' + winExcludedPathC /** As xterm reads from DOM, space in that case is nonbreaking char ASCII code - 160, replacing space with nonBreakningSpace or space ASCII code - 32. */ export const lineAndColumnClause = [ + '(([^:\\s\\(\\)<>\'\"\\[\\]]*) ((\\d+))(:(\\d+)))', // (file path) 336:9 [see #140780] '((\\S*)[\'"], line ((\\d+)( column (\\d+))?))', // "(file path)", line 45 [see #40468] '((\\S*)[\'"],((\\d+)(:(\\d+))?))', // "(file path)",45 [see #78205] '((\\S*) on line ((\\d+)(, column (\\d+))?))', // (file path) on line 8, column 13 diff --git a/src/vs/workbench/contrib/terminal/test/browser/links/terminalLocalLinkDetector.test.ts b/src/vs/workbench/contrib/terminal/test/browser/links/terminalLocalLinkDetector.test.ts index 9f72ece8c18..93ff1ce3687 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/links/terminalLocalLinkDetector.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/links/terminalLocalLinkDetector.test.ts @@ -68,6 +68,7 @@ const supportedLinkFormats: LinkFormatInfo[] = [ { urlFormat: '{0} ({1}, {2})', line: '5', column: '3' }, { urlFormat: '{0}:{1}', line: '5' }, { urlFormat: '{0}:{1}:{2}', line: '5', column: '3' }, + { urlFormat: '{0} {1}:{2}', line: '5', column: '3' }, { urlFormat: '{0}[{1}]', line: '5' }, { urlFormat: '{0} [{1}]', line: '5' }, { urlFormat: '{0}[{1},{2}]', line: '5', column: '3' }, -- cgit v1.2.3 From 0b07495a5526a0d30a579bbe873df5fc54454d60 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 6 Jul 2022 07:21:07 +0200 Subject: electron - log unexpected `setJumpList` result (#154228) --- .../workspaces/electron-main/workspacesHistoryMainService.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts b/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts index 3801775bee0..2f29d96f1ab 100644 --- a/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts +++ b/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts @@ -377,7 +377,10 @@ export class WorkspacesHistoryMainService extends Disposable implements IWorkspa }); try { - app.setJumpList(jumpList); + const res = app.setJumpList(jumpList); + if (res && res !== 'ok') { + this.logService.warn(`updateWindowsJumpList#setJumpList unexpected result: ${res}`); + } } catch (error) { this.logService.warn('updateWindowsJumpList#setJumpList', error); // since setJumpList is relatively new API, make sure to guard for errors } -- cgit v1.2.3 From f89c103f1162e800043182cabf0de6f15e1adc51 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 6 Jul 2022 07:52:24 +0200 Subject: storage - :lipstick: (#154230) --- .../storage/electron-sandbox/storageService.ts | 24 ++++++++-------------- .../services/storage/browser/storageService.ts | 2 +- 2 files changed, 10 insertions(+), 16 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/storage/electron-sandbox/storageService.ts b/src/vs/platform/storage/electron-sandbox/storageService.ts index 9a27bd23135..d5bf2548f20 100644 --- a/src/vs/platform/storage/electron-sandbox/storageService.ts +++ b/src/vs/platform/storage/electron-sandbox/storageService.ts @@ -16,30 +16,24 @@ import { IAnyWorkspaceIdentifier, IEmptyWorkspaceIdentifier, ISingleFolderWorksp export class NativeStorageService extends AbstractStorageService { - private readonly applicationStorage: IStorage; - private readonly applicationStorageProfile: IUserDataProfile; + private readonly applicationStorageProfile = this.initialProfiles.defaultProfile; + private readonly applicationStorage = this.createApplicationStorage(); - private profileStorage: IStorage; - private profileStorageProfile: IUserDataProfile | undefined = undefined; + private profileStorageProfile = this.initialProfiles.currentProfile; private readonly profileStorageDisposables = this._register(new DisposableStore()); + private profileStorage = this.createProfileStorage(this.profileStorageProfile); - private workspaceStorage: IStorage | undefined = undefined; - private workspaceStorageId: string | undefined = undefined; + private workspaceStorageId = this.initialWorkspace?.id; private readonly workspaceStorageDisposables = this._register(new DisposableStore()); + private workspaceStorage = this.createWorkspaceStorage(this.initialWorkspace); constructor( - workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | IEmptyWorkspaceIdentifier | undefined, - { defaultProfile, currentProfile }: { defaultProfile: IUserDataProfile; currentProfile: IUserDataProfile }, + private readonly initialWorkspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | IEmptyWorkspaceIdentifier | undefined, + private readonly initialProfiles: { defaultProfile: IUserDataProfile; currentProfile: IUserDataProfile }, private readonly mainProcessService: IMainProcessService, private readonly environmentService: IEnvironmentService ) { super(); - - this.applicationStorageProfile = defaultProfile; - - this.applicationStorage = this.createApplicationStorage(); - this.profileStorage = this.createProfileStorage(currentProfile); - this.workspaceStorage = this.createWorkspaceStorage(workspace); } private createApplicationStorage(): IStorage { @@ -148,7 +142,7 @@ export class NativeStorageService extends AbstractStorageService { } protected async switchToProfile(toProfile: IUserDataProfile, preserveData: boolean): Promise { - if (this.profileStorageProfile && !this.canSwitchProfile(this.profileStorageProfile, toProfile)) { + if (!this.canSwitchProfile(this.profileStorageProfile, toProfile)) { return; } diff --git a/src/vs/workbench/services/storage/browser/storageService.ts b/src/vs/workbench/services/storage/browser/storageService.ts index 694d8317a1f..a939ea7e567 100644 --- a/src/vs/workbench/services/storage/browser/storageService.ts +++ b/src/vs/workbench/services/storage/browser/storageService.ts @@ -166,7 +166,7 @@ export class BrowserStorageService extends AbstractStorageService { } protected async switchToProfile(toProfile: IUserDataProfile, preserveData: boolean): Promise { - if (this.profileStorageProfile && !this.canSwitchProfile(this.profileStorageProfile, toProfile)) { + if (!this.canSwitchProfile(this.profileStorageProfile, toProfile)) { return; } -- cgit v1.2.3 From c7e5301345e3d976f95f231a821e9e67555829cc Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 5 Jul 2022 22:54:58 -0700 Subject: fix #151986. Fix interactive window navigation. (#154200) fix #151986 --- .../browser/interactive.contribution.ts | 28 +++++++++++++++++----- .../interactive/browser/interactiveEditor.ts | 7 +++++- 2 files changed, 28 insertions(+), 7 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts index f108213e01b..c49ec5ad519 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts @@ -9,6 +9,7 @@ import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { parse } from 'vs/base/common/marshalling'; import { Schemas } from 'vs/base/common/network'; +import { extname } from 'vs/base/common/resources'; import { isFalsyOrWhitespace } from 'vs/base/common/strings'; import { assertType } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; @@ -25,7 +26,7 @@ import { localize } from 'vs/nls'; import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { EditorActivation } from 'vs/platform/editor/common/editor'; +import { EditorActivation, IResourceEditorInput } from 'vs/platform/editor/common/editor'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -48,9 +49,10 @@ import { InteractiveEditor } from 'vs/workbench/contrib/interactive/browser/inte import { InteractiveEditorInput } from 'vs/workbench/contrib/interactive/browser/interactiveEditorInput'; import { IInteractiveHistoryService, InteractiveHistoryService } from 'vs/workbench/contrib/interactive/browser/interactiveHistoryService'; import { NOTEBOOK_EDITOR_WIDGET_ACTION_WEIGHT } from 'vs/workbench/contrib/notebook/browser/controller/coreActions'; +import { INotebookEditorOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { NotebookEditorWidget } from 'vs/workbench/contrib/notebook/browser/notebookEditorWidget'; import * as icons from 'vs/workbench/contrib/notebook/browser/notebookIcons'; -import { CellEditType, CellKind, ICellOutput, NotebookSetting } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellEditType, CellKind, CellUri, ICellOutput, NotebookSetting } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService'; import { INotebookContentProvider, INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; import { columnToEditorGroup } from 'vs/workbench/services/editor/common/editorGroupColumn'; @@ -214,12 +216,26 @@ export class InteractiveDocumentContribution extends Disposable implements IWork priority: RegisteredEditorPriority.exclusive }, { - canSupportResource: uri => uri.scheme === Schemas.vscodeInteractive, + canSupportResource: uri => uri.scheme === Schemas.vscodeInteractive || (uri.scheme === Schemas.vscodeNotebookCell && extname(uri) === '.interactive'), singlePerResource: true }, - ({ resource }) => { - const editorInput = editorService.getEditors(EditorsOrder.SEQUENTIAL).find(editor => editor.editor instanceof InteractiveEditorInput && editor.editor.resource?.toString() === resource.toString()); - return editorInput!; + ({ resource, options }) => { + const data = CellUri.parse(resource); + let notebookUri: URI = resource; + let cellOptions: IResourceEditorInput | undefined; + + if (data) { + notebookUri = data.notebook; + cellOptions = { resource, options }; + } + + const notebookOptions = { ...options, cellOptions } as INotebookEditorOptions; + + const editorInput = editorService.getEditors(EditorsOrder.SEQUENTIAL).find(editor => editor.editor instanceof InteractiveEditorInput && editor.editor.resource?.toString() === notebookUri.toString()); + return { + editor: editorInput!.editor, + options: notebookOptions + }; } ); } diff --git a/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts b/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts index 37d2b4fde50..ca1f164befa 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts @@ -22,7 +22,7 @@ import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane'; import { EditorPaneSelectionChangeReason, IEditorMemento, IEditorOpenContext, IEditorPaneSelectionChangeEvent } from 'vs/workbench/common/editor'; import { getSimpleEditorOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions'; import { InteractiveEditorInput } from 'vs/workbench/contrib/interactive/browser/interactiveEditorInput'; -import { ICellViewModel, INotebookEditorViewState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { ICellViewModel, INotebookEditorOptions, INotebookEditorViewState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { NotebookEditorExtensionsRegistry } from 'vs/workbench/contrib/notebook/browser/notebookEditorExtensions'; import { IBorrowValue, INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/notebookEditorService'; import { cellEditorBackground, NotebookEditorWidget } from 'vs/workbench/contrib/notebook/browser/notebookEditorWidget'; @@ -501,6 +501,11 @@ export class InteractiveEditor extends EditorPane { this.#syncWithKernel(); } + override setOptions(options: INotebookEditorOptions | undefined): void { + this.#notebookWidget.value?.setOptions(options); + super.setOptions(options); + } + #toEditorPaneSelectionChangeReason(e: ICursorPositionChangedEvent): EditorPaneSelectionChangeReason { switch (e.source) { case TextEditorSelectionSource.PROGRAMMATIC: return EditorPaneSelectionChangeReason.PROGRAMMATIC; -- cgit v1.2.3 From 2d0d5b28a6d9c9233d46d27252f79a728a25d30c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 6 Jul 2022 08:14:02 +0200 Subject: File watcher stops working with malformed workspace file (fix #153881) (#154231) --- .../files/node/watcher/parcel/parcelWatcher.ts | 27 ++++++++++++++++++---- .../test/node/parcelWatcher.integrationTest.ts | 14 +++++++++-- 2 files changed, 35 insertions(+), 6 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts b/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts index 56509eb740f..66b0bc116eb 100644 --- a/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts +++ b/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as parcelWatcher from '@parcel/watcher'; -import { existsSync, unlinkSync } from 'fs'; +import { existsSync, statSync, unlinkSync } from 'fs'; import { tmpdir } from 'os'; import { DeferredPromise, RunOnceScheduler, ThrottledWorker } from 'vs/base/common/async'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; @@ -653,7 +653,7 @@ export class ParcelWatcher extends Disposable implements IRecursiveWatcher { } } - protected normalizeRequests(requests: IRecursiveWatchRequest[]): IRecursiveWatchRequest[] { + protected normalizeRequests(requests: IRecursiveWatchRequest[], validatePaths = true): IRecursiveWatchRequest[] { const requestTrie = TernarySearchTree.forPaths(!isLinux); // Sort requests by path length to have shortest first @@ -674,16 +674,35 @@ export class ParcelWatcher extends Disposable implements IRecursiveWatcher { continue; // path is ignored entirely (via `**` glob exclude) } + // Check for overlapping requests if (requestTrie.findSubstr(request.path)) { try { const realpath = realpathSync(request.path); if (realpath === request.path) { this.trace(`ignoring a path for watching who's parent is already watched: ${request.path}`); - continue; // path is not a symbolic link or similar + continue; } } catch (error) { - continue; // invalid path - ignore from watching + this.trace(`ignoring a path for watching who's realpath failed to resolve: ${request.path} (error: ${error})`); + + continue; + } + } + + // Check for invalid paths + if (validatePaths) { + try { + const stat = statSync(request.path); + if (!stat.isDirectory()) { + this.trace(`ignoring a path for watching that is a file and not a folder: ${request.path}`); + + continue; + } + } catch (error) { + this.trace(`ignoring a path for watching who's stat info failed to resolve: ${request.path} (error: ${error})`); + + continue; } } diff --git a/src/vs/platform/files/test/node/parcelWatcher.integrationTest.ts b/src/vs/platform/files/test/node/parcelWatcher.integrationTest.ts index 052e2ffb603..3196a4b6271 100644 --- a/src/vs/platform/files/test/node/parcelWatcher.integrationTest.ts +++ b/src/vs/platform/files/test/node/parcelWatcher.integrationTest.ts @@ -33,7 +33,7 @@ import { ltrim } from 'vs/base/common/strings'; return { path, excludes, recursive: true }; }); - return this.normalizeRequests(requests).map(request => request.path); + return this.normalizeRequests(requests, false /* validate paths skipped for tests */).map(request => request.path); } override async watch(requests: IRecursiveWatchRequest[]): Promise { @@ -155,7 +155,7 @@ import { ltrim } from 'vs/base/common/strings'; } test('basics', async function () { - await watcher.watch([{ path: testDir, excludes: [], recursive: true }]); // + await watcher.watch([{ path: testDir, excludes: [], recursive: true }]); // New file const newFilePath = join(testDir, 'deep', 'newFile.txt'); @@ -430,6 +430,16 @@ import { ltrim } from 'vs/base/common/strings'; await changeFuture; }); + test('invalid path does not crash watcher', async function () { + await watcher.watch([ + { path: testDir, excludes: [], recursive: true }, + { path: join(testDir, 'invalid-folder'), excludes: [], recursive: true }, + { path: __filename, excludes: [], recursive: true } + ]); + + return basicCrudTest(join(testDir, 'deep', 'newFile.txt')); + }); + test('subsequent watch updates watchers (excludes)', async function () { await watcher.watch([{ path: testDir, excludes: [realpathSync(testDir)], recursive: true }]); await watcher.watch([{ path: testDir, excludes: [], recursive: true }]); -- cgit v1.2.3 From 6770e54beaade2921f576d953482f38999240d07 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 6 Jul 2022 10:09:43 +0200 Subject: add `ICodeEditorService#registerCodeEditorOpenHandler` so that 3rd parties can influence opening, e.g diff or merge editor This allows to remove editor registration for 3wm editor. --- .../browser/services/abstractCodeEditorService.ts | 22 +++++- .../editor/browser/services/codeEditorService.ts | 6 ++ .../browser/standaloneCodeEditorService.ts | 16 ++-- .../browser/mergeEditor.contribution.ts | 11 ++- .../mergeEditor/browser/view/mergeEditor.ts | 85 ++++++++++------------ .../services/editor/browser/codeEditorService.ts | 9 ++- 6 files changed, 88 insertions(+), 61 deletions(-) (limited to 'src/vs') diff --git a/src/vs/editor/browser/services/abstractCodeEditorService.ts b/src/vs/editor/browser/services/abstractCodeEditorService.ts index 761c4eee60f..aaa31ee4ce4 100644 --- a/src/vs/editor/browser/services/abstractCodeEditorService.ts +++ b/src/vs/editor/browser/services/abstractCodeEditorService.ts @@ -5,11 +5,12 @@ import * as dom from 'vs/base/browser/dom'; import { Emitter, Event } from 'vs/base/common/event'; -import { IDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle'; +import { IDisposable, DisposableStore, Disposable, toDisposable } from 'vs/base/common/lifecycle'; +import { LinkedList } from 'vs/base/common/linkedList'; import * as strings from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; -import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; +import { ICodeEditorOpenHandler, ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { IContentDecorationRenderOptions, IDecorationRenderOptions, IThemeDecorationRenderOptions, isThemeColor } from 'vs/editor/common/editorCommon'; import { IModelDecorationOptions, IModelDecorationOverviewRulerOptions, InjectedTextOptions, ITextModel, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model'; import { IResourceEditorInput } from 'vs/platform/editor/common/editor'; @@ -42,6 +43,7 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC protected _globalStyleSheet: GlobalStyleSheet | null; private readonly _decorationOptionProviders = new Map(); private readonly _editorStyleSheets = new Map(); + private readonly _codeEditorOpenHandlers = new LinkedList(); constructor( @IThemeService private readonly _themeService: IThemeService, @@ -247,7 +249,21 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC } abstract getActiveCodeEditor(): ICodeEditor | null; - abstract openCodeEditor(input: IResourceEditorInput, source: ICodeEditor | null, sideBySide?: boolean): Promise; + + async openCodeEditor(input: IResourceEditorInput, source: ICodeEditor | null, sideBySide?: boolean): Promise { + for (const handler of this._codeEditorOpenHandlers) { + const candidate = await handler(input, source, sideBySide); + if (candidate !== null) { + return candidate; + } + } + return null; + } + + registerCodeEditorOpenHandler(handler: ICodeEditorOpenHandler): IDisposable { + const rm = this._codeEditorOpenHandlers.unshift(handler); + return toDisposable(rm); + } } export class ModelTransientSettingWatcher { diff --git a/src/vs/editor/browser/services/codeEditorService.ts b/src/vs/editor/browser/services/codeEditorService.ts index b56596939a8..40d7947efcd 100644 --- a/src/vs/editor/browser/services/codeEditorService.ts +++ b/src/vs/editor/browser/services/codeEditorService.ts @@ -10,6 +10,7 @@ import { IModelDecorationOptions, ITextModel } from 'vs/editor/common/model'; import { ITextResourceEditorInput } from 'vs/platform/editor/common/editor'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { URI } from 'vs/base/common/uri'; +import { IDisposable } from 'vs/base/common/lifecycle'; export const ICodeEditorService = createDecorator('codeEditorService'); @@ -53,4 +54,9 @@ export interface ICodeEditorService { getActiveCodeEditor(): ICodeEditor | null; openCodeEditor(input: ITextResourceEditorInput, source: ICodeEditor | null, sideBySide?: boolean): Promise; + registerCodeEditorOpenHandler(handler: ICodeEditorOpenHandler): IDisposable; +} + +export interface ICodeEditorOpenHandler { + (input: ITextResourceEditorInput, source: ICodeEditor | null, sideBySide?: boolean): Promise; } diff --git a/src/vs/editor/standalone/browser/standaloneCodeEditorService.ts b/src/vs/editor/standalone/browser/standaloneCodeEditorService.ts index af167ba519d..2f9e648d52d 100644 --- a/src/vs/editor/standalone/browser/standaloneCodeEditorService.ts +++ b/src/vs/editor/standalone/browser/standaloneCodeEditorService.ts @@ -13,7 +13,7 @@ import { IRange } from 'vs/editor/common/core/range'; import { ScrollType } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IResourceEditorInput, ITextResourceEditorInput } from 'vs/platform/editor/common/editor'; +import { ITextResourceEditorInput } from 'vs/platform/editor/common/editor'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IThemeService } from 'vs/platform/theme/common/themeService'; @@ -31,6 +31,13 @@ export class StandaloneCodeEditorService extends AbstractCodeEditorService { this.onCodeEditorRemove(() => this._checkContextKey()); this._editorIsOpen = contextKeyService.createKey('editorIsOpen', false); this._activeCodeEditor = null; + + this.registerCodeEditorOpenHandler(async (input, source, sideBySide) => { + if (!source) { + return null; + } + return this.doOpenEditor(source, input); + }); } private _checkContextKey(): void { @@ -52,13 +59,6 @@ export class StandaloneCodeEditorService extends AbstractCodeEditorService { return this._activeCodeEditor; } - public openCodeEditor(input: IResourceEditorInput, source: ICodeEditor | null, sideBySide?: boolean): Promise { - if (!source) { - return Promise.resolve(null); - } - - return Promise.resolve(this.doOpenEditor(source, input)); - } private doOpenEditor(editor: ICodeEditor, input: ITextResourceEditorInput): ICodeEditor | null { const model = this.findModel(editor, input.resource); diff --git a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution.ts b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution.ts index 8dc07e6463f..09206f43520 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution.ts @@ -8,11 +8,13 @@ import { registerAction2 } from 'vs/platform/actions/common/actions'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { Registry } from 'vs/platform/registry/common/platform'; import { EditorPaneDescriptor, IEditorPaneRegistry } from 'vs/workbench/browser/editor'; +import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; import { EditorExtensions, IEditorFactoryRegistry } from 'vs/workbench/common/editor'; -import { CompareInput1WithBaseCommand, CompareInput2WithBaseCommand, GoToNextConflict, GoToPreviousConflict, OpenMergeEditor, ToggleActiveConflictInput1, ToggleActiveConflictInput2, SetColumnLayout, SetMixedLayout, OpenBaseFile } from 'vs/workbench/contrib/mergeEditor/browser/commands/commands'; +import { CompareInput1WithBaseCommand, CompareInput2WithBaseCommand, GoToNextConflict, GoToPreviousConflict, OpenBaseFile, OpenMergeEditor, SetColumnLayout, SetMixedLayout, ToggleActiveConflictInput1, ToggleActiveConflictInput2 } from 'vs/workbench/contrib/mergeEditor/browser/commands/commands'; import { MergeEditorCopyContentsToJSON, MergeEditorOpenContents } from 'vs/workbench/contrib/mergeEditor/browser/commands/devCommands'; import { MergeEditorInput } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput'; -import { MergeEditor } from 'vs/workbench/contrib/mergeEditor/browser/view/mergeEditor'; +import { MergeEditor, MergeEditorOpenHandlerContribution } from 'vs/workbench/contrib/mergeEditor/browser/view/mergeEditor'; +import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { MergeEditorSerializer } from './mergeEditorSerializer'; Registry.as(EditorExtensions.EditorPane).registerEditorPane( @@ -47,3 +49,8 @@ registerAction2(ToggleActiveConflictInput2); registerAction2(CompareInput1WithBaseCommand); registerAction2(CompareInput2WithBaseCommand); + + +Registry + .as(WorkbenchExtensions.Workbench) + .registerWorkbenchContribution(MergeEditorOpenHandlerContribution, LifecyclePhase.Restored); diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts index 544e07332cb..ff44bc01163 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts @@ -11,12 +11,13 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { Color } from 'vs/base/common/color'; import { BugIndicatingError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; -import { DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { autorunWithStore, IObservable } from 'vs/base/common/observable'; import { isEqual } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import 'vs/css!./media/mergeEditor'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; import { IEditorOptions as ICodeEditorOptions } from 'vs/editor/common/config/editorOptions'; import { ICodeEditorViewState, ScrollType } from 'vs/editor/common/editorCommon'; @@ -26,7 +27,7 @@ import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/men import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IEditorOptions, ITextEditorOptions } from 'vs/platform/editor/common/editor'; +import { IEditorOptions, ITextEditorOptions, ITextResourceEditorInput } from 'vs/platform/editor/common/editor'; import { IFileService } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILabelService } from 'vs/platform/label/common/label'; @@ -35,7 +36,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { FloatingClickWidget } from 'vs/workbench/browser/codeeditor'; import { AbstractTextEditor } from 'vs/workbench/browser/parts/editor/textEditor'; -import { EditorInputWithOptions, EditorResourceAccessor, IEditorOpenContext } from 'vs/workbench/common/editor'; +import { IEditorOpenContext } from 'vs/workbench/common/editor'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { applyTextEditorOptions } from 'vs/workbench/common/editor/editorOptions'; import { MergeEditorInput } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput'; @@ -46,7 +47,6 @@ import { MergeEditorViewModel } from 'vs/workbench/contrib/mergeEditor/browser/v import { ctxBaseResourceScheme, ctxIsMergeEditor, ctxMergeEditorLayout, MergeEditorLayoutTypes } from 'vs/workbench/contrib/mergeEditor/common/mergeEditor'; import { settingsSashBorder } from 'vs/workbench/contrib/preferences/common/settingsEditorColorRegistry'; import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { IEditorResolverService, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import './colors'; import { InputCodeEditorView } from './editors/inputCodeEditorView'; @@ -86,9 +86,9 @@ export class MergeEditor extends AbstractTextEditor { private readonly _sessionDisposables = new DisposableStore(); private _grid!: Grid; - private readonly input1View = this._register(this.instantiation.createInstance(InputCodeEditorView, 1)); - private readonly input2View = this._register(this.instantiation.createInstance(InputCodeEditorView, 2)); - private readonly inputResultView = this._register(this.instantiation.createInstance(ResultCodeEditorView)); + private readonly input1View = this._register(this.instantiationService.createInstance(InputCodeEditorView, 1)); + private readonly input2View = this._register(this.instantiationService.createInstance(InputCodeEditorView, 2)); + private readonly inputResultView = this._register(this.instantiationService.createInstance(ResultCodeEditorView)); private readonly _layoutMode: MergeEditorLayout; private readonly _ctxIsMergeEditor: IContextKey; @@ -103,7 +103,7 @@ export class MergeEditor extends AbstractTextEditor { } constructor( - @IInstantiationService private readonly instantiation: IInstantiationService, + @IInstantiationService instantiation: IInstantiationService, @ILabelService private readonly _labelService: ILabelService, @IMenuService private readonly _menuService: IMenuService, @IContextKeyService private readonly _contextKeyService: IContextKeyService, @@ -115,7 +115,6 @@ export class MergeEditor extends AbstractTextEditor { @IEditorService editorService: IEditorService, @IEditorGroupsService editorGroupService: IEditorGroupsService, @IFileService fileService: IFileService, - @IEditorResolverService private readonly _editorResolverService: IEditorResolverService, ) { super(MergeEditor.ID, telemetryService, instantiation, storageService, textResourceConfigurationService, themeService, editorService, editorGroupService, fileService); @@ -186,7 +185,7 @@ export class MergeEditor extends AbstractTextEditor { createAndFillInActionBarActions(toolbarMenu, { renderShortTitle: true, shouldForwardArgs: true }, actions); if (actions.length > 0) { const [first] = actions; - const acceptBtn = this.instantiation.createInstance(FloatingClickWidget, this.inputResultView.editor, first.label, first.id); + const acceptBtn = this.instantiationService.createInstance(FloatingClickWidget, this.inputResultView.editor, first.label, first.id); toolbarMenuDisposables.add(acceptBtn.onClick(() => first.run(this.inputResultView.editor.getModel()?.uri))); toolbarMenuDisposables.add(acceptBtn); acceptBtn.render(); @@ -296,7 +295,6 @@ export class MergeEditor extends AbstractTextEditor { await super.setInput(input, options, context, token); this._sessionDisposables.clear(); - this._toggleEditorOverwrite(true); const model = await input.resolve(); this._model = model; @@ -373,7 +371,6 @@ export class MergeEditor extends AbstractTextEditor { super.clearInput(); this._sessionDisposables.clear(); - this._toggleEditorOverwrite(false); for (const { editor } of [this.input1View, this.input2View, this.inputResultView]) { editor.setModel(null); @@ -405,39 +402,6 @@ export class MergeEditor extends AbstractTextEditor { } this._ctxIsMergeEditor.set(visible); - this._toggleEditorOverwrite(visible); - } - - private readonly _editorOverrideHandle = this._store.add(new MutableDisposable()); - - private _toggleEditorOverwrite(haveIt: boolean) { - if (!haveIt) { - this._editorOverrideHandle.clear(); - return; - } - // this is RATHER UGLY. I dynamically register an editor for THIS (editor,input) so that - // navigating within the merge editor works, e.g navigating from the outline or breakcrumps - // or revealing a definition, reference etc - // TODO@jrieken @bpasero @lramos15 - const input = this.input; - if (input instanceof MergeEditorInput) { - this._editorOverrideHandle.value = this._editorResolverService.registerEditor( - `${input.result.scheme}:${input.result.fsPath}`, - { - id: `${this.getId()}/fake`, - label: this.input?.getName()!, - priority: RegisteredEditorPriority.exclusive - }, - {}, - (candidate): EditorInputWithOptions => { - const resource = EditorResourceAccessor.getCanonicalUri(candidate); - if (!isEqual(resource, this.model?.result.uri)) { - throw new Error(`Expected to be called WITH ${input.result.toString()}`); - } - return { editor: input }; - } - ); - } } // ---- interact with "outside world" via`getControl`, `scopedContextKeyService`: we only expose the result-editor keep the others internal @@ -506,6 +470,37 @@ export class MergeEditor extends AbstractTextEditor { } } +export class MergeEditorOpenHandlerContribution extends Disposable { + + constructor( + @IEditorService private readonly _editorService: IEditorService, + @ICodeEditorService codeEditorService: ICodeEditorService, + ) { + super(); + this._store.add(codeEditorService.registerCodeEditorOpenHandler(this.openCodeEditorFromMergeEditor.bind(this))); + } + + private async openCodeEditorFromMergeEditor(input: ITextResourceEditorInput, _source: ICodeEditor | null, sideBySide?: boolean | undefined): Promise { + const activePane = this._editorService.activeEditorPane; + if (!sideBySide + && input.options + && activePane instanceof MergeEditor + && activePane.getControl() + && activePane.input instanceof MergeEditorInput + && isEqual(input.resource, activePane.input.result) + ) { + // Special: stay inside the merge editor when it is active and when the input + // targets the result editor of the merge editor. + const targetEditor = activePane.getControl()!; + applyTextEditorOptions(input.options, targetEditor, ScrollType.Smooth); + return targetEditor; + } + + // cannot handle this + return null; + } +} + type IMergeEditorViewState = ICodeEditorViewState & { readonly input1State?: ICodeEditorViewState; readonly input2State?: ICodeEditorViewState; diff --git a/src/vs/workbench/services/editor/browser/codeEditorService.ts b/src/vs/workbench/services/editor/browser/codeEditorService.ts index 0aaf3980f4f..492e5077def 100644 --- a/src/vs/workbench/services/editor/browser/codeEditorService.ts +++ b/src/vs/workbench/services/editor/browser/codeEditorService.ts @@ -24,6 +24,9 @@ export class CodeEditorService extends AbstractCodeEditorService { @IConfigurationService private readonly configurationService: IConfigurationService, ) { super(themeService); + + this.registerCodeEditorOpenHandler(this.doOpenCodeEditor.bind(this)); + this.registerCodeEditorOpenHandler(this.doOpenCodeEditorFromDiff.bind(this)); } getActiveCodeEditor(): ICodeEditor | null { @@ -44,7 +47,7 @@ export class CodeEditorService extends AbstractCodeEditorService { return null; } - async openCodeEditor(input: IResourceEditorInput, source: ICodeEditor | null, sideBySide?: boolean): Promise { + private async doOpenCodeEditorFromDiff(input: IResourceEditorInput, source: ICodeEditor | null, sideBySide?: boolean): Promise { // Special case: If the active editor is a diff editor and the request to open originates and // targets the modified side of it, we just apply the request there to prevent opening the modified @@ -66,10 +69,10 @@ export class CodeEditorService extends AbstractCodeEditorService { return targetEditor; } - // Open using our normal editor service - return this.doOpenCodeEditor(input, source, sideBySide); + return null; } + // Open using our normal editor service private async doOpenCodeEditor(input: IResourceEditorInput, source: ICodeEditor | null, sideBySide?: boolean): Promise { // Special case: we want to detect the request to open an editor that -- cgit v1.2.3 From 7c346e113b4cff07019139de115cc72005819383 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 6 Jul 2022 10:10:21 +0200 Subject: make sure document outline uses the code editor service from the current (code) editor --- .../contrib/codeEditor/browser/outline/documentSymbolsOutline.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsOutline.ts b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsOutline.ts index 922bf591bf7..5f44dc67e26 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsOutline.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsOutline.ts @@ -403,8 +403,7 @@ class DocumentSymbolsOutlineCreator implements IOutlineCreator void; constructor( - @IOutlineService outlineService: IOutlineService, - @IInstantiationService private readonly _instantiationService: IInstantiationService, + @IOutlineService outlineService: IOutlineService ) { const reg = outlineService.registerOutlineCreator(this); this.dispose = () => reg.dispose(); @@ -427,7 +426,7 @@ class DocumentSymbolsOutlineCreator implements IOutlineCreator accessor.get(IInstantiationService).createInstance(DocumentSymbolsOutline, editor!, target, firstLoadBarrier)); await firstLoadBarrier.wait(); return result; } -- cgit v1.2.3 From 3ecb7fe9996f0863dab796edfc55f12d9c82cdcc Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Jul 2022 10:34:24 +0200 Subject: move reset default profile to UserDataProfilesService --- src/vs/workbench/browser/web.main.ts | 2 +- src/vs/workbench/electron-sandbox/desktop.main.ts | 2 +- .../test/browser/configurationEditingService.test.ts | 2 +- .../test/browser/configurationService.test.ts | 20 ++++++++++---------- .../test/browser/extensionStorageMigration.test.ts | 2 +- .../test/browser/keybindingEditing.test.ts | 3 ++- .../storage/test/browser/storageService.test.ts | 5 +++-- .../browser/userDataProfileManagement.ts | 4 ---- .../userDataProfile/common/userDataProfileService.ts | 19 ++++++++++++++----- .../workbench/test/browser/workbenchTestServices.ts | 2 +- .../test/electron-browser/workbenchTestServices.ts | 2 +- 11 files changed, 35 insertions(+), 28 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index e83eb19ce63..e9b7f4fc8b0 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -263,7 +263,7 @@ export class BrowserMain extends Disposable { const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); serviceCollection.set(IUserDataProfilesService, userDataProfilesService); - const userDataProfileService = new UserDataProfileService(userDataProfilesService.defaultProfile); + const userDataProfileService = new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService); serviceCollection.set(IUserDataProfileService, userDataProfileService); // URI Identity diff --git a/src/vs/workbench/electron-sandbox/desktop.main.ts b/src/vs/workbench/electron-sandbox/desktop.main.ts index 706079b5ea7..38363be6614 100644 --- a/src/vs/workbench/electron-sandbox/desktop.main.ts +++ b/src/vs/workbench/electron-sandbox/desktop.main.ts @@ -237,7 +237,7 @@ export class DesktopMain extends Disposable { // User Data Profiles const userDataProfilesService = new UserDataProfilesNativeService(this.configuration.profiles.all, mainProcessService, environmentService, fileService, logService); serviceCollection.set(IUserDataProfilesService, userDataProfilesService); - const userDataProfileService = new UserDataProfileService(reviveProfile(this.configuration.profiles.current, userDataProfilesService.profilesHome.scheme)); + const userDataProfileService = new UserDataProfileService(reviveProfile(this.configuration.profiles.current, userDataProfilesService.profilesHome.scheme), userDataProfilesService); serviceCollection.set(IUserDataProfileService, userDataProfileService); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/src/vs/workbench/services/configuration/test/browser/configurationEditingService.test.ts b/src/vs/workbench/services/configuration/test/browser/configurationEditingService.test.ts index 243add76058..6412bd0e4c3 100644 --- a/src/vs/workbench/services/configuration/test/browser/configurationEditingService.test.ts +++ b/src/vs/workbench/services/configuration/test/browser/configurationEditingService.test.ts @@ -111,7 +111,7 @@ suite('ConfigurationEditingService', () => { environmentService.policyFile = joinPath(workspaceFolder, 'policies.json'); instantiationService.stub(IEnvironmentService, environmentService); const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); - userDataProfileService = new UserDataProfileService(userDataProfilesService.defaultProfile); + userDataProfileService = new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService); const remoteAgentService = disposables.add(instantiationService.createInstance(RemoteAgentService, null)); disposables.add(fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, logService)))); instantiationService.stub(IFileService, fileService); diff --git a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts index 3a1d3a6ca2b..1254e1a9b0b 100644 --- a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts @@ -86,7 +86,7 @@ suite('WorkspaceContextService - Folder', () => { const environmentService = TestEnvironmentService; fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); - testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); await (testObject).initialize(convertToWorkspacePayload(folder)); }); @@ -127,7 +127,7 @@ suite('WorkspaceContextService - Folder', () => { const environmentService = TestEnvironmentService; fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); - const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); await (testObject).initialize(convertToWorkspacePayload(folder)); const actual = testObject.getWorkspaceFolder(joinPath(folder, 'a')); @@ -148,7 +148,7 @@ suite('WorkspaceContextService - Folder', () => { const environmentService = TestEnvironmentService; fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); - const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); await (testObject).initialize(convertToWorkspacePayload(folder)); @@ -196,7 +196,7 @@ suite('WorkspaceContextService - Workspace', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); - testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile), userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IConfigurationService, testObject); @@ -255,7 +255,7 @@ suite('WorkspaceContextService - Workspace Editing', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); - testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile), userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); instantiationService.stub(IFileService, fileService); instantiationService.stub(IWorkspaceContextService, testObject); @@ -499,7 +499,7 @@ suite('WorkspaceService - Initialization', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); - userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile)); + userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); instantiationService.stub(IFileService, fileService); instantiationService.stub(IWorkspaceContextService, testObject); @@ -759,7 +759,7 @@ suite('WorkspaceConfigurationService - Folder', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); - userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile)); + userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); workspaceService = testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new FilePolicyService(environmentService.policyFile, fileService, logService))); instantiationService.stub(IFileService, fileService); instantiationService.stub(IWorkspaceContextService, testObject); @@ -1425,7 +1425,7 @@ suite('WorkspaceConfigurationService - Profiles', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); - userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(toUserDataProfile('custom', joinPath(environmentService.userRoamingDataHome, 'profiles', 'temp')))); + userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(toUserDataProfile('custom', joinPath(environmentService.userRoamingDataHome, 'profiles', 'temp')), userDataProfilesService)); workspaceService = testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new FilePolicyService(environmentService.policyFile, fileService, logService))); instantiationService.stub(IFileService, fileService); instantiationService.stub(IWorkspaceContextService, testObject); @@ -1613,7 +1613,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); - userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile)); + userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); const workspaceService = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); instantiationService.stub(IFileService, fileService); @@ -2276,7 +2276,7 @@ suite('WorkspaceConfigurationService - Remote Folder', () => { fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); const configurationCache: IConfigurationCache = { read: () => Promise.resolve(''), write: () => Promise.resolve(), remove: () => Promise.resolve(), needsCaching: () => false }; const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); - userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile)); + userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); testObject = disposables.add(new WorkspaceService({ configurationCache, remoteAuthority }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IConfigurationService, testObject); diff --git a/src/vs/workbench/services/extensions/test/browser/extensionStorageMigration.test.ts b/src/vs/workbench/services/extensions/test/browser/extensionStorageMigration.test.ts index bbee18ae82b..d6843185c30 100644 --- a/src/vs/workbench/services/extensions/test/browser/extensionStorageMigration.test.ts +++ b/src/vs/workbench/services/extensions/test/browser/extensionStorageMigration.test.ts @@ -39,7 +39,7 @@ suite('ExtensionStorageMigration', () => { instantiationService.stub(IFileService, fileService); const environmentService = instantiationService.stub(IEnvironmentService, >{ userRoamingDataHome: ROOT, workspaceStorageHome }); const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, new NullLogService())); - instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile)); + instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); instantiationService.stub(IExtensionStorageService, instantiationService.createInstance(ExtensionStorageService)); }); diff --git a/src/vs/workbench/services/keybinding/test/browser/keybindingEditing.test.ts b/src/vs/workbench/services/keybinding/test/browser/keybindingEditing.test.ts index 66b5e7fa8a8..a20bd496d4b 100644 --- a/src/vs/workbench/services/keybinding/test/browser/keybindingEditing.test.ts +++ b/src/vs/workbench/services/keybinding/test/browser/keybindingEditing.test.ts @@ -66,7 +66,8 @@ suite('KeybindingsEditing', () => { const configService = new TestConfigurationService(); configService.setUserConfiguration('files', { 'eol': '\n' }); - userDataProfileService = new UserDataProfileService(new UserDataProfilesService(environmentService, fileService, logService).defaultProfile); + const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); + userDataProfileService = new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService); instantiationService = workbenchInstantiationService({ fileService: () => fileService, diff --git a/src/vs/workbench/services/storage/test/browser/storageService.test.ts b/src/vs/workbench/services/storage/test/browser/storageService.test.ts index 58d1c19d3cb..4205c92d7a8 100644 --- a/src/vs/workbench/services/storage/test/browser/storageService.test.ts +++ b/src/vs/workbench/services/storage/test/browser/storageService.test.ts @@ -16,9 +16,10 @@ import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFil import { NullLogService } from 'vs/platform/log/common/log'; import { StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { createSuite } from 'vs/platform/storage/test/common/storageService.test'; -import { IUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUserDataProfile, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { BrowserStorageService, IndexedDBStorageDatabase } from 'vs/workbench/services/storage/browser/storageService'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; +import { TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices'; async function createStorageService(): Promise<[DisposableStore, BrowserStorageService]> { const disposables = new DisposableStore(); @@ -45,7 +46,7 @@ async function createStorageService(): Promise<[DisposableStore, BrowserStorageS extensionsResource: joinPath(inMemoryExtraProfileRoot, 'extensionsResource') }; - const storageService = disposables.add(new BrowserStorageService({ id: 'workspace-storage-test' }, new UserDataProfileService(inMemoryExtraProfile), logService)); + const storageService = disposables.add(new BrowserStorageService({ id: 'workspace-storage-test' }, new UserDataProfileService(inMemoryExtraProfile, new UserDataProfilesService(TestEnvironmentService, fileService, logService)), logService)); await storageService.initialize(); diff --git a/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts b/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts index ba46d3e24d7..798abb97873 100644 --- a/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts +++ b/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts @@ -46,10 +46,6 @@ export class UserDataProfileManagementService extends Disposable implements IUse this.enterProfile(this.userDataProfilesService.defaultProfile, false, localize('reload message when removed', "The current profile has been removed. Please reload to switch back to default profile")); return; } - if (this.userDataProfileService.currentProfile.isDefault) { - this.userDataProfileService.updateCurrentProfile(this.userDataProfilesService.defaultProfile, false); - return; - } } async createAndEnterProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, fromExisting?: boolean): Promise { diff --git a/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts b/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts index 96fa879239f..57c6e4161a2 100644 --- a/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts +++ b/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts @@ -6,7 +6,7 @@ import { Promises } from 'vs/base/common/async'; import { Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; -import { IUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { DidChangeUserDataProfileEvent, IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; export class UserDataProfileService extends Disposable implements IUserDataProfileService { @@ -19,17 +19,26 @@ export class UserDataProfileService extends Disposable implements IUserDataProfi private _currentProfile: IUserDataProfile; get currentProfile(): IUserDataProfile { return this._currentProfile; } - constructor(currentProfile: IUserDataProfile) { + constructor(currentProfile: IUserDataProfile, userDataProfilesService: IUserDataProfilesService) { super(); this._currentProfile = currentProfile; + this._register(userDataProfilesService.onDidChangeProfiles(() => { + /** + * If the current profile is default profile, then reset it because, + * In Desktop the extensions resource will be set/unset in the default profile when profiles are changed. + */ + if (this._currentProfile.isDefault) { + this._currentProfile = userDataProfilesService.defaultProfile; + } + })); } async updateCurrentProfile(userDataProfile: IUserDataProfile, preserveData: boolean): Promise { - const previous = this._currentProfile; - this._currentProfile = userDataProfile; - if (this._currentProfile.id === previous.id) { + if (this._currentProfile.id === userDataProfile.id) { return; } + const previous = this._currentProfile; + this._currentProfile = userDataProfile; const joiners: Promise[] = []; this._onDidChangeCurrentProfile.fire({ preserveData, diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index c45f26e708a..caa62c81497 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -286,7 +286,7 @@ export function workbenchInstantiationService( const fileService = overrides?.fileService ? overrides.fileService(instantiationService) : new TestFileService(); instantiationService.stub(IFileService, fileService); const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, new NullLogService())); - instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile)); + instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); instantiationService.stub(IUriIdentityService, new UriIdentityService(fileService)); instantiationService.stub(IWorkingCopyBackupService, new TestWorkingCopyBackupService()); instantiationService.stub(ITelemetryService, NullTelemetryService); diff --git a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts index ded96d4e010..1880f3377d6 100644 --- a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts @@ -290,7 +290,7 @@ export function workbenchInstantiationService(disposables = new DisposableStore( instantiationService.stub(IWorkbenchEnvironmentService, TestEnvironmentService); instantiationService.stub(INativeWorkbenchEnvironmentService, TestEnvironmentService); const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(TestEnvironmentService, new FileService(new NullLogService()), new NullLogService())); - instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile)); + instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); return instantiationService; } -- cgit v1.2.3 From e4069c40f75bd876b9609fb5a291306aa03b062f Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Jul 2022 10:37:18 +0200 Subject: extract default extensions profile init and uninit invoke it from main --- .../sharedProcess/sharedProcessMain.ts | 7 +++- src/vs/code/electron-main/app.ts | 17 +++++++- .../common/extensionManagement.ts | 7 ++++ .../electron-main/defaultExtensionsProfileInit.ts | 27 +++++++++++++ .../defaultExtensionsProfileInit.ts | 45 ++++++++++++++++++++++ .../browser/userDataProfileManagement.ts | 31 +-------------- 6 files changed, 101 insertions(+), 33 deletions(-) create mode 100644 src/vs/platform/extensionManagement/electron-main/defaultExtensionsProfileInit.ts create mode 100644 src/vs/platform/extensionManagement/electron-sandbox/defaultExtensionsProfileInit.ts (limited to 'src/vs') diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index 4d77d394a3a..f166be81aeb 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -31,7 +31,7 @@ import { INativeEnvironmentService } from 'vs/platform/environment/common/enviro import { SharedProcessEnvironmentService } from 'vs/platform/sharedProcess/node/sharedProcessEnvironmentService'; import { GlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; -import { IExtensionGalleryService, IExtensionManagementService, IExtensionTipsService, IGlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IDefaultExtensionsProfileInitService, IExtensionGalleryService, IExtensionManagementService, IExtensionTipsService, IGlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionManagementChannel, ExtensionTipsChannel } from 'vs/platform/extensionManagement/common/extensionManagementIpc'; import { ExtensionTipsService } from 'vs/platform/extensionManagement/electron-sandbox/extensionTipsService'; import { ExtensionManagementService, INativeServerExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; @@ -106,6 +106,7 @@ import { PolicyChannelClient } from 'vs/platform/policy/common/policyIpc'; import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/policy'; import { UserDataProfilesNativeService } from 'vs/platform/userDataProfile/electron-sandbox/userDataProfile'; import { OneDataSystemWebAppender } from 'vs/platform/telemetry/browser/1dsAppender'; +import { DefaultExtensionsProfileInitService } from 'vs/platform/extensionManagement/electron-sandbox/defaultExtensionsProfileInit'; class SharedProcessMain extends Disposable { @@ -316,6 +317,7 @@ class SharedProcessMain extends Disposable { services.set(IExtensionsProfileScannerService, new SyncDescriptor(ExtensionsProfileScannerService)); services.set(IExtensionsScannerService, new SyncDescriptor(ExtensionsScannerService)); services.set(INativeServerExtensionManagementService, new SyncDescriptor(ExtensionManagementService)); + services.set(IDefaultExtensionsProfileInitService, new SyncDescriptor(DefaultExtensionsProfileInitService)); // Extension Gallery services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService)); @@ -426,6 +428,9 @@ class SharedProcessMain extends Disposable { // Worker const sharedProcessWorkerChannel = ProxyChannel.fromService(accessor.get(ISharedProcessWorkerService)); this.server.registerChannel(ipcSharedProcessWorkerChannelName, sharedProcessWorkerChannel); + + // Default Extensions Profile Init + this.server.registerChannel('IDefaultExtensionsProfileInitService', ProxyChannel.fromService(accessor.get(IDefaultExtensionsProfileInitService))); } private registerErrorHandler(logService: ILogService): void { diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 7b912a581c3..14346728268 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -102,6 +102,8 @@ import { CredentialsNativeMainService } from 'vs/platform/credentials/electron-m import { IPolicyService } from 'vs/platform/policy/common/policy'; import { PolicyChannel } from 'vs/platform/policy/common/policyIpc'; import { IUserDataProfilesMainService } from 'vs/platform/userDataProfile/electron-main/userDataProfile'; +import { IDefaultExtensionsProfileInitService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { DefaultExtensionsProfileInitHandler } from 'vs/platform/extensionManagement/electron-main/defaultExtensionsProfileInit'; /** * The main VS Code application. There will only ever be one instance, @@ -525,8 +527,8 @@ export class CodeApplication extends Disposable { // Services const appInstantiationService = await this.initServices(machineId, sharedProcess, sharedProcessReady); - // Setup Auth Handler - this._register(appInstantiationService.createInstance(ProxyAuthHandler)); + // Setup Handlers + this.setUpHandlers(appInstantiationService); // Init Channels appInstantiationService.invokeFunction(accessor => this.initChannels(accessor, mainProcessElectronServer, sharedProcessClient)); @@ -543,6 +545,14 @@ export class CodeApplication extends Disposable { } } + private setUpHandlers(instantiationService: IInstantiationService): void { + // Auth Handler + this._register(instantiationService.createInstance(ProxyAuthHandler)); + + // Default Extensions Profile Init Handler + this._register(instantiationService.createInstance(DefaultExtensionsProfileInitHandler)); + } + private async resolveMachineId(): Promise { // We cache the machineId for faster lookups on startup @@ -679,6 +689,9 @@ export class CodeApplication extends Disposable { services.set(ITelemetryService, NullTelemetryService); } + // Default Extensions Profile Init + services.set(IDefaultExtensionsProfileInitService, ProxyChannel.toService(getDelayedChannel(sharedProcessReady.then(client => client.getChannel('IDefaultExtensionsProfileInitService'))))); + // Init services that require it await backupMainService.initialize(); diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 3c5ec520512..9302da87da0 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -528,3 +528,10 @@ export interface IExtensionManagementCLIService { uninstallExtensions(extensions: (string | URI)[], force: boolean, output?: CLIOutput): Promise; locateExtension(extensions: string[], output?: CLIOutput): Promise; } + +export const IDefaultExtensionsProfileInitService = createDecorator('IDefaultExtensionsProfileInitService'); +export interface IDefaultExtensionsProfileInitService { + readonly _serviceBrand: undefined; + initialize(): Promise; + uninitialize(): Promise; +} diff --git a/src/vs/platform/extensionManagement/electron-main/defaultExtensionsProfileInit.ts b/src/vs/platform/extensionManagement/electron-main/defaultExtensionsProfileInit.ts new file mode 100644 index 00000000000..2db8dfaa0d8 --- /dev/null +++ b/src/vs/platform/extensionManagement/electron-main/defaultExtensionsProfileInit.ts @@ -0,0 +1,27 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable } from 'vs/base/common/lifecycle'; +import { IDefaultExtensionsProfileInitService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IUserDataProfilesMainService } from 'vs/platform/userDataProfile/electron-main/userDataProfile'; + +export class DefaultExtensionsProfileInitHandler extends Disposable { + constructor( + @IDefaultExtensionsProfileInitService private readonly defaultExtensionsProfileInitService: IDefaultExtensionsProfileInitService, + @IUserDataProfilesMainService userDataProfilesService: IUserDataProfilesMainService, + ) { + super(); + this._register(userDataProfilesService.onWillCreateProfile(e => { + if (userDataProfilesService.profiles.length === 0) { + e.join(this.defaultExtensionsProfileInitService.initialize()); + } + })); + this._register(userDataProfilesService.onDidChangeProfiles(e => { + if (userDataProfilesService.profiles.length === 0) { + this.defaultExtensionsProfileInitService.uninitialize(); + } + })); + } +} diff --git a/src/vs/platform/extensionManagement/electron-sandbox/defaultExtensionsProfileInit.ts b/src/vs/platform/extensionManagement/electron-sandbox/defaultExtensionsProfileInit.ts new file mode 100644 index 00000000000..d353dc77727 --- /dev/null +++ b/src/vs/platform/extensionManagement/electron-sandbox/defaultExtensionsProfileInit.ts @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable } from 'vs/base/common/lifecycle'; +import { joinPath } from 'vs/base/common/resources'; +import { URI } from 'vs/base/common/uri'; +import { IDefaultExtensionsProfileInitService, IExtensionManagementService, ILocalExtension, Metadata } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; +import { ExtensionType } from 'vs/platform/extensions/common/extensions'; +import { IFileService } from 'vs/platform/files/common/files'; +import { EXTENSIONS_RESOURCE_NAME, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; + +export class DefaultExtensionsProfileInitService extends Disposable implements IDefaultExtensionsProfileInitService { + + readonly _serviceBrand: undefined; + + constructor( + @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, + @IFileService private readonly fileService: IFileService, + @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, + @IExtensionsProfileScannerService private readonly extensionsProfileScannerService: IExtensionsProfileScannerService, + ) { + super(); + } + + async initialize(): Promise { + /* Create and populate the default extensions profile resource */ + const extensionsProfileResource = this.getDefaultExtensionsProfileResource(); + try { await this.fileService.del(extensionsProfileResource); } catch (error) { /* ignore */ } + const userExtensions = await this.extensionManagementService.getInstalled(ExtensionType.User); + const extensions: [ILocalExtension, Metadata | undefined][] = await Promise.all(userExtensions.map(async e => ([e, await this.extensionManagementService.getMetadata(e)]))); + await this.extensionsProfileScannerService.addExtensionsToProfile(extensions, extensionsProfileResource); + } + + async uninitialize(): Promise { + /* Remove the default extensions profile resource */ + try { await this.fileService.del(this.getDefaultExtensionsProfileResource()); } catch (error) { /* ignore */ } + } + + private getDefaultExtensionsProfileResource(): URI { + return this.userDataProfilesService.defaultProfile.extensionsResource ?? joinPath(this.userDataProfilesService.defaultProfile.location, EXTENSIONS_RESOURCE_NAME); + } +} diff --git a/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts b/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts index 798abb97873..6cc49e7a131 100644 --- a/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts +++ b/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts @@ -4,19 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { Disposable } from 'vs/base/common/lifecycle'; -import { joinPath } from 'vs/base/common/resources'; -import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; -import { ILocalExtension, Metadata } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; -import { ExtensionType } from 'vs/platform/extensions/common/extensions'; -import { IFileService } from 'vs/platform/files/common/files'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { DidChangeProfilesEvent, EXTENSIONS_RESOURCE_NAME, IUserDataProfile, IUserDataProfilesService, UseDefaultProfileFlags, WorkspaceIdentifier } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { DidChangeProfilesEvent, IUserDataProfile, IUserDataProfilesService, UseDefaultProfileFlags, WorkspaceIdentifier } from 'vs/platform/userDataProfile/common/userDataProfile'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; -import { IExtensionManagementServerService, IWorkbenchExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IUserDataProfileManagementService, IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; @@ -27,10 +20,6 @@ export class UserDataProfileManagementService extends Disposable implements IUse constructor( @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, - @IFileService private readonly fileService: IFileService, - @IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService, - @IWorkbenchExtensionManagementService private readonly extensionManagementService: IWorkbenchExtensionManagementService, - @IExtensionsProfileScannerService private readonly extensionsProfileScannerService: IExtensionsProfileScannerService, @IHostService private readonly hostService: IHostService, @IDialogService private readonly dialogService: IDialogService, @IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService, @@ -51,11 +40,6 @@ export class UserDataProfileManagementService extends Disposable implements IUse async createAndEnterProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, fromExisting?: boolean): Promise { const workspaceIdentifier = this.getWorkspaceIdentifier(); const newProfile = this.userDataProfilesService.newProfile(name, useDefaultFlags); - await this.fileService.createFolder(newProfile.location); - if (!this.userDataProfilesService.defaultProfile.extensionsResource) { - // Extensions profile is not yet created for default profile, create it now - await this.createDefaultExtensionsProfile(joinPath(this.userDataProfilesService.defaultProfile.location, EXTENSIONS_RESOURCE_NAME)); - } const createdProfile = await this.userDataProfilesService.createProfile(newProfile, workspaceIdentifier); await this.enterProfile(createdProfile, !!fromExisting); return createdProfile; @@ -71,11 +55,7 @@ export class UserDataProfileManagementService extends Disposable implements IUse if (profile.id === this.userDataProfileService.currentProfile.id) { throw new Error(localize('cannotDeleteCurrentProfile', "Cannot delete the current profile")); } - const defaultExtensionsResourceToDelete = this.userDataProfilesService.profiles.length === 2 ? this.userDataProfilesService.defaultProfile.extensionsResource : undefined; await this.userDataProfilesService.removeProfile(profile); - if (defaultExtensionsResourceToDelete) { - try { await this.fileService.del(defaultExtensionsResourceToDelete); } catch (error) { /* ignore */ } - } } async switchProfile(profile: IUserDataProfile): Promise { @@ -118,15 +98,6 @@ export class UserDataProfileManagementService extends Disposable implements IUse await this.userDataProfileService.updateCurrentProfile(profile, preserveData); await this.extensionService.startExtensionHosts(); } - - private async createDefaultExtensionsProfile(extensionsProfileResource: URI): Promise { - try { await this.fileService.del(extensionsProfileResource); } catch (error) { /* ignore */ } - const extensionManagementService = this.extensionManagementServerService.localExtensionManagementServer?.extensionManagementService ?? this.extensionManagementService; - const userExtensions = await extensionManagementService.getInstalled(ExtensionType.User); - const extensions: [ILocalExtension, Metadata | undefined][] = await Promise.all(userExtensions.map(async e => ([e, await this.extensionManagementService.getMetadata(e)]))); - await this.extensionsProfileScannerService.addExtensionsToProfile(extensions, extensionsProfileResource); - return extensionsProfileResource; - } } registerSingleton(IUserDataProfileManagementService, UserDataProfileManagementService); -- cgit v1.2.3 From b3d6ef63a72e5f388a86265aae79c238ffd1f4ee Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Jul 2022 10:58:19 +0200 Subject: show error when action fails --- .../contrib/userDataProfile/common/userDataProfileActions.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts b/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts index cda5ca4d8fe..01a3ef3d346 100644 --- a/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts +++ b/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts @@ -117,12 +117,17 @@ registerAction2(class RemoveProfileAction extends Action2 { const userDataProfileService = accessor.get(IUserDataProfileService); const userDataProfilesService = accessor.get(IUserDataProfilesService); const userDataProfileManagementService = accessor.get(IUserDataProfileManagementService); + const notificationService = accessor.get(INotificationService); const profiles = userDataProfilesService.profiles.filter(p => p.id !== userDataProfileService.currentProfile.id && !p.isDefault); if (profiles.length) { const pick = await quickInputService.pick(profiles.map(profile => ({ label: profile.name, profile })), { placeHolder: localize('pick profile', "Select Settings Profile") }); if (pick) { - await userDataProfileManagementService.removeProfile(pick.profile); + try { + await userDataProfileManagementService.removeProfile(pick.profile); + } catch (error) { + notificationService.error(error); + } } } } -- cgit v1.2.3 From 0f52e4b9c12e1750c7ec53f8484472d7fa7f205f Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Jul 2022 11:06:56 +0200 Subject: merge newProfile with createProfile --- .../platform/userDataProfile/common/userDataProfile.ts | 9 ++------- .../userDataProfile/electron-main/userDataProfile.ts | 16 ++++++++-------- .../userDataProfile/electron-sandbox/userDataProfile.ts | 6 +++--- .../electron-main/userDataProfileMainService.test.ts | 4 ++-- .../userDataProfile/browser/userDataProfileManagement.ts | 8 +++----- 5 files changed, 18 insertions(+), 25 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/userDataProfile/common/userDataProfile.ts b/src/vs/platform/userDataProfile/common/userDataProfile.ts index 949133b32f5..e4027d99812 100644 --- a/src/vs/platform/userDataProfile/common/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/common/userDataProfile.ts @@ -78,8 +78,7 @@ export interface IUserDataProfilesService { readonly onDidChangeProfiles: Event; readonly profiles: IUserDataProfile[]; - newProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags): CustomUserDataProfile; - createProfile(profile: IUserDataProfile, workspaceIdentifier?: WorkspaceIdentifier): Promise; + createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier): Promise; setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise; getProfile(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile; removeProfile(profile: IUserDataProfile): Promise; @@ -139,16 +138,12 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf this.profilesHome = joinPath(this.environmentService.userRoamingDataHome, 'profiles'); } - newProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags): CustomUserDataProfile { - return toUserDataProfile(name, joinPath(this.profilesHome, hash(name).toString(16)), useDefaultFlags); - } - protected createDefaultUserDataProfile(extensions: boolean): IUserDataProfile { const profile = toUserDataProfile(localize('defaultProfile', "Default"), this.environmentService.userRoamingDataHome); return { ...profile, isDefault: true, extensionsResource: extensions ? profile.extensionsResource : undefined }; } - createProfile(profile: IUserDataProfile, workspaceIdentifier?: WorkspaceIdentifier): Promise { throw new Error('Not implemented'); } + createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier): Promise { throw new Error('Not implemented'); } setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise { throw new Error('Not implemented'); } getProfile(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile { throw new Error('Not implemented'); } removeProfile(profile: IUserDataProfile): Promise { throw new Error('Not implemented'); } diff --git a/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts b/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts index 7073ead9cda..f890a1e2fcf 100644 --- a/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts @@ -11,10 +11,12 @@ import { refineServiceDecorator } from 'vs/platform/instantiation/common/instant import { ILogService } from 'vs/platform/log/common/log'; import { IStateMainService } from 'vs/platform/state/electron-main/state'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { IUserDataProfile, IUserDataProfilesService, reviveProfile, PROFILES_ENABLEMENT_CONFIG, WorkspaceIdentifier } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUserDataProfile, IUserDataProfilesService, reviveProfile, PROFILES_ENABLEMENT_CONFIG, WorkspaceIdentifier, UseDefaultProfileFlags, toUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile'; import { Promises } from 'vs/base/common/async'; import { StoredProfileAssociations, StoredUserDataProfile, UserDataProfilesService } from 'vs/platform/userDataProfile/node/userDataProfile'; import { IStringDictionary } from 'vs/base/common/collections'; +import { joinPath } from 'vs/base/common/resources'; +import { hash } from 'vs/base/common/hash'; export type WillCreateProfileEvent = { profile: IUserDataProfile; @@ -51,18 +53,16 @@ export class UserDataProfilesMainService extends UserDataProfilesService impleme super(stateMainService, uriIdentityService, environmentService, fileService, logService); } - override async createProfile(profile: IUserDataProfile, workspaceIdentifier?: WorkspaceIdentifier): Promise { + override async createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier): Promise { if (!this.enabled) { throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); } - profile = reviveProfile(profile, this.profilesHome.scheme); - if (this.getStoredProfiles().some(p => p.name === profile.name)) { - throw new Error(`Profile with name ${profile.name} already exists`); + if (this.getStoredProfiles().some(p => p.name === name)) { + throw new Error(`Profile with name ${name} already exists`); } - if (!(await this.fileService.exists(this.profilesHome))) { - await this.fileService.createFolder(this.profilesHome); - } + const profile = toUserDataProfile(name, joinPath(this.profilesHome, hash(name).toString(16)), useDefaultFlags); + await this.fileService.createFolder(profile.location); const joiners: Promise[] = []; this._onWillCreateProfile.fire({ diff --git a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts index 210bd2288b9..417dc0bf5c8 100644 --- a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts @@ -9,7 +9,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IFileService } from 'vs/platform/files/common/files'; import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/services'; import { ILogService } from 'vs/platform/log/common/log'; -import { DidChangeProfilesEvent, IUserDataProfile, IUserDataProfilesService, reviveProfile, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { DidChangeProfilesEvent, IUserDataProfile, IUserDataProfilesService, reviveProfile, UseDefaultProfileFlags, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; export class UserDataProfilesNativeService extends UserDataProfilesService implements IUserDataProfilesService { @@ -37,8 +37,8 @@ export class UserDataProfilesNativeService extends UserDataProfilesService imple })); } - override async createProfile(profile: IUserDataProfile, workspaceIdentifier?: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): Promise { - const result = await this.channel.call>('createProfile', [profile, workspaceIdentifier]); + override async createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): Promise { + const result = await this.channel.call>('createProfile', [name, useDefaultFlags, workspaceIdentifier]); return reviveProfile(result, this.profilesHome.scheme); } diff --git a/src/vs/platform/userDataProfile/test/electron-main/userDataProfileMainService.test.ts b/src/vs/platform/userDataProfile/test/electron-main/userDataProfileMainService.test.ts index b5592746149..ec861ab96f4 100644 --- a/src/vs/platform/userDataProfile/test/electron-main/userDataProfileMainService.test.ts +++ b/src/vs/platform/userDataProfile/test/electron-main/userDataProfileMainService.test.ts @@ -59,13 +59,13 @@ suite('UserDataProfileMainService', () => { }); test('default profile when there are profiles', async () => { - await testObject.createProfile(testObject.newProfile('test')); + await testObject.createProfile('test'); assert.strictEqual(testObject.defaultProfile.isDefault, true); assert.strictEqual(testObject.defaultProfile.extensionsResource?.toString(), joinPath(environmentService.userRoamingDataHome, 'extensions.json').toString()); }); test('default profile when profiles are removed', async () => { - const profile = await testObject.createProfile(testObject.newProfile('test')); + const profile = await testObject.createProfile('test'); await testObject.removeProfile(profile); assert.strictEqual(testObject.defaultProfile.isDefault, true); assert.strictEqual(testObject.defaultProfile.extensionsResource, undefined); diff --git a/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts b/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts index 6cc49e7a131..3b1578dc366 100644 --- a/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts +++ b/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts @@ -38,11 +38,9 @@ export class UserDataProfileManagementService extends Disposable implements IUse } async createAndEnterProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, fromExisting?: boolean): Promise { - const workspaceIdentifier = this.getWorkspaceIdentifier(); - const newProfile = this.userDataProfilesService.newProfile(name, useDefaultFlags); - const createdProfile = await this.userDataProfilesService.createProfile(newProfile, workspaceIdentifier); - await this.enterProfile(createdProfile, !!fromExisting); - return createdProfile; + const profile = await this.userDataProfilesService.createProfile(name, useDefaultFlags, this.getWorkspaceIdentifier()); + await this.enterProfile(profile, !!fromExisting); + return profile; } async removeProfile(profile: IUserDataProfile): Promise { -- cgit v1.2.3 From 8ad7d24334f9b7860706b71983c74ec06bfb377e Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Jul 2022 11:09:47 +0200 Subject: remove migration --- .../common/extensionsProfileScannerService.ts | 37 +--------------------- 1 file changed, 1 insertion(+), 36 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts b/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts index 8acce96e6e1..43c8cfd1e19 100644 --- a/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts +++ b/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts @@ -10,12 +10,10 @@ import { ResourceMap } from 'vs/base/common/map'; import { URI, UriComponents } from 'vs/base/common/uri'; import { ILocalExtension, Metadata } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { IExtensionIdentifier, IExtensionManifest } from 'vs/platform/extensions/common/extensions'; +import { IExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { FileOperationError, FileOperationResult, IFileService } from 'vs/platform/files/common/files'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; -import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; interface IStoredProfileExtension { identifier: IExtensionIdentifier; @@ -43,45 +41,13 @@ export interface IExtensionsProfileScannerService { export class ExtensionsProfileScannerService extends Disposable implements IExtensionsProfileScannerService { readonly _serviceBrand: undefined; - private readonly migratePromise: Promise; private readonly resourcesAccessQueueMap = new ResourceMap>(); constructor( @IFileService private readonly fileService: IFileService, - @IUriIdentityService private readonly uriIdentityService: IUriIdentityService, - @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, @ILogService private readonly logService: ILogService, ) { super(); - this.migratePromise = this.migrate(); - } - - // TODO: @sandy081 remove it in a month - private async migrate(): Promise { - await Promise.all(this.userDataProfilesService.profiles.map(async e => { - if (!e.extensionsResource) { - return; - } - try { - let needsMigrating: boolean = false; - const storedWebExtensions: IStoredProfileExtension[] = JSON.parse((await this.fileService.readFile(e.extensionsResource)).value.toString()); - for (const e of storedWebExtensions) { - if (!e.location) { - continue; - } - if (!e.version) { - try { - const content = (await this.fileService.readFile(this.uriIdentityService.extUri.joinPath(URI.revive(e.location), 'package.json'))).value.toString(); - e.version = (JSON.parse(content)).version; - needsMigrating = true; - } catch (error) { /* ignore */ } - } - } - if (needsMigrating) { - await this.fileService.writeFile(e.extensionsResource, VSBuffer.fromString(JSON.stringify(storedWebExtensions))); - } - } catch (error) { /* Ignore */ } - })); } scanProfileExtensions(profileLocation: URI): Promise { @@ -102,7 +68,6 @@ export class ExtensionsProfileScannerService extends Disposable implements IExte } private async withProfileExtensions(file: URI, updateFn?: (extensions: IScannedProfileExtension[]) => IScannedProfileExtension[]): Promise { - await this.migratePromise; return this.getResourceAccessQueue(file).queue(async () => { let extensions: IScannedProfileExtension[] = []; -- cgit v1.2.3 From 0f3bbc794aa9c0c06a150097f4d61144c329b57d Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 03:58:41 -0700 Subject: Move resizable to base This is a generally useful component, should be in base --- src/vs/base/browser/ui/resizable/resizable.ts | 190 +++++++++++++++++++++ src/vs/editor/contrib/suggest/browser/resizable.ts | 190 --------------------- .../contrib/suggest/browser/suggestWidget.ts | 2 +- .../suggest/browser/suggestWidgetDetails.ts | 2 +- 4 files changed, 192 insertions(+), 192 deletions(-) create mode 100644 src/vs/base/browser/ui/resizable/resizable.ts delete mode 100644 src/vs/editor/contrib/suggest/browser/resizable.ts (limited to 'src/vs') diff --git a/src/vs/base/browser/ui/resizable/resizable.ts b/src/vs/base/browser/ui/resizable/resizable.ts new file mode 100644 index 00000000000..95dfb06b8d0 --- /dev/null +++ b/src/vs/base/browser/ui/resizable/resizable.ts @@ -0,0 +1,190 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Dimension } from 'vs/base/browser/dom'; +import { Orientation, OrthogonalEdge, Sash, SashState } from 'vs/base/browser/ui/sash/sash'; +import { Emitter, Event } from 'vs/base/common/event'; +import { DisposableStore } from 'vs/base/common/lifecycle'; + + +export interface IResizeEvent { + dimension: Dimension; + done: boolean; + north?: boolean; + east?: boolean; + south?: boolean; + west?: boolean; +} + +export class ResizableHTMLElement { + + readonly domNode: HTMLElement; + + private readonly _onDidWillResize = new Emitter(); + readonly onDidWillResize: Event = this._onDidWillResize.event; + + private readonly _onDidResize = new Emitter(); + readonly onDidResize: Event = this._onDidResize.event; + + private readonly _northSash: Sash; + private readonly _eastSash: Sash; + private readonly _southSash: Sash; + private readonly _westSash: Sash; + private readonly _sashListener = new DisposableStore(); + + private _size = new Dimension(0, 0); + private _minSize = new Dimension(0, 0); + private _maxSize = new Dimension(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER); + private _preferredSize?: Dimension; + + constructor() { + this.domNode = document.createElement('div'); + this._eastSash = new Sash(this.domNode, { getVerticalSashLeft: () => this._size.width }, { orientation: Orientation.VERTICAL }); + this._westSash = new Sash(this.domNode, { getVerticalSashLeft: () => 0 }, { orientation: Orientation.VERTICAL }); + this._northSash = new Sash(this.domNode, { getHorizontalSashTop: () => 0 }, { orientation: Orientation.HORIZONTAL, orthogonalEdge: OrthogonalEdge.North }); + this._southSash = new Sash(this.domNode, { getHorizontalSashTop: () => this._size.height }, { orientation: Orientation.HORIZONTAL, orthogonalEdge: OrthogonalEdge.South }); + + this._northSash.orthogonalStartSash = this._westSash; + this._northSash.orthogonalEndSash = this._eastSash; + this._southSash.orthogonalStartSash = this._westSash; + this._southSash.orthogonalEndSash = this._eastSash; + + let currentSize: Dimension | undefined; + let deltaY = 0; + let deltaX = 0; + + this._sashListener.add(Event.any(this._northSash.onDidStart, this._eastSash.onDidStart, this._southSash.onDidStart, this._westSash.onDidStart)(() => { + if (currentSize === undefined) { + this._onDidWillResize.fire(); + currentSize = this._size; + deltaY = 0; + deltaX = 0; + } + })); + this._sashListener.add(Event.any(this._northSash.onDidEnd, this._eastSash.onDidEnd, this._southSash.onDidEnd, this._westSash.onDidEnd)(() => { + if (currentSize !== undefined) { + currentSize = undefined; + deltaY = 0; + deltaX = 0; + this._onDidResize.fire({ dimension: this._size, done: true }); + } + })); + + this._sashListener.add(this._eastSash.onDidChange(e => { + if (currentSize) { + deltaX = e.currentX - e.startX; + this.layout(currentSize.height + deltaY, currentSize.width + deltaX); + this._onDidResize.fire({ dimension: this._size, done: false, east: true }); + } + })); + this._sashListener.add(this._westSash.onDidChange(e => { + if (currentSize) { + deltaX = -(e.currentX - e.startX); + this.layout(currentSize.height + deltaY, currentSize.width + deltaX); + this._onDidResize.fire({ dimension: this._size, done: false, west: true }); + } + })); + this._sashListener.add(this._northSash.onDidChange(e => { + if (currentSize) { + deltaY = -(e.currentY - e.startY); + this.layout(currentSize.height + deltaY, currentSize.width + deltaX); + this._onDidResize.fire({ dimension: this._size, done: false, north: true }); + } + })); + this._sashListener.add(this._southSash.onDidChange(e => { + if (currentSize) { + deltaY = e.currentY - e.startY; + this.layout(currentSize.height + deltaY, currentSize.width + deltaX); + this._onDidResize.fire({ dimension: this._size, done: false, south: true }); + } + })); + + this._sashListener.add(Event.any(this._eastSash.onDidReset, this._westSash.onDidReset)(e => { + if (this._preferredSize) { + this.layout(this._size.height, this._preferredSize.width); + this._onDidResize.fire({ dimension: this._size, done: true }); + } + })); + this._sashListener.add(Event.any(this._northSash.onDidReset, this._southSash.onDidReset)(e => { + if (this._preferredSize) { + this.layout(this._preferredSize.height, this._size.width); + this._onDidResize.fire({ dimension: this._size, done: true }); + } + })); + } + + dispose(): void { + this._northSash.dispose(); + this._southSash.dispose(); + this._eastSash.dispose(); + this._westSash.dispose(); + this._sashListener.dispose(); + this._onDidResize.dispose(); + this._onDidWillResize.dispose(); + this.domNode.remove(); + } + + enableSashes(north: boolean, east: boolean, south: boolean, west: boolean): void { + this._northSash.state = north ? SashState.Enabled : SashState.Disabled; + this._eastSash.state = east ? SashState.Enabled : SashState.Disabled; + this._southSash.state = south ? SashState.Enabled : SashState.Disabled; + this._westSash.state = west ? SashState.Enabled : SashState.Disabled; + } + + layout(height: number = this.size.height, width: number = this.size.width): void { + + const { height: minHeight, width: minWidth } = this._minSize; + const { height: maxHeight, width: maxWidth } = this._maxSize; + + height = Math.max(minHeight, Math.min(maxHeight, height)); + width = Math.max(minWidth, Math.min(maxWidth, width)); + + const newSize = new Dimension(width, height); + if (!Dimension.equals(newSize, this._size)) { + this.domNode.style.height = height + 'px'; + this.domNode.style.width = width + 'px'; + this._size = newSize; + this._northSash.layout(); + this._eastSash.layout(); + this._southSash.layout(); + this._westSash.layout(); + } + } + + clearSashHoverState(): void { + this._eastSash.clearSashHoverState(); + this._westSash.clearSashHoverState(); + this._northSash.clearSashHoverState(); + this._southSash.clearSashHoverState(); + } + + get size() { + return this._size; + } + + set maxSize(value: Dimension) { + this._maxSize = value; + } + + get maxSize() { + return this._maxSize; + } + + set minSize(value: Dimension) { + this._minSize = value; + } + + get minSize() { + return this._minSize; + } + + set preferredSize(value: Dimension | undefined) { + this._preferredSize = value; + } + + get preferredSize() { + return this._preferredSize; + } +} diff --git a/src/vs/editor/contrib/suggest/browser/resizable.ts b/src/vs/editor/contrib/suggest/browser/resizable.ts deleted file mode 100644 index 95dfb06b8d0..00000000000 --- a/src/vs/editor/contrib/suggest/browser/resizable.ts +++ /dev/null @@ -1,190 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Dimension } from 'vs/base/browser/dom'; -import { Orientation, OrthogonalEdge, Sash, SashState } from 'vs/base/browser/ui/sash/sash'; -import { Emitter, Event } from 'vs/base/common/event'; -import { DisposableStore } from 'vs/base/common/lifecycle'; - - -export interface IResizeEvent { - dimension: Dimension; - done: boolean; - north?: boolean; - east?: boolean; - south?: boolean; - west?: boolean; -} - -export class ResizableHTMLElement { - - readonly domNode: HTMLElement; - - private readonly _onDidWillResize = new Emitter(); - readonly onDidWillResize: Event = this._onDidWillResize.event; - - private readonly _onDidResize = new Emitter(); - readonly onDidResize: Event = this._onDidResize.event; - - private readonly _northSash: Sash; - private readonly _eastSash: Sash; - private readonly _southSash: Sash; - private readonly _westSash: Sash; - private readonly _sashListener = new DisposableStore(); - - private _size = new Dimension(0, 0); - private _minSize = new Dimension(0, 0); - private _maxSize = new Dimension(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER); - private _preferredSize?: Dimension; - - constructor() { - this.domNode = document.createElement('div'); - this._eastSash = new Sash(this.domNode, { getVerticalSashLeft: () => this._size.width }, { orientation: Orientation.VERTICAL }); - this._westSash = new Sash(this.domNode, { getVerticalSashLeft: () => 0 }, { orientation: Orientation.VERTICAL }); - this._northSash = new Sash(this.domNode, { getHorizontalSashTop: () => 0 }, { orientation: Orientation.HORIZONTAL, orthogonalEdge: OrthogonalEdge.North }); - this._southSash = new Sash(this.domNode, { getHorizontalSashTop: () => this._size.height }, { orientation: Orientation.HORIZONTAL, orthogonalEdge: OrthogonalEdge.South }); - - this._northSash.orthogonalStartSash = this._westSash; - this._northSash.orthogonalEndSash = this._eastSash; - this._southSash.orthogonalStartSash = this._westSash; - this._southSash.orthogonalEndSash = this._eastSash; - - let currentSize: Dimension | undefined; - let deltaY = 0; - let deltaX = 0; - - this._sashListener.add(Event.any(this._northSash.onDidStart, this._eastSash.onDidStart, this._southSash.onDidStart, this._westSash.onDidStart)(() => { - if (currentSize === undefined) { - this._onDidWillResize.fire(); - currentSize = this._size; - deltaY = 0; - deltaX = 0; - } - })); - this._sashListener.add(Event.any(this._northSash.onDidEnd, this._eastSash.onDidEnd, this._southSash.onDidEnd, this._westSash.onDidEnd)(() => { - if (currentSize !== undefined) { - currentSize = undefined; - deltaY = 0; - deltaX = 0; - this._onDidResize.fire({ dimension: this._size, done: true }); - } - })); - - this._sashListener.add(this._eastSash.onDidChange(e => { - if (currentSize) { - deltaX = e.currentX - e.startX; - this.layout(currentSize.height + deltaY, currentSize.width + deltaX); - this._onDidResize.fire({ dimension: this._size, done: false, east: true }); - } - })); - this._sashListener.add(this._westSash.onDidChange(e => { - if (currentSize) { - deltaX = -(e.currentX - e.startX); - this.layout(currentSize.height + deltaY, currentSize.width + deltaX); - this._onDidResize.fire({ dimension: this._size, done: false, west: true }); - } - })); - this._sashListener.add(this._northSash.onDidChange(e => { - if (currentSize) { - deltaY = -(e.currentY - e.startY); - this.layout(currentSize.height + deltaY, currentSize.width + deltaX); - this._onDidResize.fire({ dimension: this._size, done: false, north: true }); - } - })); - this._sashListener.add(this._southSash.onDidChange(e => { - if (currentSize) { - deltaY = e.currentY - e.startY; - this.layout(currentSize.height + deltaY, currentSize.width + deltaX); - this._onDidResize.fire({ dimension: this._size, done: false, south: true }); - } - })); - - this._sashListener.add(Event.any(this._eastSash.onDidReset, this._westSash.onDidReset)(e => { - if (this._preferredSize) { - this.layout(this._size.height, this._preferredSize.width); - this._onDidResize.fire({ dimension: this._size, done: true }); - } - })); - this._sashListener.add(Event.any(this._northSash.onDidReset, this._southSash.onDidReset)(e => { - if (this._preferredSize) { - this.layout(this._preferredSize.height, this._size.width); - this._onDidResize.fire({ dimension: this._size, done: true }); - } - })); - } - - dispose(): void { - this._northSash.dispose(); - this._southSash.dispose(); - this._eastSash.dispose(); - this._westSash.dispose(); - this._sashListener.dispose(); - this._onDidResize.dispose(); - this._onDidWillResize.dispose(); - this.domNode.remove(); - } - - enableSashes(north: boolean, east: boolean, south: boolean, west: boolean): void { - this._northSash.state = north ? SashState.Enabled : SashState.Disabled; - this._eastSash.state = east ? SashState.Enabled : SashState.Disabled; - this._southSash.state = south ? SashState.Enabled : SashState.Disabled; - this._westSash.state = west ? SashState.Enabled : SashState.Disabled; - } - - layout(height: number = this.size.height, width: number = this.size.width): void { - - const { height: minHeight, width: minWidth } = this._minSize; - const { height: maxHeight, width: maxWidth } = this._maxSize; - - height = Math.max(minHeight, Math.min(maxHeight, height)); - width = Math.max(minWidth, Math.min(maxWidth, width)); - - const newSize = new Dimension(width, height); - if (!Dimension.equals(newSize, this._size)) { - this.domNode.style.height = height + 'px'; - this.domNode.style.width = width + 'px'; - this._size = newSize; - this._northSash.layout(); - this._eastSash.layout(); - this._southSash.layout(); - this._westSash.layout(); - } - } - - clearSashHoverState(): void { - this._eastSash.clearSashHoverState(); - this._westSash.clearSashHoverState(); - this._northSash.clearSashHoverState(); - this._southSash.clearSashHoverState(); - } - - get size() { - return this._size; - } - - set maxSize(value: Dimension) { - this._maxSize = value; - } - - get maxSize() { - return this._maxSize; - } - - set minSize(value: Dimension) { - this._minSize = value; - } - - get minSize() { - return this._minSize; - } - - set preferredSize(value: Dimension | undefined) { - this._preferredSize = value; - } - - get preferredSize() { - return this._preferredSize; - } -} diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts index 3a03d2da7dd..74cffe08fe9 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts @@ -30,7 +30,7 @@ import { attachListStyler } from 'vs/platform/theme/common/styler'; import { isHighContrast } from 'vs/platform/theme/common/theme'; import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService'; import { CompletionModel } from './completionModel'; -import { ResizableHTMLElement } from './resizable'; +import { ResizableHTMLElement } from '../../../../base/browser/ui/resizable/resizable'; import { CompletionItem, Context as SuggestContext } from './suggest'; import { canExpandCompletionItem, SuggestDetailsOverlay, SuggestDetailsWidget } from './suggestWidgetDetails'; import { getAriaId, ItemRenderer } from './suggestWidgetRenderer'; diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts b/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts index e9d6c4c5130..cd6e10771c0 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts @@ -12,7 +12,7 @@ import { DisposableStore } from 'vs/base/common/lifecycle'; import { MarkdownRenderer } from 'vs/editor/contrib/markdownRenderer/browser/markdownRenderer'; import { ICodeEditor, IOverlayWidget } from 'vs/editor/browser/editorBrowser'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; -import { ResizableHTMLElement } from 'vs/editor/contrib/suggest/browser/resizable'; +import { ResizableHTMLElement } from 'vs/base/browser/ui/resizable/resizable'; import * as nls from 'vs/nls'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { CompletionItem } from './suggest'; -- cgit v1.2.3 From 01d119a39c9ee60cb834d90b6d8e561b97bb91bb Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 6 Jul 2022 13:06:34 +0200 Subject: select the symbol under cursor when opening quick pick (#154247) fixes https://github.com/microsoft/vscode/issues/154246 --- .../quickAccess/browser/gotoSymbolQuickAccess.ts | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src/vs') diff --git a/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts b/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts index 1801ab78538..b1ba09a6133 100644 --- a/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts +++ b/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts @@ -19,6 +19,7 @@ import { AbstractEditorNavigationQuickAccessProvider, IEditorNavigationQuickAcce import { localize } from 'vs/nls'; import { IQuickPick, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; +import { Position } from 'vs/editor/common/core/position'; export interface IGotoSymbolQuickPickItem extends IQuickPickItem { kind: SymbolKind; @@ -155,7 +156,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit // Set initial picks and update on type let picksCts: CancellationTokenSource | undefined = undefined; - const updatePickerItems = async () => { + const updatePickerItems = async (positionToEnclose: Position | undefined) => { // Cancel any previous ask for picks and busy picksCts?.dispose(true); @@ -175,6 +176,13 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit if (items.length > 0) { picker.items = items; + if (positionToEnclose && query.original.length === 0) { + const candidate = items.find(item => item.type !== 'separator' && item.range && Range.containsPosition(item.range.decoration, positionToEnclose)); + if (candidate) { + picker.activeItems = [candidate]; + } + } + } else { if (query.original.length > 0) { this.provideLabelPick(picker, localize('noMatchingSymbolResults', "No matching editor symbols")); @@ -188,19 +196,19 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit } } }; - disposables.add(picker.onDidChangeValue(() => updatePickerItems())); - updatePickerItems(); + disposables.add(picker.onDidChangeValue(() => updatePickerItems(undefined))); + updatePickerItems(editor.getSelection()?.getPosition()); + // Reveal and decorate when active item changes - // However, ignore the very first event so that + // However, ignore the very first two events so that // opening the picker is not immediately revealing // and decorating the first entry. - let ignoreFirstActiveEvent = true; + let ignoreFirstActiveEvent = 2; disposables.add(picker.onDidChangeActive(() => { const [item] = picker.activeItems; if (item && item.range) { - if (ignoreFirstActiveEvent) { - ignoreFirstActiveEvent = false; + if (ignoreFirstActiveEvent-- > 0) { return; } -- cgit v1.2.3 From b94a4bf43814fb4582a5f5e5cf8c48ecd2b90766 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Jul 2022 13:19:07 +0200 Subject: always include default profile in the profiles --- .../sharedProcess/contrib/extensionsCleaner.ts | 4 ++-- .../electron-main/defaultExtensionsProfileInit.ts | 4 ++-- .../test/node/extensionsScannerService.test.ts | 5 +--- .../userDataProfile/common/userDataProfile.ts | 5 ++-- .../electron-main/userDataProfile.ts | 28 ++++++++++++---------- .../userDataProfile/node/userDataProfile.ts | 7 ++---- .../test/common/userDataProfileService.test.ts | 6 +++-- .../userDataProfileMainService.test.ts | 6 +++-- .../userDataProfile/browser/userDataProfile.ts | 2 +- 9 files changed, 33 insertions(+), 34 deletions(-) (limited to 'src/vs') diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/extensionsCleaner.ts b/src/vs/code/electron-browser/sharedProcess/contrib/extensionsCleaner.ts index 221d77ffdfa..0116d6e8aa8 100644 --- a/src/vs/code/electron-browser/sharedProcess/contrib/extensionsCleaner.ts +++ b/src/vs/code/electron-browser/sharedProcess/contrib/extensionsCleaner.ts @@ -34,7 +34,7 @@ export class ExtensionsCleaner extends Disposable { ) { super(); - extensionManagementService.removeUninstalledExtensions(this.userDataProfilesService.profiles.length === 0); + extensionManagementService.removeUninstalledExtensions(this.userDataProfilesService.profiles.length === 1); migrateUnsupportedExtensions(extensionManagementService, extensionGalleryService, extensionStorageService, extensionEnablementService, logService); ExtensionStorageService.removeOutdatedExtensionVersions(extensionManagementService, storageService); this._register(instantiationService.createInstance(ProfileExtensionsCleaner)); @@ -66,7 +66,7 @@ class ProfileExtensionsCleaner extends Disposable { this.logService.error(error); } - if (all.length === 0) { + if (all.length === 1) { // Exit profile mode this.profileModeDisposables.clear(); // Listen for entering into profile mode diff --git a/src/vs/platform/extensionManagement/electron-main/defaultExtensionsProfileInit.ts b/src/vs/platform/extensionManagement/electron-main/defaultExtensionsProfileInit.ts index 2db8dfaa0d8..fd3d1698683 100644 --- a/src/vs/platform/extensionManagement/electron-main/defaultExtensionsProfileInit.ts +++ b/src/vs/platform/extensionManagement/electron-main/defaultExtensionsProfileInit.ts @@ -14,12 +14,12 @@ export class DefaultExtensionsProfileInitHandler extends Disposable { ) { super(); this._register(userDataProfilesService.onWillCreateProfile(e => { - if (userDataProfilesService.profiles.length === 0) { + if (userDataProfilesService.profiles.length === 1) { e.join(this.defaultExtensionsProfileInitService.initialize()); } })); this._register(userDataProfilesService.onDidChangeProfiles(e => { - if (userDataProfilesService.profiles.length === 0) { + if (userDataProfilesService.profiles.length === 1) { this.defaultExtensionsProfileInitService.uninitialize(); } })); diff --git a/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts b/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts index 54a7232c285..cdfaa38b842 100644 --- a/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts +++ b/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts @@ -17,7 +17,6 @@ import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFil import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { ILogService, NullLogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; -import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; let translations: Translations = Object.create(null); @@ -70,9 +69,7 @@ suite('NativeExtensionsScanerService Test', () => { extensionsPath: userExtensionsLocation.fsPath, }); instantiationService.stub(IProductService, { version: '1.66.0' }); - const uriIdentityService = new UriIdentityService(fileService); - const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); - instantiationService.stub(IExtensionsProfileScannerService, new ExtensionsProfileScannerService(fileService, uriIdentityService, userDataProfilesService, logService)); + instantiationService.stub(IExtensionsProfileScannerService, new ExtensionsProfileScannerService(fileService, logService)); instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); await fileService.createFolder(systemExtensionsLocation); await fileService.createFolder(userExtensionsLocation); diff --git a/src/vs/platform/userDataProfile/common/userDataProfile.ts b/src/vs/platform/userDataProfile/common/userDataProfile.ts index e4027d99812..423be13c443 100644 --- a/src/vs/platform/userDataProfile/common/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/common/userDataProfile.ts @@ -122,9 +122,8 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf readonly profilesHome: URI; - private readonly _defaultProfile = this.createDefaultUserDataProfile(false); - get defaultProfile(): IUserDataProfile { return this.profiles[0] ?? this._defaultProfile; } - get profiles(): IUserDataProfile[] { return []; } + get defaultProfile(): IUserDataProfile { return this.profiles[0]; } + get profiles(): IUserDataProfile[] { return [this.createDefaultUserDataProfile(false)]; } protected readonly _onDidChangeProfiles = this._register(new Emitter()); readonly onDidChangeProfiles = this._onDidChangeProfiles.event; diff --git a/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts b/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts index f890a1e2fcf..ae1c744da24 100644 --- a/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts @@ -11,7 +11,7 @@ import { refineServiceDecorator } from 'vs/platform/instantiation/common/instant import { ILogService } from 'vs/platform/log/common/log'; import { IStateMainService } from 'vs/platform/state/electron-main/state'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { IUserDataProfile, IUserDataProfilesService, reviveProfile, PROFILES_ENABLEMENT_CONFIG, WorkspaceIdentifier, UseDefaultProfileFlags, toUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUserDataProfile, IUserDataProfilesService, PROFILES_ENABLEMENT_CONFIG, WorkspaceIdentifier, UseDefaultProfileFlags, toUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile'; import { Promises } from 'vs/base/common/async'; import { StoredProfileAssociations, StoredUserDataProfile, UserDataProfilesService } from 'vs/platform/userDataProfile/node/userDataProfile'; import { IStringDictionary } from 'vs/base/common/collections'; @@ -79,38 +79,40 @@ export class UserDataProfilesMainService extends UserDataProfilesService impleme await this.setProfileForWorkspace(profile, workspaceIdentifier); } - return this.profiles.find(p => this.uriIdentityService.extUri.isEqual(p.location, profile.location))!; + return profile; } - override async setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise { + override async setProfileForWorkspace(profileToSet: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise { if (!this.enabled) { throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); } - profile = reviveProfile(profile, this.profilesHome.scheme); - this.updateWorkspaceAssociation(workspaceIdentifier, profile); + const profile = this.profiles.find(p => p.id === profileToSet.id); + if (!profile) { + throw new Error(`Profile '${profileToSet.name}' does not exist`); + } - return this.profiles.find(p => this.uriIdentityService.extUri.isEqual(p.location, profile.location))!; + this.updateWorkspaceAssociation(workspaceIdentifier, profile); + return profile; } async unsetWorkspace(workspaceIdentifier: WorkspaceIdentifier): Promise { if (!this.enabled) { throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); } - this.updateWorkspaceAssociation(workspaceIdentifier); } - override async removeProfile(profile: IUserDataProfile): Promise { + override async removeProfile(profileToRemove: IUserDataProfile): Promise { if (!this.enabled) { throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); } - if (profile.isDefault) { + if (profileToRemove.isDefault) { throw new Error('Cannot remove default profile'); } - profile = reviveProfile(profile, this.profilesHome.scheme); - if (!this.getStoredProfiles().some(p => this.uriIdentityService.extUri.isEqual(p.location, profile.location))) { - throw new Error(`Profile with name ${profile.name} does not exist`); + const profile = this.profiles.find(p => p.id === profileToRemove.id); + if (!profile) { + throw new Error(`Profile '${profileToRemove.name}' does not exist`); } const joiners: Promise[] = []; @@ -135,7 +137,7 @@ export class UserDataProfilesMainService extends UserDataProfilesService impleme this.updateProfiles([], [profile]); try { - if (this.profiles.length === 2) { + if (this.profiles.length === 1) { await this.fileService.del(this.profilesHome, { recursive: true }); } else { await this.fileService.del(profile.location, { recursive: true }); diff --git a/src/vs/platform/userDataProfile/node/userDataProfile.ts b/src/vs/platform/userDataProfile/node/userDataProfile.ts index a7b7c247891..34428dd9689 100644 --- a/src/vs/platform/userDataProfile/node/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/node/userDataProfile.ts @@ -57,15 +57,11 @@ export class UserDataProfilesService extends BaseUserDataProfilesService impleme protected _profilesObject: UserDataProfilesObject | undefined; protected get profilesObject(): UserDataProfilesObject { - if (!this.enabled) { - return { profiles: [], workspaces: new ResourceMap() }; - } if (!this._profilesObject) { - const profiles = this.getStoredProfiles().map(storedProfile => toUserDataProfile(storedProfile.name, storedProfile.location, storedProfile.useDefaultFlags)); + const profiles = this.enabled ? this.getStoredProfiles().map(storedProfile => toUserDataProfile(storedProfile.name, storedProfile.location, storedProfile.useDefaultFlags)) : []; let emptyWindow: IUserDataProfile | undefined; const workspaces = new ResourceMap(); if (profiles.length) { - profiles.unshift(this.createDefaultUserDataProfile(true)); const profileAssicaitions = this.getStoredProfileAssociations(); if (profileAssicaitions.workspaces) { for (const [workspacePath, profilePath] of Object.entries(profileAssicaitions.workspaces)) { @@ -82,6 +78,7 @@ export class UserDataProfilesService extends BaseUserDataProfilesService impleme emptyWindow = profiles.find(p => this.uriIdentityService.extUri.isEqual(p.location, emptyWindowProfileLocation)); } } + profiles.unshift(this.createDefaultUserDataProfile(profiles.length > 0)); this._profilesObject = { profiles, workspaces, emptyWindow }; } return this._profilesObject; diff --git a/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts b/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts index b284dd6fd70..549c686644c 100644 --- a/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts +++ b/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts @@ -54,8 +54,10 @@ suite('UserDataProfileService (Common)', () => { assert.strictEqual(testObject.defaultProfile.extensionsResource, undefined); }); - test('profiles are empty', () => { - assert.deepStrictEqual(testObject.profiles, []); + test('profiles always include default profile', () => { + assert.deepStrictEqual(testObject.profiles.length, 1); + assert.deepStrictEqual(testObject.profiles[0].isDefault, true); + assert.deepStrictEqual(testObject.profiles[0].extensionsResource, undefined); }); diff --git a/src/vs/platform/userDataProfile/test/electron-main/userDataProfileMainService.test.ts b/src/vs/platform/userDataProfile/test/electron-main/userDataProfileMainService.test.ts index ec861ab96f4..23e7656a1ad 100644 --- a/src/vs/platform/userDataProfile/test/electron-main/userDataProfileMainService.test.ts +++ b/src/vs/platform/userDataProfile/test/electron-main/userDataProfileMainService.test.ts @@ -54,8 +54,10 @@ suite('UserDataProfileMainService', () => { assert.strictEqual(testObject.defaultProfile.extensionsResource, undefined); }); - test('profiles are empty', () => { - assert.deepStrictEqual(testObject.profiles, []); + test('profiles always include default profile', () => { + assert.deepStrictEqual(testObject.profiles.length, 1); + assert.deepStrictEqual(testObject.profiles[0].isDefault, true); + assert.deepStrictEqual(testObject.profiles[0].extensionsResource, undefined); }); test('default profile when there are profiles', async () => { diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts index 8a75af540d3..44aa262be18 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts @@ -133,7 +133,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements private profileStatusAccessor: IStatusbarEntryAccessor | undefined; private updateStatus(): void { - if (this.userDataProfilesService.profiles.length) { + if (this.userDataProfilesService.profiles.length > 1) { const statusBarEntry: IStatusbarEntry = { name: PROFILES_CATEGORY, command: 'workbench.profiles.actions.switchProfile', -- cgit v1.2.3 From 2f5975cb43b72e6795d0ee75788151a6f7b087e3 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 04:27:56 -0700 Subject: Relative -> absolute path --- src/vs/editor/contrib/suggest/browser/suggestWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts index 74cffe08fe9..987961a013c 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts @@ -30,7 +30,7 @@ import { attachListStyler } from 'vs/platform/theme/common/styler'; import { isHighContrast } from 'vs/platform/theme/common/theme'; import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService'; import { CompletionModel } from './completionModel'; -import { ResizableHTMLElement } from '../../../../base/browser/ui/resizable/resizable'; +import { ResizableHTMLElement } from 'vs/base/browser/ui/resizable/resizable'; import { CompletionItem, Context as SuggestContext } from './suggest'; import { canExpandCompletionItem, SuggestDetailsOverlay, SuggestDetailsWidget } from './suggestWidgetDetails'; import { getAriaId, ItemRenderer } from './suggestWidgetRenderer'; -- cgit v1.2.3 From d2b2d407621e23b5886c69e3987977b06aafdd64 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Jul 2022 13:29:38 +0200 Subject: remove return type for setProfileForWorkspace --- src/vs/platform/userDataProfile/common/userDataProfile.ts | 4 ++-- src/vs/platform/userDataProfile/electron-main/userDataProfile.ts | 3 +-- src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/userDataProfile/common/userDataProfile.ts b/src/vs/platform/userDataProfile/common/userDataProfile.ts index 423be13c443..375166c4ce5 100644 --- a/src/vs/platform/userDataProfile/common/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/common/userDataProfile.ts @@ -79,7 +79,7 @@ export interface IUserDataProfilesService { readonly profiles: IUserDataProfile[]; createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier): Promise; - setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise; + setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise; getProfile(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile; removeProfile(profile: IUserDataProfile): Promise; } @@ -143,7 +143,7 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf } createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier): Promise { throw new Error('Not implemented'); } - setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise { throw new Error('Not implemented'); } + setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise { throw new Error('Not implemented'); } getProfile(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile { throw new Error('Not implemented'); } removeProfile(profile: IUserDataProfile): Promise { throw new Error('Not implemented'); } } diff --git a/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts b/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts index ae1c744da24..e52855d4867 100644 --- a/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts @@ -82,7 +82,7 @@ export class UserDataProfilesMainService extends UserDataProfilesService impleme return profile; } - override async setProfileForWorkspace(profileToSet: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise { + override async setProfileForWorkspace(profileToSet: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise { if (!this.enabled) { throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); } @@ -93,7 +93,6 @@ export class UserDataProfilesMainService extends UserDataProfilesService impleme } this.updateWorkspaceAssociation(workspaceIdentifier, profile); - return profile; } async unsetWorkspace(workspaceIdentifier: WorkspaceIdentifier): Promise { diff --git a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts index 417dc0bf5c8..9d999933058 100644 --- a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts @@ -42,9 +42,8 @@ export class UserDataProfilesNativeService extends UserDataProfilesService imple return reviveProfile(result, this.profilesHome.scheme); } - override async setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): Promise { - const result = await this.channel.call>('setProfileForWorkspace', [profile, workspaceIdentifier]); - return reviveProfile(result, this.profilesHome.scheme); + override async setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): Promise { + await this.channel.call>('setProfileForWorkspace', [profile, workspaceIdentifier]); } override removeProfile(profile: IUserDataProfile): Promise { -- cgit v1.2.3 From 92b276d6d095d33e638a95a7a03fa5b8d3894e4e Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 6 Jul 2022 13:37:21 +0200 Subject: support `noSelect` for the `editor.action.triggerSuggest` command (#154251) This allows to trigger suggest (as normal) but not select an item, https://github.com/microsoft/vscode/issues/151336 --- src/vs/editor/contrib/suggest/browser/suggest.ts | 1 + .../contrib/suggest/browser/suggestController.ts | 29 ++++++++++------- .../editor/contrib/suggest/browser/suggestModel.ts | 27 +++++++++------- .../contrib/suggest/browser/suggestWidget.ts | 12 +++++-- .../suggest/test/browser/suggestModel.test.ts | 37 +++++++++++++++------- 5 files changed, 70 insertions(+), 36 deletions(-) (limited to 'src/vs') diff --git a/src/vs/editor/contrib/suggest/browser/suggest.ts b/src/vs/editor/contrib/suggest/browser/suggest.ts index 59e61786894..805c58df531 100644 --- a/src/vs/editor/contrib/suggest/browser/suggest.ts +++ b/src/vs/editor/contrib/suggest/browser/suggest.ts @@ -31,6 +31,7 @@ import { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes'; export const Context = { Visible: historyNavigationVisible, + HasFocusedSuggestion: new RawContextKey('suggestWidgetHasFocusedSuggestion', false, localize('suggestWidgetHasSelection', "Whether any suggestion is focused")), DetailsVisible: new RawContextKey('suggestWidgetDetailsVisible', false, localize('suggestWidgetDetailsVisible', "Whether suggestion details are visible")), MultipleSuggestions: new RawContextKey('suggestWidgetMultipleSuggestions', false, localize('suggestWidgetMultipleSuggestions', "Whether there are multiple suggestions to pick from")), MakesTextEdit: new RawContextKey('suggestionMakesTextEdit', true, localize('suggestionMakesTextEdit', "Whether inserting the current suggestion yields in a change or has everything already been typed")), diff --git a/src/vs/editor/contrib/suggest/browser/suggestController.ts b/src/vs/editor/contrib/suggest/browser/suggestController.ts index c3b80a8c5e9..14045fe6bec 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestController.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestController.ts @@ -226,8 +226,11 @@ export class SuggestController implements IEditorContribution { this._lineSuffix.value = new LineSuffix(this.editor.getModel()!, e.position); })); this._toDispose.add(this.model.onDidSuggest(e => { - if (!e.shy) { - let index = -1; + if (e.shy) { + return; + } + let index = -1; + if (!e.noSelect) { for (const selector of this._selectors.itemsOrderedByPriorityDesc) { index = selector.select(this.editor.getModel()!, this.editor.getPosition()!, e.completionModel.items); if (index !== -1) { @@ -237,8 +240,8 @@ export class SuggestController implements IEditorContribution { if (index === -1) { index = this._memoryService.select(this.editor.getModel()!, this.editor.getPosition()!, e.completionModel.items); } - this.widget.value.showSuggestions(e.completionModel, index, e.isFrozen, e.auto); } + this.widget.value.showSuggestions(e.completionModel, index, e.isFrozen, e.auto); })); this._toDispose.add(this.model.onDidCancel(e => { if (!e.retrigger) { @@ -400,7 +403,7 @@ export class SuggestController implements IEditorContribution { } else if (item.completion.command.id === TriggerSuggestAction.id) { // retigger - this.model.trigger({ auto: true, shy: false }, true); + this.model.trigger({ auto: true, shy: false, noSelect: false }, true); } else { // exec command, done @@ -494,9 +497,9 @@ export class SuggestController implements IEditorContribution { } } - triggerSuggest(onlyFrom?: Set, auto?: boolean, noFilter?: boolean): void { + triggerSuggest(onlyFrom?: Set, auto?: boolean, noFilter?: boolean, noSelect?: boolean): void { if (this.editor.hasModel()) { - this.model.trigger({ auto: auto ?? false, shy: false }, false, onlyFrom, undefined, noFilter); + this.model.trigger({ auto: auto ?? false, shy: false, noSelect: noSelect ?? false }, false, onlyFrom, undefined, noFilter); this.editor.revealPosition(this.editor.getPosition(), ScrollType.Smooth); this.editor.focus(); } @@ -565,7 +568,7 @@ export class SuggestController implements IEditorContribution { }, undefined, listener); }); - this.model.trigger({ auto: false, shy: true }); + this.model.trigger({ auto: false, shy: true, noSelect: false }); this.editor.revealPosition(positionNow, ScrollType.Smooth); this.editor.focus(); } @@ -706,15 +709,19 @@ export class TriggerSuggestAction extends EditorAction { return; } - type TriggerArgs = { auto: boolean }; + type TriggerArgs = { auto: boolean; noSelection: boolean }; let auto: boolean | undefined; + let noSelect: boolean | undefined; if (args && typeof args === 'object') { if ((args).auto === true) { auto = true; } + if ((args).noSelection === true) { + noSelect = true; + } } - controller.triggerSuggest(undefined, auto); + controller.triggerSuggest(undefined, auto, undefined, noSelect); } } @@ -728,7 +735,7 @@ const SuggestCommand = EditorCommand.bindToContribution(Sugge registerEditorCommand(new SuggestCommand({ id: 'acceptSelectedSuggestion', - precondition: SuggestContext.Visible, + precondition: ContextKeyExpr.and(SuggestContext.Visible, SuggestContext.HasFocusedSuggestion), handler(x) { x.acceptSelectedSuggestion(true, false); }, @@ -766,7 +773,7 @@ registerEditorCommand(new SuggestCommand({ registerEditorCommand(new SuggestCommand({ id: 'acceptAlternativeSelectedSuggestion', - precondition: ContextKeyExpr.and(SuggestContext.Visible, EditorContextKeys.textInputFocus), + precondition: ContextKeyExpr.and(SuggestContext.Visible, EditorContextKeys.textInputFocus, SuggestContext.HasFocusedSuggestion), kbOpts: { weight: weight, kbExpr: EditorContextKeys.textInputFocus, diff --git a/src/vs/editor/contrib/suggest/browser/suggestModel.ts b/src/vs/editor/contrib/suggest/browser/suggestModel.ts index 62f7bebafe1..7159e6a10ec 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestModel.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestModel.ts @@ -44,11 +44,13 @@ export interface ISuggestEvent { readonly isFrozen: boolean; readonly auto: boolean; readonly shy: boolean; + readonly noSelect: boolean; } export interface SuggestTriggerContext { readonly auto: boolean; readonly shy: boolean; + readonly noSelect: boolean; readonly triggerKind?: CompletionTriggerKind; readonly triggerCharacter?: string; } @@ -82,14 +84,16 @@ export class LineContext { readonly leadingWord: IWordAtPosition; readonly auto: boolean; readonly shy: boolean; + readonly noSelect: boolean; - constructor(model: ITextModel, position: Position, auto: boolean, shy: boolean) { + constructor(model: ITextModel, position: Position, auto: boolean, shy: boolean, noSelect: boolean) { this.leadingLineContent = model.getLineContent(position.lineNumber).substr(0, position.column - 1); this.leadingWord = model.getWordUntilPosition(position); this.lineNumber = position.lineNumber; this.column = position.column; this.auto = auto; this.shy = shy; + this.noSelect = noSelect; } } @@ -279,7 +283,7 @@ export class SuggestModel implements IDisposable { const existing = this._completionModel ? { items: this._completionModel.adopt(supports), clipboardText: this._completionModel.clipboardText } : undefined; - this.trigger({ auto: true, shy: false, triggerCharacter: lastChar }, Boolean(this._completionModel), supports, existing); + this.trigger({ auto: true, shy: false, noSelect: false, triggerCharacter: lastChar }, Boolean(this._completionModel), supports, existing); } }; @@ -314,7 +318,7 @@ export class SuggestModel implements IDisposable { if (!this._editor.hasModel() || !this._languageFeaturesService.completionProvider.has(this._editor.getModel())) { this.cancel(); } else { - this.trigger({ auto: this._state === State.Auto, shy: false }, true); + this.trigger({ auto: this._state === State.Auto, shy: false, noSelect: false }, true); } } } @@ -413,7 +417,7 @@ export class SuggestModel implements IDisposable { } // we made it till here -> trigger now - this.trigger({ auto: true, shy: false }); + this.trigger({ auto: true, shy: false, noSelect: false }); }, this._editor.getOption(EditorOption.quickSuggestionsDelay)); } @@ -433,7 +437,7 @@ export class SuggestModel implements IDisposable { } const model = this._editor.getModel(); const position = this._editor.getPosition(); - const ctx = new LineContext(model, position, this._state === State.Auto, false); + const ctx = new LineContext(model, position, this._state === State.Auto, false, false); this._onNewContext(ctx); }); } @@ -445,7 +449,7 @@ export class SuggestModel implements IDisposable { const model = this._editor.getModel(); const auto = context.auto; - const ctx = new LineContext(model, this._editor.getPosition(), auto, context.shy); + const ctx = new LineContext(model, this._editor.getPosition(), auto, context.shy, context.noSelect); // Cancel previous requests, change state & update UI this.cancel(retrigger); @@ -520,7 +524,7 @@ export class SuggestModel implements IDisposable { items = items.concat(existing.items).sort(cmpFn); } - const ctx = new LineContext(model, this._editor.getPosition(), auto, context.shy); + const ctx = new LineContext(model, this._editor.getPosition(), auto, context.shy, context.noSelect); this._completionModel = new CompletionModel(items, this._context!.column, { leadingLineContent: ctx.leadingLineContent, characterCountDelta: ctx.column - this._context!.column @@ -630,7 +634,7 @@ export class SuggestModel implements IDisposable { if (ctx.column < this._context.column) { // typed -> moved cursor LEFT -> retrigger if still on a word if (ctx.leadingWord.word) { - this.trigger({ auto: this._context.auto, shy: false }, true); + this.trigger({ auto: this._context.auto, shy: false, noSelect: false }, true); } else { this.cancel(); } @@ -652,7 +656,7 @@ export class SuggestModel implements IDisposable { inactiveProvider.delete(provider); } const items = this._completionModel.adopt(new Set()); - this.trigger({ auto: this._context.auto, shy: false }, true, inactiveProvider, { items, clipboardText: this._completionModel.clipboardText }); + this.trigger({ auto: this._context.auto, shy: false, noSelect: false }, true, inactiveProvider, { items, clipboardText: this._completionModel.clipboardText }); return; } @@ -660,7 +664,7 @@ export class SuggestModel implements IDisposable { // typed -> moved cursor RIGHT & incomple model & still on a word -> retrigger const { incomplete } = this._completionModel; const items = this._completionModel.adopt(incomplete); - this.trigger({ auto: this._state === State.Auto, shy: false, triggerKind: CompletionTriggerKind.TriggerForIncompleteCompletions }, true, incomplete, { items, clipboardText: this._completionModel.clipboardText }); + this.trigger({ auto: this._state === State.Auto, shy: false, noSelect: false, triggerKind: CompletionTriggerKind.TriggerForIncompleteCompletions }, true, incomplete, { items, clipboardText: this._completionModel.clipboardText }); } else { // typed -> moved cursor RIGHT -> update UI @@ -676,7 +680,7 @@ export class SuggestModel implements IDisposable { if (LineContext.shouldAutoTrigger(this._editor) && this._context.leadingWord.endColumn < ctx.leadingWord.startColumn) { // retrigger when heading into a new word - this.trigger({ auto: this._context.auto, shy: false }, true); + this.trigger({ auto: this._context.auto, shy: false, noSelect: false }, true); return; } @@ -703,6 +707,7 @@ export class SuggestModel implements IDisposable { completionModel: this._completionModel, auto: this._context.auto, shy: this._context.shy, + noSelect: this._context.noSelect, isFrozen, }); } diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts index 3a03d2da7dd..afdf48a801a 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts @@ -124,6 +124,7 @@ export class SuggestWidget implements IDisposable { private readonly _ctxSuggestWidgetVisible: IContextKey; private readonly _ctxSuggestWidgetDetailsVisible: IContextKey; private readonly _ctxSuggestWidgetMultipleSuggestions: IContextKey; + private readonly _ctxSuggestWidgetHasFocusedSuggestion: IContextKey; private readonly _showTimeout = new TimeoutTimer(); private readonly _disposables = new DisposableStore(); @@ -283,7 +284,7 @@ export class SuggestWidget implements IDisposable { this._ctxSuggestWidgetVisible = SuggestContext.Visible.bindTo(_contextKeyService); this._ctxSuggestWidgetDetailsVisible = SuggestContext.DetailsVisible.bindTo(_contextKeyService); this._ctxSuggestWidgetMultipleSuggestions = SuggestContext.MultipleSuggestions.bindTo(_contextKeyService); - + this._ctxSuggestWidgetHasFocusedSuggestion = SuggestContext.HasFocusedSuggestion.bindTo(_contextKeyService); this._disposables.add(dom.addStandardDisposableListener(this._details.widget.domNode, 'keydown', e => { this._onDetailsKeydown.fire(e); @@ -365,6 +366,7 @@ export class SuggestWidget implements IDisposable { } this.editor.setAriaOptions({ activeDescendant: undefined }); + this._ctxSuggestWidgetHasFocusedSuggestion.set(false); return; } @@ -372,6 +374,7 @@ export class SuggestWidget implements IDisposable { return; } + this._ctxSuggestWidgetHasFocusedSuggestion.set(true); const item = e.elements[0]; const index = e.indexes[0]; @@ -440,6 +443,7 @@ export class SuggestWidget implements IDisposable { this._contentWidget.hide(); this._ctxSuggestWidgetVisible.reset(); this._ctxSuggestWidgetMultipleSuggestions.reset(); + this._ctxSuggestWidgetHasFocusedSuggestion.reset(); this._showTimeout.cancel(); this.element.domNode.classList.remove('visible'); this._list.splice(0, this._list.length); @@ -538,8 +542,10 @@ export class SuggestWidget implements IDisposable { this._focusedItem = undefined; this._list.splice(0, this._list.length, this._completionModel.items); this._setState(isFrozen ? State.Frozen : State.Open); - this._list.reveal(selectionIndex, 0); - this._list.setFocus([selectionIndex]); + if (selectionIndex >= 0) { + this._list.reveal(selectionIndex, 0); + this._list.setFocus([selectionIndex]); + } this._layout(this.element.size); // Reset focus border diff --git a/src/vs/editor/contrib/suggest/test/browser/suggestModel.test.ts b/src/vs/editor/contrib/suggest/test/browser/suggestModel.test.ts index f25e0b22040..0a1b3dda2de 100644 --- a/src/vs/editor/contrib/suggest/test/browser/suggestModel.test.ts +++ b/src/vs/editor/contrib/suggest/test/browser/suggestModel.test.ts @@ -253,7 +253,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { return Promise.all([ assertEvent(model.onDidTrigger, function () { - model.trigger({ auto: true, shy: false }); + model.trigger({ auto: true, shy: false, noSelect: false }); }, function (event) { assert.strictEqual(event.auto, true); @@ -265,13 +265,13 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { }), assertEvent(model.onDidTrigger, function () { - model.trigger({ auto: true, shy: false }); + model.trigger({ auto: true, shy: false, noSelect: false }); }, function (event) { assert.strictEqual(event.auto, true); }), assertEvent(model.onDidTrigger, function () { - model.trigger({ auto: false, shy: false }); + model.trigger({ auto: false, shy: false, noSelect: false }); }, function (event) { assert.strictEqual(event.auto, false); }) @@ -287,12 +287,12 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { return withOracle(model => { return Promise.all([ assertEvent(model.onDidCancel, function () { - model.trigger({ auto: true, shy: false }); + model.trigger({ auto: true, shy: false, noSelect: false }); }, function (event) { assert.strictEqual(event.retrigger, false); }), assertEvent(model.onDidSuggest, function () { - model.trigger({ auto: false, shy: false }); + model.trigger({ auto: false, shy: false, noSelect: false }); }, function (event) { assert.strictEqual(event.auto, false); assert.strictEqual(event.isFrozen, false); @@ -343,7 +343,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { return assertEvent(model.onDidSuggest, () => { // make sure completionModel starts here! - model.trigger({ auto: true, shy: false }); + model.trigger({ auto: true, shy: false, noSelect: false }); }, event => { return assertEvent(model.onDidSuggest, () => { @@ -443,7 +443,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { editor.setPosition({ lineNumber: 1, column: 3 }); return assertEvent(model.onDidSuggest, () => { - model.trigger({ auto: false, shy: false }); + model.trigger({ auto: false, shy: false, noSelect: false }); }, event => { assert.strictEqual(event.auto, false); assert.strictEqual(event.isFrozen, false); @@ -468,7 +468,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { editor.setPosition({ lineNumber: 1, column: 3 }); return assertEvent(model.onDidSuggest, () => { - model.trigger({ auto: false, shy: false }); + model.trigger({ auto: false, shy: false, noSelect: false }); }, event => { assert.strictEqual(event.auto, false); assert.strictEqual(event.isFrozen, false); @@ -505,7 +505,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { editor.setPosition({ lineNumber: 1, column: 4 }); return assertEvent(model.onDidSuggest, () => { - model.trigger({ auto: false, shy: false }); + model.trigger({ auto: false, shy: false, noSelect: false }); }, event => { assert.strictEqual(event.auto, false); assert.strictEqual(event.completionModel.incomplete.size, 1); @@ -542,7 +542,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { editor.setPosition({ lineNumber: 1, column: 4 }); return assertEvent(model.onDidSuggest, () => { - model.trigger({ auto: false, shy: false }); + model.trigger({ auto: false, shy: false, noSelect: false }); }, event => { assert.strictEqual(event.auto, false); assert.strictEqual(event.completionModel.incomplete.size, 1); @@ -701,7 +701,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { await assertEvent(sugget.onDidSuggest, () => { editor.setPosition({ lineNumber: 1, column: 3 }); - sugget.trigger({ auto: false, shy: false }); + sugget.trigger({ auto: false, shy: false, noSelect: false }); }, event => { assert.strictEqual(event.completionModel.items.length, 1); @@ -928,4 +928,19 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { }); }); }); + + test('noSelect-flag makes it from request to suggest event', function () { + + disposables.add(registry.register({ scheme: 'test' }, alwaysSomethingSupport)); + + return withOracle((model, editor) => { + return assertEvent(model.onDidSuggest, () => { + model.trigger({ auto: false, noSelect: true, shy: false }); + }, event => { + assert.strictEqual(event.noSelect, true); + assert.strictEqual(event.auto, false); + assert.strictEqual(event.shy, false); + }); + }); + }); }); -- cgit v1.2.3 From b1eab983e40dfdca90d0f9833b00afe4233c12c3 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 6 Jul 2022 13:41:24 +0200 Subject: remove `forEach` usage in my and some other places (#154252) https://github.com/microsoft/vscode/issues/154195 --- src/vs/editor/browser/config/migrateOptions.ts | 11 ++++--- src/vs/workbench/api/browser/mainThreadDialogs.ts | 9 ++++-- .../contrib/snippets/browser/snippetsFile.ts | 11 +++---- .../services/actions/common/menusExtensionPoint.ts | 35 +++++++++++----------- 4 files changed, 33 insertions(+), 33 deletions(-) (limited to 'src/vs') diff --git a/src/vs/editor/browser/config/migrateOptions.ts b/src/vs/editor/browser/config/migrateOptions.ts index 49d6a503a84..42f1bc526a8 100644 --- a/src/vs/editor/browser/config/migrateOptions.ts +++ b/src/vs/editor/browser/config/migrateOptions.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { forEach } from 'vs/base/common/collections'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; export interface ISettingsReader { @@ -152,14 +151,14 @@ const suggestFilteredTypesMapping: Record = { registerEditorSettingMigration('suggest.filteredTypes', (value, read, write) => { if (value && typeof value === 'object') { - forEach(suggestFilteredTypesMapping, entry => { - const v = value[entry.key]; + for (const entry of Object.entries(suggestFilteredTypesMapping)) { + const v = value[entry[0]]; if (v === false) { - if (typeof read(`suggest.${entry.value}`) === 'undefined') { - write(`suggest.${entry.value}`, false); + if (typeof read(`suggest.${entry[1]}`) === 'undefined') { + write(`suggest.${entry[1]}`, false); } } - }); + } write('suggest.filteredTypes', undefined); } }); diff --git a/src/vs/workbench/api/browser/mainThreadDialogs.ts b/src/vs/workbench/api/browser/mainThreadDialogs.ts index 1f8066b2c0d..e9ca6d75502 100644 --- a/src/vs/workbench/api/browser/mainThreadDialogs.ts +++ b/src/vs/workbench/api/browser/mainThreadDialogs.ts @@ -6,7 +6,6 @@ import { URI } from 'vs/base/common/uri'; import { MainThreadDiaglogsShape, MainContext, MainThreadDialogOpenOptions, MainThreadDialogSaveOptions } from '../common/extHost.protocol'; import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers'; -import { forEach } from 'vs/base/common/collections'; import { IFileDialogService, IOpenDialogOptions, ISaveDialogOptions } from 'vs/platform/dialogs/common/dialogs'; @extHostNamedCustomer(MainContext.MainThreadDialogs) @@ -51,7 +50,9 @@ export class MainThreadDialogs implements MainThreadDiaglogsShape { }; if (options?.filters) { result.filters = []; - forEach(options.filters, entry => result.filters!.push({ name: entry.key, extensions: entry.value })); + for (const [key, value] of Object.entries(options.filters)) { + result.filters!.push({ name: key, extensions: value }); + } } return result; } @@ -64,7 +65,9 @@ export class MainThreadDialogs implements MainThreadDiaglogsShape { }; if (options?.filters) { result.filters = []; - forEach(options.filters, entry => result.filters!.push({ name: entry.key, extensions: entry.value })); + for (const [key, value] of Object.entries(options.filters)) { + result.filters.push({ name: key, extensions: value }); + } } return result; } diff --git a/src/vs/workbench/contrib/snippets/browser/snippetsFile.ts b/src/vs/workbench/contrib/snippets/browser/snippetsFile.ts index eb1497201da..784296b70de 100644 --- a/src/vs/workbench/contrib/snippets/browser/snippetsFile.ts +++ b/src/vs/workbench/contrib/snippets/browser/snippetsFile.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { parse as jsonParse, getNodeType } from 'vs/base/common/json'; -import { forEach } from 'vs/base/common/collections'; import { localize } from 'vs/nls'; import { extname, basename } from 'vs/base/common/path'; import { SnippetParser, Variable, Placeholder, Text } from 'vs/editor/contrib/snippet/browser/snippetParser'; @@ -256,17 +255,15 @@ export class SnippetFile { this._loadPromise = Promise.resolve(this._load()).then(content => { const data = jsonParse(content); if (getNodeType(data) === 'object') { - forEach(data, entry => { - const { key: name, value: scopeOrTemplate } = entry; + for (const [name, scopeOrTemplate] of Object.entries(data)) { if (isJsonSerializedSnippet(scopeOrTemplate)) { this._parseSnippet(name, scopeOrTemplate, this.data); } else { - forEach(scopeOrTemplate, entry => { - const { key: name, value: template } = entry; + for (const [name, template] of Object.entries(scopeOrTemplate)) { this._parseSnippet(name, template, this.data); - }); + } } - }); + } } return this; }); diff --git a/src/vs/workbench/services/actions/common/menusExtensionPoint.ts b/src/vs/workbench/services/actions/common/menusExtensionPoint.ts index c78225da320..e1b8f018998 100644 --- a/src/vs/workbench/services/actions/common/menusExtensionPoint.ts +++ b/src/vs/workbench/services/actions/common/menusExtensionPoint.ts @@ -686,44 +686,45 @@ submenusExtensionPoint.setHandler(extensions => { for (const extension of extensions) { const { value, collector } = extension; - forEach(value, entry => { - if (!schema.isValidSubmenu(entry.value, collector)) { + for (const [, submenuInfo] of Object.entries(value)) { + + if (!schema.isValidSubmenu(submenuInfo, collector)) { return; } - if (!entry.value.id) { - collector.warn(localize('submenuId.invalid.id', "`{0}` is not a valid submenu identifier", entry.value.id)); + if (!submenuInfo.id) { + collector.warn(localize('submenuId.invalid.id', "`{0}` is not a valid submenu identifier", submenuInfo.id)); return; } - if (_submenus.has(entry.value.id)) { - collector.info(localize('submenuId.duplicate.id', "The `{0}` submenu was already previously registered.", entry.value.id)); + if (_submenus.has(submenuInfo.id)) { + collector.info(localize('submenuId.duplicate.id', "The `{0}` submenu was already previously registered.", submenuInfo.id)); return; } - if (!entry.value.label) { - collector.warn(localize('submenuId.invalid.label', "`{0}` is not a valid submenu label", entry.value.label)); + if (!submenuInfo.label) { + collector.warn(localize('submenuId.invalid.label', "`{0}` is not a valid submenu label", submenuInfo.label)); return; } let absoluteIcon: { dark: URI; light?: URI } | ThemeIcon | undefined; - if (entry.value.icon) { - if (typeof entry.value.icon === 'string') { - absoluteIcon = ThemeIcon.fromString(entry.value.icon) || { dark: resources.joinPath(extension.description.extensionLocation, entry.value.icon) }; + if (submenuInfo.icon) { + if (typeof submenuInfo.icon === 'string') { + absoluteIcon = ThemeIcon.fromString(submenuInfo.icon) || { dark: resources.joinPath(extension.description.extensionLocation, submenuInfo.icon) }; } else { absoluteIcon = { - dark: resources.joinPath(extension.description.extensionLocation, entry.value.icon.dark), - light: resources.joinPath(extension.description.extensionLocation, entry.value.icon.light) + dark: resources.joinPath(extension.description.extensionLocation, submenuInfo.icon.dark), + light: resources.joinPath(extension.description.extensionLocation, submenuInfo.icon.light) }; } } const item: IRegisteredSubmenu = { - id: new MenuId(`api:${entry.value.id}`), - label: entry.value.label, + id: new MenuId(`api:${submenuInfo.id}`), + label: submenuInfo.label, icon: absoluteIcon }; - _submenus.set(entry.value.id, item); - }); + _submenus.set(submenuInfo.id, item); + } } }); -- cgit v1.2.3 From 824671d1fbb16300c8bd4940fa49010f54cd7512 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Jul 2022 13:46:39 +0200 Subject: remove CustomUserDataProfile type --- src/vs/platform/userDataProfile/common/userDataProfile.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/userDataProfile/common/userDataProfile.ts b/src/vs/platform/userDataProfile/common/userDataProfile.ts index 375166c4ce5..b800cf8b84c 100644 --- a/src/vs/platform/userDataProfile/common/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/common/userDataProfile.ts @@ -42,8 +42,6 @@ export interface IUserDataProfile { readonly useDefaultFlags?: UseDefaultProfileFlags; } -export type CustomUserDataProfile = IUserDataProfile & { readonly extensionsResource: URI; readonly isDefault: false }; - export function isUserDataProfile(thing: unknown): thing is IUserDataProfile { const candidate = thing as IUserDataProfile | undefined; @@ -101,7 +99,7 @@ export function reviveProfile(profile: UriDto, scheme: string) export const EXTENSIONS_RESOURCE_NAME = 'extensions.json'; -export function toUserDataProfile(name: string, location: URI, useDefaultFlags?: UseDefaultProfileFlags): CustomUserDataProfile { +export function toUserDataProfile(name: string, location: URI, useDefaultFlags?: UseDefaultProfileFlags): IUserDataProfile { return { id: hash(location.path).toString(16), name: name, -- cgit v1.2.3 From 835670ed8f05fc116139bfb3b65f3343b978f945 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Jul 2022 13:49:06 +0200 Subject: fix using extension resource --- .../electron-sandbox/nativeExtensionManagementService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts index 3252281bf30..6282bc77cf8 100644 --- a/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts @@ -68,7 +68,7 @@ export class NativeExtensionManagementService extends ExtensionManagementChannel private async whenProfileChanged(e: DidChangeUserDataProfileEvent): Promise { const previousExtensionsResource = e.previous.extensionsResource ?? joinPath(e.previous.location, EXTENSIONS_RESOURCE_NAME); if (e.preserveData) { - await this.fileService.copy(previousExtensionsResource, e.profile.extensionsResource!); + await this.fileService.copy(previousExtensionsResource, previousExtensionsResource); } else { const oldExtensions = await super.getInstalled(ExtensionType.User, previousExtensionsResource); const newExtensions = await this.getInstalled(ExtensionType.User); -- cgit v1.2.3 From d45ad24af8762cb434a8b5d6094b277efc62e8a3 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 6 Jul 2022 13:55:39 +0200 Subject: remove totally unneeded hack that slipped through... (#154254) --- src/vs/workbench/contrib/bulkEdit/browser/bulkTextEdits.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/bulkEdit/browser/bulkTextEdits.ts b/src/vs/workbench/contrib/bulkEdit/browser/bulkTextEdits.ts index b07897a513a..6906a0b4fb7 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/bulkTextEdits.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/bulkTextEdits.ts @@ -116,7 +116,7 @@ class ModelEditTask implements IDisposable { if (!edit.text) { return edit; } - const text = new SnippetParser().parse(edit.text, false, false).toString(); + const text = new SnippetParser().text(edit.text); return { ...edit, insertAsSnippet: false, text }; } } @@ -233,13 +233,13 @@ export class BulkTextEdits { let makeMinimal = false; if (this._editor?.getModel()?.uri.toString() === ref.object.textEditorModel.uri.toString()) { task = new EditorEditTask(ref, this._editor); - makeMinimal = true && false; // todo@jrieken HACK + makeMinimal = true; } else { task = new ModelEditTask(ref); } for (const edit of value) { - if (makeMinimal) { + if (makeMinimal && !edit.textEdit.insertAsSnippet) { const newEdits = await this._editorWorker.computeMoreMinimalEdits(edit.resource, [edit.textEdit]); if (!newEdits) { task.addEdit(edit); -- cgit v1.2.3 From 9c6d42b1390c1e56c29f04543eaa57f97140e9f9 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Jul 2022 14:18:20 +0200 Subject: do not compute profiles always --- src/vs/platform/userDataProfile/common/userDataProfile.ts | 3 ++- src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/userDataProfile/common/userDataProfile.ts b/src/vs/platform/userDataProfile/common/userDataProfile.ts index b800cf8b84c..89a181cda49 100644 --- a/src/vs/platform/userDataProfile/common/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/common/userDataProfile.ts @@ -121,7 +121,8 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf readonly profilesHome: URI; get defaultProfile(): IUserDataProfile { return this.profiles[0]; } - get profiles(): IUserDataProfile[] { return [this.createDefaultUserDataProfile(false)]; } + protected _profiles: IUserDataProfile[] = [this.createDefaultUserDataProfile(false)]; + get profiles(): IUserDataProfile[] { return this._profiles; } protected readonly _onDidChangeProfiles = this._register(new Emitter()); readonly onDidChangeProfiles = this._onDidChangeProfiles.event; diff --git a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts index 9d999933058..1666539da3e 100644 --- a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts @@ -16,7 +16,6 @@ export class UserDataProfilesNativeService extends UserDataProfilesService imple private readonly channel: IChannel; - private _profiles: IUserDataProfile[] = []; override get profiles(): IUserDataProfile[] { return this._profiles; } constructor( -- cgit v1.2.3 From 8b475a06d9884ef3ce3f54f236124e4543d6f466 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Wed, 6 Jul 2022 05:35:37 -0700 Subject: Include if client is in unsupported mode & include restricted mode in copy (#154209) --- .../electron-sandbox/issue/issueReporterMain.ts | 5 +++ .../electron-sandbox/issue/issueReporterModel.ts | 12 +++++-- .../issue/testReporterModel.test.ts | 42 +++++++++++++++------- src/vs/platform/issue/common/issue.ts | 1 + .../issue/electron-sandbox/issueService.ts | 13 ++++++- 5 files changed, 58 insertions(+), 15 deletions(-) (limited to 'src/vs') diff --git a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts index 4037fbb3441..046cb3929ff 100644 --- a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts +++ b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts @@ -140,6 +140,7 @@ export class IssueReporter extends Disposable { this.handleExtensionData(configuration.data.enabledExtensions); this.updateExperimentsInfo(configuration.data.experiments); this.updateRestrictedMode(configuration.data.restrictedMode); + this.updateUnsupportedMode(configuration.data.isUnsupported); } render(): void { @@ -1154,6 +1155,10 @@ export class IssueReporter extends Disposable { this.issueReporterModel.update({ restrictedMode }); } + private updateUnsupportedMode(isUnsupported: boolean) { + this.issueReporterModel.update({ isUnsupported }); + } + private updateExperimentsInfo(experimentInfo: string | undefined) { this.issueReporterModel.update({ experimentInfo }); const target = document.querySelector('.block-experiments .block-info'); diff --git a/src/vs/code/electron-sandbox/issue/issueReporterModel.ts b/src/vs/code/electron-sandbox/issue/issueReporterModel.ts index 37a1a40beb0..b0cc736e46e 100644 --- a/src/vs/code/electron-sandbox/issue/issueReporterModel.ts +++ b/src/vs/code/electron-sandbox/issue/issueReporterModel.ts @@ -33,6 +33,7 @@ export interface IssueReporterData { filterResultCount?: number; experimentInfo?: string; restrictedMode?: boolean; + isUnsupported?: boolean; } export class IssueReporterModel { @@ -61,14 +62,21 @@ export class IssueReporterModel { } serialize(): string { + const modes = []; + if (this._data.restrictedMode) { + modes.push('Restricted'); + } + if (this._data.isUnsupported) { + modes.push('Unsupported'); + } return ` -Issue Type: ${this.getIssueTypeTitle()} +Type: ${this.getIssueTypeTitle()} ${this._data.issueDescription} ${this.getExtensionVersion()} VS Code version: ${this._data.versionInfo && this._data.versionInfo.vscodeVersion} OS version: ${this._data.versionInfo && this._data.versionInfo.os} -Restricted Mode: ${this._data.restrictedMode ? 'Yes' : 'No'} +Modes:${modes.length ? ' ' + modes.join(', ') : ''} ${this.getRemoteOSes()} ${this.getInfos()} `; diff --git a/src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts b/src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts index 87bca75fedf..e2280b2338e 100644 --- a/src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts +++ b/src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts @@ -27,13 +27,13 @@ suite('IssueReporter', () => { const issueReporterModel = new IssueReporterModel({}); assert.strictEqual(issueReporterModel.serialize(), ` -Issue Type: Bug +Type: Bug undefined VS Code version: undefined OS version: undefined -Restricted Mode: No +Modes: Extensions: none `); @@ -58,13 +58,13 @@ Extensions: none }); assert.strictEqual(issueReporterModel.serialize(), ` -Issue Type: Bug +Type: Bug undefined VS Code version: undefined OS version: undefined -Restricted Mode: No +Modes:
System Info @@ -102,13 +102,13 @@ Restricted Mode: No }); assert.strictEqual(issueReporterModel.serialize(), ` -Issue Type: Bug +Type: Bug undefined VS Code version: undefined OS version: undefined -Restricted Mode: No +Modes:
System Info @@ -157,13 +157,13 @@ vsins829:30139715 }); assert.strictEqual(issueReporterModel.serialize(), ` -Issue Type: Bug +Type: Bug undefined VS Code version: undefined OS version: undefined -Restricted Mode: No +Modes:
System Info @@ -214,13 +214,13 @@ Restricted Mode: No }); assert.strictEqual(issueReporterModel.serialize(), ` -Issue Type: Bug +Type: Bug undefined VS Code version: undefined OS version: undefined -Restricted Mode: No +Modes: Remote OS version: Linux x64 4.18.0
@@ -263,13 +263,13 @@ Remote OS version: Linux x64 4.18.0 }); assert.strictEqual(issueReporterModel.serialize(), ` -Issue Type: Bug +Type: Bug undefined VS Code version: undefined OS version: undefined -Restricted Mode: No +Modes:
System Info @@ -287,6 +287,24 @@ Restricted Mode: No `); }); + test('should supply mode if applicable', () => { + const issueReporterModel = new IssueReporterModel({ + isUnsupported: true, + restrictedMode: true + }); + assert.strictEqual(issueReporterModel.serialize(), + ` +Type: Bug + +undefined + +VS Code version: undefined +OS version: undefined +Modes: Restricted, Unsupported + +Extensions: none +`); + }); test('should normalize GitHub urls', () => { [ 'https://github.com/repo', diff --git a/src/vs/platform/issue/common/issue.ts b/src/vs/platform/issue/common/issue.ts index 550c83be0d9..cbc4d251934 100644 --- a/src/vs/platform/issue/common/issue.ts +++ b/src/vs/platform/issue/common/issue.ts @@ -59,6 +59,7 @@ export interface IssueReporterData extends WindowData { extensionId?: string; experiments?: string; restrictedMode: boolean; + isUnsupported: boolean; githubAccessToken: string; readonly issueTitle?: string; readonly issueBody?: string; diff --git a/src/vs/workbench/services/issue/electron-sandbox/issueService.ts b/src/vs/workbench/services/issue/electron-sandbox/issueService.ts index 40f41611139..a72466b917a 100644 --- a/src/vs/workbench/services/issue/electron-sandbox/issueService.ts +++ b/src/vs/workbench/services/issue/electron-sandbox/issueService.ts @@ -20,6 +20,7 @@ import { IWorkbenchAssignmentService } from 'vs/workbench/services/assignment/co import { IAuthenticationService } from 'vs/workbench/services/authentication/common/authentication'; import { registerMainProcessRemoteService } from 'vs/platform/ipc/electron-sandbox/services'; import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust'; +import { IIntegrityService } from 'vs/workbench/services/integrity/common/integrity'; export class WorkbenchIssueService implements IWorkbenchIssueService { declare readonly _serviceBrand: undefined; @@ -33,7 +34,8 @@ export class WorkbenchIssueService implements IWorkbenchIssueService { @IWorkspaceTrustManagementService private readonly workspaceTrustManagementService: IWorkspaceTrustManagementService, @IProductService private readonly productService: IProductService, @IWorkbenchAssignmentService private readonly experimentService: IWorkbenchAssignmentService, - @IAuthenticationService private readonly authenticationService: IAuthenticationService + @IAuthenticationService private readonly authenticationService: IAuthenticationService, + @IIntegrityService private readonly integrityService: IIntegrityService ) { } async openReporter(dataOverrides: Partial = {}): Promise { @@ -82,6 +84,14 @@ export class WorkbenchIssueService implements IWorkbenchIssueService { // Ignore } + // air on the side of caution and have false be the default + let isUnsupported = false; + try { + isUnsupported = !(await this.integrityService.isPure()).isPure; + } catch (e) { + // Ignore + } + const theme = this.themeService.getColorTheme(); const issueReporterData: IssueReporterData = Object.assign({ styles: getIssueReporterStyles(theme), @@ -89,6 +99,7 @@ export class WorkbenchIssueService implements IWorkbenchIssueService { enabledExtensions: extensionData, experiments: experiments?.join('\n'), restrictedMode: !this.workspaceTrustManagementService.isWorkspaceTrusted(), + isUnsupported, githubAccessToken, }, dataOverrides); return this.issueService.openReporter(issueReporterData); -- cgit v1.2.3 From 5e1a19f4d439cd4a0ac23e0169df94a5646aa0a2 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 05:50:54 -0700 Subject: Ensure exact match links are only checked on absolute paths Fixes #153832 --- src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts b/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts index bfc044ba133..0d07ef46dfd 100644 --- a/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts +++ b/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts @@ -218,6 +218,9 @@ export class TerminalSearchLinkOpener implements ITerminalLinkOpener { private async _tryOpenExactLink(text: string, link: ITerminalSimpleLink): Promise { const sanitizedLink = text.replace(/:\d+(:\d+)?$/, ''); + if (!osPathModule(this._os).isAbsolute(sanitizedLink)) { + return false; + } try { const result = await this._getExactMatch(sanitizedLink); if (result) { -- cgit v1.2.3 From 6df57ad27f21eae9aedb2316c96cb7c07632f1cb Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 06:02:39 -0700 Subject: Fix test and only avoid exact match when a separator does not exist --- .../terminal/browser/links/terminalLinkOpeners.ts | 8 +++- .../test/browser/links/terminalLinkOpeners.test.ts | 51 +++++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts b/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts index 0d07ef46dfd..fda9a67bd29 100644 --- a/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts +++ b/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts @@ -218,7 +218,13 @@ export class TerminalSearchLinkOpener implements ITerminalLinkOpener { private async _tryOpenExactLink(text: string, link: ITerminalSimpleLink): Promise { const sanitizedLink = text.replace(/:\d+(:\d+)?$/, ''); - if (!osPathModule(this._os).isAbsolute(sanitizedLink)) { + // For only file links disallow exact link matching, for example searching for `foo.txt` + // when no cwd information is available should search when only the initial cwd is available + // as it's ambiguous if there are multiple matches. + // + // However, for `src/foo.txt`, if there's an exact match for `src/foo.txt` in any folder we + // want to take it, even if there are partial matches like `src2/foo.txt` available. + if (!sanitizedLink.match(/[\\/]/)) { return false; } try { diff --git a/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkOpeners.test.ts b/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkOpeners.test.ts index dcbdef59e2c..e7eea1e62fc 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkOpeners.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkOpeners.test.ts @@ -97,10 +97,21 @@ suite('Workbench - TerminalLinkOpeners', () => { capabilities.add(TerminalCapability.CommandDetection, commandDetection); }); - test('should open single exact match against cwd when searching if it exists', async () => { + test('should open single exact match against cwd when searching if it exists when command detection cwd is available', async () => { localFileOpener = instantiationService.createInstance(TerminalLocalFileLinkOpener, OperatingSystem.Linux); const localFolderOpener = instantiationService.createInstance(TerminalLocalFolderInWorkspaceLinkOpener); opener = instantiationService.createInstance(TerminalSearchLinkOpener, capabilities, Promise.resolve('/initial/cwd'), localFileOpener, localFolderOpener, OperatingSystem.Linux); + // Set a fake detected command starting as line 0 to establish the cwd + commandDetection.setCommands([{ + command: '', + cwd: '/initial/cwd', + timestamp: 0, + getOutput() { return undefined; }, + marker: { + line: 0 + } as Partial as any, + hasOutput: true + }]); fileService.setFiles([ URI.from({ scheme: Schemas.file, path: '/initial/cwd/foo/bar.txt' }), URI.from({ scheme: Schemas.file, path: '/initial/cwd/foo2/bar.txt' }) @@ -116,6 +127,44 @@ suite('Workbench - TerminalLinkOpeners', () => { }); }); + test('should open single exact match against cwd for paths containing a separator when searching if it exists, even when command detection isn\'t available', async () => { + localFileOpener = instantiationService.createInstance(TerminalLocalFileLinkOpener, OperatingSystem.Linux); + const localFolderOpener = instantiationService.createInstance(TerminalLocalFolderInWorkspaceLinkOpener); + opener = instantiationService.createInstance(TerminalSearchLinkOpener, capabilities, Promise.resolve('/initial/cwd'), localFileOpener, localFolderOpener, OperatingSystem.Linux); + fileService.setFiles([ + URI.from({ scheme: Schemas.file, path: '/initial/cwd/foo/bar.txt' }), + URI.from({ scheme: Schemas.file, path: '/initial/cwd/foo2/bar.txt' }) + ]); + await opener.open({ + text: 'foo/bar.txt', + bufferRange: { start: { x: 1, y: 1 }, end: { x: 8, y: 1 } }, + type: TerminalBuiltinLinkType.Search + }); + deepStrictEqual(activationResult, { + link: 'file:///initial/cwd/foo/bar.txt', + source: 'editor' + }); + }); + + test('should not open single exact match for paths not containing a when command detection isn\'t available', async () => { + localFileOpener = instantiationService.createInstance(TerminalLocalFileLinkOpener, OperatingSystem.Linux); + const localFolderOpener = instantiationService.createInstance(TerminalLocalFolderInWorkspaceLinkOpener); + opener = instantiationService.createInstance(TerminalSearchLinkOpener, capabilities, Promise.resolve('/initial/cwd'), localFileOpener, localFolderOpener, OperatingSystem.Linux); + fileService.setFiles([ + URI.from({ scheme: Schemas.file, path: '/initial/cwd/foo/bar.txt' }), + URI.from({ scheme: Schemas.file, path: '/initial/cwd/foo2/bar.txt' }) + ]); + await opener.open({ + text: 'bar.txt', + bufferRange: { start: { x: 1, y: 1 }, end: { x: 8, y: 1 } }, + type: TerminalBuiltinLinkType.Search + }); + deepStrictEqual(activationResult, { + link: 'bar.txt', + source: 'search' + }); + }); + suite('macOS/Linux', () => { setup(() => { localFileOpener = instantiationService.createInstance(TerminalLocalFileLinkOpener, OperatingSystem.Linux); -- cgit v1.2.3 From 585b6685dda19344ec0304331f294f1c5f9efe24 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Jul 2022 15:08:38 +0200 Subject: remove forEach usage (#154259) * remove forEach usage * remove extra line --- .../common/extensionTipsService.ts | 5 ++-- .../electron-sandbox/extensionTipsService.ts | 6 ++--- .../workbench/api/browser/viewsExtensionPoint.ts | 27 +++++++++++----------- .../extensions/browser/fileBasedRecommendations.ts | 10 ++++---- .../configuration/browser/configurationService.ts | 4 ++-- .../browser/webExtensionsScannerService.ts | 4 ++-- 6 files changed, 27 insertions(+), 29 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/extensionManagement/common/extensionTipsService.ts b/src/vs/platform/extensionManagement/common/extensionTipsService.ts index 4e59c5a3b47..c9c4aaf97dd 100644 --- a/src/vs/platform/extensionManagement/common/extensionTipsService.ts +++ b/src/vs/platform/extensionManagement/common/extensionTipsService.ts @@ -5,7 +5,6 @@ import { isNonEmptyArray } from 'vs/base/common/arrays'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { forEach } from 'vs/base/common/collections'; import { Disposable } from 'vs/base/common/lifecycle'; import { IConfigBasedExtensionTip as IRawConfigBasedExtensionTip } from 'vs/base/common/product'; import { joinPath } from 'vs/base/common/resources'; @@ -31,7 +30,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe ) { super(); if (this.productService.configBasedExtensionTips) { - forEach(this.productService.configBasedExtensionTips, ({ value }) => this.allConfigBasedTips.set(value.configPath, value)); + Object.entries(this.productService.configBasedExtensionTips).forEach(([, value]) => this.allConfigBasedTips.set(value.configPath, value)); } } @@ -60,7 +59,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe try { const content = await this.fileService.readFile(joinPath(folder, configPath)); const recommendationByRemote: Map = new Map(); - forEach(tip.recommendations, ({ key, value }) => { + Object.entries(tip.recommendations).forEach(([key, value]) => { if (isNonEmptyArray(value.remotes)) { for (const remote of value.remotes) { recommendationByRemote.set(remote, { diff --git a/src/vs/platform/extensionManagement/electron-sandbox/extensionTipsService.ts b/src/vs/platform/extensionManagement/electron-sandbox/extensionTipsService.ts index c6e03e0bf5f..fdfb6721b9a 100644 --- a/src/vs/platform/extensionManagement/electron-sandbox/extensionTipsService.ts +++ b/src/vs/platform/extensionManagement/electron-sandbox/extensionTipsService.ts @@ -5,7 +5,7 @@ import { isNonEmptyArray } from 'vs/base/common/arrays'; import { disposableTimeout, timeout } from 'vs/base/common/async'; -import { forEach, IStringDictionary } from 'vs/base/common/collections'; +import { IStringDictionary } from 'vs/base/common/collections'; import { Event } from 'vs/base/common/event'; import { join } from 'vs/base/common/path'; import { isWindows } from 'vs/base/common/platform'; @@ -67,11 +67,11 @@ export class ExtensionTipsService extends BaseExtensionTipsService { ) { super(fileService, productService, requestService, logService); if (productService.exeBasedExtensionTips) { - forEach(productService.exeBasedExtensionTips, ({ key, value: exeBasedExtensionTip }) => { + Object.entries(productService.exeBasedExtensionTips).forEach(([key, exeBasedExtensionTip]) => { const highImportanceRecommendations: { extensionId: string; extensionName: string; isExtensionPack: boolean }[] = []; const mediumImportanceRecommendations: { extensionId: string; extensionName: string; isExtensionPack: boolean }[] = []; const otherRecommendations: { extensionId: string; extensionName: string; isExtensionPack: boolean }[] = []; - forEach(exeBasedExtensionTip.recommendations, ({ key: extensionId, value }) => { + Object.entries(exeBasedExtensionTip.recommendations).forEach(([extensionId, value]) => { if (value.important) { if (exeBasedExtensionTip.important) { highImportanceRecommendations.push({ extensionId, extensionName: value.name, isExtensionPack: !!value.isExtensionPack }); diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index 1932e2ce93d..b94fab104e1 100644 --- a/src/vs/workbench/api/browser/viewsExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsExtensionPoint.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { coalesce } from 'vs/base/common/arrays'; -import { forEach } from 'vs/base/common/collections'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import * as resources from 'vs/base/common/resources'; import { isFalsyOrWhitespace } from 'vs/base/common/strings'; @@ -322,16 +321,16 @@ class ViewsExtensionHandler implements IWorkbenchContribution { let activityBarOrder = CUSTOM_VIEWS_START_ORDER + viewContainersRegistry.all.filter(v => !!v.extensionId && viewContainersRegistry.getViewContainerLocation(v) === ViewContainerLocation.Sidebar).length; let panelOrder = 5 + viewContainersRegistry.all.filter(v => !!v.extensionId && viewContainersRegistry.getViewContainerLocation(v) === ViewContainerLocation.Panel).length + 1; for (const { value, collector, description } of extensionPoints) { - forEach(value, entry => { - if (!this.isValidViewsContainer(entry.value, collector)) { + Object.entries(value).forEach(([key, value]) => { + if (!this.isValidViewsContainer(value, collector)) { return; } - switch (entry.key) { + switch (key) { case 'activitybar': - activityBarOrder = this.registerCustomViewContainers(entry.value, description, activityBarOrder, existingViewContainers, ViewContainerLocation.Sidebar); + activityBarOrder = this.registerCustomViewContainers(value, description, activityBarOrder, existingViewContainers, ViewContainerLocation.Sidebar); break; case 'panel': - panelOrder = this.registerCustomViewContainers(entry.value, description, panelOrder, existingViewContainers, ViewContainerLocation.Panel); + panelOrder = this.registerCustomViewContainers(value, description, panelOrder, existingViewContainers, ViewContainerLocation.Panel); break; } }); @@ -455,22 +454,22 @@ class ViewsExtensionHandler implements IWorkbenchContribution { for (const extension of extensions) { const { value, collector } = extension; - forEach(value, entry => { - if (!this.isValidViewDescriptors(entry.value, collector)) { + Object.entries(value).forEach(([key, value]) => { + if (!this.isValidViewDescriptors(value, collector)) { return; } - if (entry.key === 'remote' && !isProposedApiEnabled(extension.description, 'contribViewsRemote')) { - collector.warn(localize('ViewContainerRequiresProposedAPI', "View container '{0}' requires 'enabledApiProposals: [\"contribViewsRemote\"]' to be added to 'Remote'.", entry.key)); + if (key === 'remote' && !isProposedApiEnabled(extension.description, 'contribViewsRemote')) { + collector.warn(localize('ViewContainerRequiresProposedAPI', "View container '{0}' requires 'enabledApiProposals: [\"contribViewsRemote\"]' to be added to 'Remote'.", key)); return; } - const viewContainer = this.getViewContainer(entry.key); + const viewContainer = this.getViewContainer(key); if (!viewContainer) { - collector.warn(localize('ViewContainerDoesnotExist', "View container '{0}' does not exist and all views registered to it will be added to 'Explorer'.", entry.key)); + collector.warn(localize('ViewContainerDoesnotExist', "View container '{0}' does not exist and all views registered to it will be added to 'Explorer'.", key)); } const container = viewContainer || this.getDefaultViewContainer(); - const viewDescriptors = coalesce(entry.value.map((item, index) => { + const viewDescriptors = coalesce(value.map((item, index) => { // validate if (viewIds.has(item.id)) { collector.error(localize('duplicateView1', "Cannot register multiple views with same id `{0}`", item.id)); @@ -514,7 +513,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution { collapsed: this.showCollapsed(container) || initialVisibility === InitialVisibility.Collapsed, order: order, extensionId: extension.description.identifier, - originalContainerId: entry.key, + originalContainerId: key, group: item.group, remoteAuthority: item.remoteName || (item).remoteAuthority, // TODO@roblou - delete after remote extensions are updated hideByDefault: initialVisibility === InitialVisibility.Hidden, diff --git a/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.ts b/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.ts index d1b91197ff4..57b4387c1c7 100644 --- a/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.ts +++ b/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.ts @@ -14,7 +14,7 @@ import { localize } from 'vs/nls'; import { StorageScope, IStorageService, StorageTarget } from 'vs/platform/storage/common/storage'; import { IProductService } from 'vs/platform/product/common/productService'; import { ImportantExtensionTip } from 'vs/base/common/product'; -import { forEach, IStringDictionary } from 'vs/base/common/collections'; +import { IStringDictionary } from 'vs/base/common/collections'; import { ITextModel } from 'vs/editor/common/model'; import { Schemas } from 'vs/base/common/network'; import { basename, extname } from 'vs/base/common/resources'; @@ -115,10 +115,10 @@ export class FileBasedRecommendations extends ExtensionRecommendations { this.tasExperimentService = tasExperimentService; if (productService.extensionTips) { - forEach(productService.extensionTips, ({ key, value }) => this.extensionTips.set(key.toLowerCase(), value)); + Object.entries(productService.extensionTips).forEach(([key, value]) => this.extensionTips.set(key.toLowerCase(), value)); } if (productService.extensionImportantTips) { - forEach(productService.extensionImportantTips, ({ key, value }) => this.importantExtensionTips.set(key.toLowerCase(), value)); + Object.entries(productService.extensionImportantTips).forEach(([key, value]) => this.importantExtensionTips.set(key.toLowerCase(), value)); } } @@ -153,7 +153,7 @@ export class FileBasedRecommendations extends ExtensionRecommendations { const cachedRecommendations = this.getCachedRecommendations(); const now = Date.now(); // Retire existing recommendations if they are older than a week or are not part of this.productService.extensionTips anymore - forEach(cachedRecommendations, ({ key, value }) => { + Object.entries(cachedRecommendations).forEach(([key, value]) => { const diff = (now - value) / milliSecondsInADay; if (diff <= 7 && allRecommendations.indexOf(key) > -1) { this.fileBasedRecommendations.set(key.toLowerCase(), { recommendedTime: value }); @@ -400,7 +400,7 @@ export class FileBasedRecommendations extends ExtensionRecommendations { storedRecommendations = storedRecommendations.reduce((result, id) => { result[id] = Date.now(); return result; }, >{}); } const result: IStringDictionary = {}; - forEach(storedRecommendations, ({ key, value }) => { + Object.entries(storedRecommendations).forEach(([key, value]) => { if (typeof value === 'number') { result[key.toLowerCase()] = value; } diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index 20b7ad38a9a..10ef3ab6d99 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -35,7 +35,7 @@ import { toErrorMessage } from 'vs/base/common/errorMessage'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust'; import { delta, distinct } from 'vs/base/common/arrays'; -import { forEach, IStringDictionary } from 'vs/base/common/collections'; +import { IStringDictionary } from 'vs/base/common/collections'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IWorkbenchAssignmentService } from 'vs/workbench/services/assignment/common/assignmentService'; import { isUndefined } from 'vs/base/common/types'; @@ -1218,7 +1218,7 @@ class RegisterConfigurationSchemasContribution extends Disposable implements IWo } const result: IStringDictionary = {}; - forEach(properties, ({ key, value }) => { + Object.entries(properties).forEach(([key, value]) => { if (!value.restricted) { result[key] = value; } diff --git a/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts b/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts index faf1645bb6d..fb5c4babf4a 100644 --- a/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts +++ b/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts @@ -39,7 +39,7 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag import { IProductService } from 'vs/platform/product/common/productService'; import { validateExtensionManifest } from 'vs/platform/extensions/common/extensionValidator'; import Severity from 'vs/base/common/severity'; -import { IStringDictionary, forEach } from 'vs/base/common/collections'; +import { IStringDictionary } from 'vs/base/common/collections'; type GalleryExtensionInfo = { readonly id: string; preRelease?: boolean; migrateStorageFrom?: string }; type ExtensionInfo = { readonly id: string; preRelease: boolean }; @@ -737,7 +737,7 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten let packageNLSUris: Map | undefined; if (e.packageNLSUris) { packageNLSUris = new Map(); - forEach(e.packageNLSUris, (entry) => packageNLSUris!.set(entry.key, URI.revive(entry.value))); + Object.entries(e.packageNLSUris).forEach(([key, value]) => packageNLSUris!.set(key, URI.revive(value))); } webExtensions.push({ -- cgit v1.2.3 From 12710c6cfe64785140be33880c1be86290ede0ea Mon Sep 17 00:00:00 2001 From: Leonardo Montini Date: Wed, 6 Jul 2022 15:34:01 +0200 Subject: Properly display the warning message --- src/vs/platform/instantiation/common/instantiationService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/platform/instantiation/common/instantiationService.ts b/src/vs/platform/instantiation/common/instantiationService.ts index b4253b7765c..1f6bba77e24 100644 --- a/src/vs/platform/instantiation/common/instantiationService.ts +++ b/src/vs/platform/instantiation/common/instantiationService.ts @@ -258,7 +258,7 @@ export class InstantiationService implements IInstantiationService { private _throwIfStrict(msg: string, printWarning: boolean): void { if (printWarning) { - console.warn(printWarning); + console.warn(msg); } if (this._strict) { throw new Error(msg); -- cgit v1.2.3 From d89ea128eca64497fe46bfb36891a8b421f31c30 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 06:39:41 -0700 Subject: Fix remote Windows terminal link URI Fixes #154265 Fixes #144534 --- .../terminal/browser/links/terminalLinkOpeners.ts | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts b/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts index bfc044ba133..52951ddd36c 100644 --- a/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts +++ b/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts @@ -189,9 +189,23 @@ export class TerminalSearchLinkOpener implements ITerminalLinkOpener { // Try open as an absolute link let resourceMatch: IResourceMatch | undefined; if (absolutePath) { - const slashNormalizedPath = this._os === OperatingSystem.Windows ? absolutePath.replace(/\\/g, '/') : absolutePath; - const scheme = this._workbenchEnvironmentService.remoteAuthority ? Schemas.vscodeRemote : Schemas.file; - const uri = URI.from({ scheme, path: slashNormalizedPath }); + let normalizedAbsolutePath: string = absolutePath; + if (this._os === OperatingSystem.Windows) { + normalizedAbsolutePath = absolutePath.replace(/\\/g, '/'); + if (normalizedAbsolutePath.match(/[a-z]:/i)) { + normalizedAbsolutePath = `/${normalizedAbsolutePath}`; + } + } + let uri: URI; + if (this._workbenchEnvironmentService.remoteAuthority) { + uri = URI.from({ + scheme: Schemas.vscodeRemote, + authority: this._workbenchEnvironmentService.remoteAuthority, + path: normalizedAbsolutePath + }); + } else { + uri = URI.file(normalizedAbsolutePath); + } try { const fileStat = await this._fileService.stat(uri); resourceMatch = { uri, isDirectory: fileStat.isDirectory }; -- cgit v1.2.3 From 94e4ee8e4902b332aa4290adfdb806a8414b6065 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 07:05:27 -0700 Subject: Prevent unicode11 addon from loading in unit tests It's not clear what caused the flake in #153757 but this should fix the suspicious unicode warning. We can reinvestigate if it happens again after this fix. Fixes #153757 --- .../workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts index a35b293a2a9..99bc8e0b095 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts @@ -80,7 +80,7 @@ const defaultTerminalConfig: Partial = { scrollback: 1000, fastScrollSensitivity: 2, mouseWheelScrollSensitivity: 1, - unicodeVersion: '11' + unicodeVersion: '6' }; suite('XtermTerminal', () => { -- cgit v1.2.3 From 2e0e882ac5997526583fd4e9e204ee77bdd534d8 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 07:37:31 -0700 Subject: Improve comment --- .../contrib/terminal/browser/links/terminalLinkOpeners.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts b/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts index fda9a67bd29..3041efab208 100644 --- a/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts +++ b/src/vs/workbench/contrib/terminal/browser/links/terminalLinkOpeners.ts @@ -218,12 +218,13 @@ export class TerminalSearchLinkOpener implements ITerminalLinkOpener { private async _tryOpenExactLink(text: string, link: ITerminalSimpleLink): Promise { const sanitizedLink = text.replace(/:\d+(:\d+)?$/, ''); - // For only file links disallow exact link matching, for example searching for `foo.txt` - // when no cwd information is available should search when only the initial cwd is available - // as it's ambiguous if there are multiple matches. + // For links made up of only a file name (no folder), disallow exact link matching. For + // example searching for `foo.txt` when there is no cwd information available (ie. only the + // initial cwd) should NOT search as it's ambiguous if there are multiple matches. // - // However, for `src/foo.txt`, if there's an exact match for `src/foo.txt` in any folder we - // want to take it, even if there are partial matches like `src2/foo.txt` available. + // However, for a link like `src/foo.txt`, if there's an exact match for `src/foo.txt` in + // any folder we want to take it, even if there are partial matches like `src2/foo.txt` + // available. if (!sanitizedLink.match(/[\\/]/)) { return false; } -- cgit v1.2.3 From 1aaff9ef3d1f779e0ff2322c1d5b4c4a03f6d8cb Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 6 Jul 2022 17:10:43 +0200 Subject: stub `activationEventIsDone` function, (#154276) fixes https://github.com/microsoft/vscode/issues/154268 --- src/vs/workbench/api/test/browser/extHostApiCommands.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts b/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts index b3fd49e72b2..2ceac7fde44 100644 --- a/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts +++ b/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts @@ -100,7 +100,9 @@ suite('ExtHostLanguageFeatureCommands', function () { override async activateByEvent() { } - + override activationEventIsDone(activationEvent: string): boolean { + return true; + } }); services.set(ICommandService, new SyncDescriptor(class extends mock() { -- cgit v1.2.3 From f9f353c90becae9610fc28f5b47078ce859eaa00 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 6 Jul 2022 08:53:12 -0700 Subject: support vscode.dev link generation in notebook editor (#154183) * support vscode.dev link generation in notebook editor * Update comments. --- .../workbench/contrib/notebook/browser/controller/coreActions.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/notebook/browser/controller/coreActions.ts b/src/vs/workbench/contrib/notebook/browser/controller/coreActions.ts index f7b01782aa0..9a42a89b378 100644 --- a/src/vs/workbench/contrib/notebook/browser/controller/coreActions.ts +++ b/src/vs/workbench/contrib/notebook/browser/controller/coreActions.ts @@ -42,7 +42,8 @@ export const enum CellToolbarOrder { export const enum CellOverflowToolbarGroups { Copy = '1_copy', Insert = '2_insert', - Edit = '3_edit' + Edit = '3_edit', + Share = '4_share' } export interface INotebookActionContext { @@ -427,3 +428,9 @@ MenuRegistry.appendMenuItem(MenuId.EditorContext, { group: CellOverflowToolbarGroups.Insert, when: NOTEBOOK_EDITOR_FOCUSED }); + +MenuRegistry.appendMenuItem(MenuId.NotebookCellTitle, { + title: localize('miShare', "Share"), + submenu: MenuId.EditorContextShare, + group: CellOverflowToolbarGroups.Share +}); -- cgit v1.2.3 From 0df86c37b602d08bab3e8def45dd445d36f55fc2 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 6 Jul 2022 11:54:37 -0400 Subject: add `hide` property to configure which tasks appear in the `Tasks: run task` quickpick (#154166) --- src/vs/workbench/api/browser/mainThreadTask.ts | 7 ++++--- src/vs/workbench/api/common/shared/tasks.ts | 1 + .../contrib/tasks/browser/abstractTaskService.ts | 2 +- .../contrib/tasks/browser/taskQuickPick.ts | 15 ++++++++++----- .../contrib/tasks/browser/terminalTaskSystem.ts | 22 ++++++++++++++++------ .../contrib/tasks/common/jsonSchema_v2.ts | 9 +++++++++ .../contrib/tasks/common/taskConfiguration.ts | 17 ++++++++++++----- src/vs/workbench/contrib/tasks/common/tasks.ts | 11 +++++++++++ 8 files changed, 64 insertions(+), 20 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/api/browser/mainThreadTask.ts b/src/vs/workbench/api/browser/mainThreadTask.ts index 69e679cc5b4..d6193015b85 100644 --- a/src/vs/workbench/api/browser/mainThreadTask.ts +++ b/src/vs/workbench/api/browser/mainThreadTask.ts @@ -342,7 +342,7 @@ namespace TaskDTO { return result; } - export function to(task: ITaskDTO | undefined, workspace: IWorkspaceContextService, executeOnly: boolean, icon?: { id?: string; color?: string }): ContributedTask | undefined { + export function to(task: ITaskDTO | undefined, workspace: IWorkspaceContextService, executeOnly: boolean, icon?: { id?: string; color?: string }, hide?: boolean): ContributedTask | undefined { if (!task || (typeof task.name !== 'string')) { return undefined; } @@ -383,7 +383,8 @@ namespace TaskDTO { isBackground: !!task.isBackground, problemMatchers: task.problemMatchers.slice(), detail: task.detail, - icon + icon, + hide } ); return result; @@ -492,7 +493,7 @@ export class MainThreadTask implements MainThreadTaskShape { dto.name = ((dto.name === undefined) ? '' : dto.name); // Using an empty name causes the name to default to the one given by the provider. return Promise.resolve(this._proxy.$resolveTask(handle, dto)).then(resolvedTask => { if (resolvedTask) { - return TaskDTO.to(resolvedTask, this._workspaceContextServer, true, task.configurationProperties.icon); + return TaskDTO.to(resolvedTask, this._workspaceContextServer, true, task.configurationProperties.icon, task.configurationProperties.hide); } return undefined; diff --git a/src/vs/workbench/api/common/shared/tasks.ts b/src/vs/workbench/api/common/shared/tasks.ts index f7f206f0649..6f0445ab393 100644 --- a/src/vs/workbench/api/common/shared/tasks.ts +++ b/src/vs/workbench/api/common/shared/tasks.ts @@ -78,6 +78,7 @@ export interface ITaskSourceDTO { scope?: number | UriComponents; color?: string; icon?: string; + hide?: boolean; } export interface ITaskHandleDTO { diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 9ef8982eebe..da7e0dccf58 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -1588,7 +1588,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer { identifier: id, dependsOn: extensionTasks.map((extensionTask) => { return { uri: extensionTask.getWorkspaceFolder()!.uri, task: extensionTask._id }; }), - name: id, + name: id } ); return { task, resolver }; diff --git a/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts b/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts index 77dc6f60769..a2cc123e381 100644 --- a/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts +++ b/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts @@ -24,7 +24,6 @@ import { TaskQuickPickEntryType } from 'vs/workbench/contrib/tasks/browser/abstr export const QUICKOPEN_DETAIL_CONFIG = 'task.quickOpen.detail'; export const QUICKOPEN_SKIP_CONFIG = 'task.quickOpen.skip'; - export function isWorkspaceFolder(folder: IWorkspace | IWorkspaceFolder): folder is IWorkspaceFolder { return 'uri' in folder; } @@ -108,7 +107,9 @@ export class TaskQuickPick extends Disposable { groupLabel: string, extraButtons: IQuickInputButton[] = []) { entries.push({ type: 'separator', label: groupLabel }); tasks.forEach(task => { - entries.push(this._createTaskEntry(task, extraButtons)); + if (!task.configurationProperties.hide) { + entries.push(this._createTaskEntry(task, extraButtons)); + } }); } @@ -304,7 +305,7 @@ export class TaskQuickPick extends Disposable { private async _doPickerSecondLevel(picker: IQuickPick, type: string) { picker.busy = true; if (type === SHOW_ALL) { - const items = (await this._taskService.tasks()).sort((a, b) => this._sorter.compare(a, b)).map(task => this._createTaskEntry(task)); + const items = (await this._taskService.tasks()).filter(t => !t.configurationProperties.hide).sort((a, b) => this._sorter.compare(a, b)).map(task => this._createTaskEntry(task)); items.push(...TaskQuickPick.allSettingEntries(this._configurationService)); picker.items = items; } else { @@ -353,9 +354,13 @@ export class TaskQuickPick extends Disposable { private async _getEntriesForProvider(type: string): Promise[]> { const tasks = (await this._taskService.tasks({ type })).sort((a, b) => this._sorter.compare(a, b)); - let taskQuickPickEntries: QuickPickInput[]; + let taskQuickPickEntries: QuickPickInput[] = []; if (tasks.length > 0) { - taskQuickPickEntries = tasks.map(task => this._createTaskEntry(task)); + for (const task of tasks) { + if (!task.configurationProperties.hide) { + taskQuickPickEntries.push(this._createTaskEntry(task)); + } + } taskQuickPickEntries.push({ type: 'separator' }, { diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index d1dd693f370..0beaded25b4 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -516,12 +516,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { for (const dependency of task.configurationProperties.dependsOn) { const dependencyTask = await resolver.resolve(dependency.uri, dependency.task!); if (dependencyTask) { - if (dependencyTask.configurationProperties.icon) { - dependencyTask.configurationProperties.icon.id ||= task.configurationProperties.icon?.id; - dependencyTask.configurationProperties.icon.color ||= task.configurationProperties.icon?.color; - } else { - dependencyTask.configurationProperties.icon = task.configurationProperties.icon; - } + this._adoptConfigurationForDependencyTask(dependencyTask, task); const key = dependencyTask.getMapKey(); let promise = this._activeTasks[key] ? this._getDependencyPromise(this._activeTasks[key]) : undefined; if (!promise) { @@ -590,6 +585,21 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { }); } + private _adoptConfigurationForDependencyTask(dependencyTask: Task, task: Task): void { + if (dependencyTask.configurationProperties.icon) { + dependencyTask.configurationProperties.icon.id ||= task.configurationProperties.icon?.id; + dependencyTask.configurationProperties.icon.color ||= task.configurationProperties.icon?.color; + } else { + dependencyTask.configurationProperties.icon = task.configurationProperties.icon; + } + + if (dependencyTask.configurationProperties.hide) { + dependencyTask.configurationProperties.hide ||= task.configurationProperties.hide; + } else { + dependencyTask.configurationProperties.hide = task.configurationProperties.hide; + } + } + private async _getDependencyPromise(task: IActiveTerminalData): Promise { if (!task.task.configurationProperties.isBackground) { return task.promise; diff --git a/src/vs/workbench/contrib/tasks/common/jsonSchema_v2.ts b/src/vs/workbench/contrib/tasks/common/jsonSchema_v2.ts index 077bd89a60e..fa67f8ecf65 100644 --- a/src/vs/workbench/contrib/tasks/common/jsonSchema_v2.ts +++ b/src/vs/workbench/contrib/tasks/common/jsonSchema_v2.ts @@ -45,6 +45,13 @@ const shellCommand: IJSONSchema = { deprecationMessage: nls.localize('JsonSchema.tasks.isShellCommand.deprecated', 'The property isShellCommand is deprecated. Use the type property of the task and the shell property in the options instead. See also the 1.14 release notes.') }; + +const hide: IJSONSchema = { + type: 'boolean', + description: nls.localize('JsonSchema.hide', 'Hide this task from the run task quick pick'), + default: true +}; + const taskIdentifier: IJSONSchema = { type: 'object', additionalProperties: true, @@ -407,6 +414,7 @@ const taskConfiguration: IJSONSchema = { }, presentation: Objects.deepClone(presentation), icon: Objects.deepClone(icon), + hide: Objects.deepClone(hide), options: options, problemMatcher: { $ref: '#/definitions/problemMatcherType', @@ -479,6 +487,7 @@ taskDescriptionProperties.command = Objects.deepClone(command); taskDescriptionProperties.args = Objects.deepClone(args); taskDescriptionProperties.isShellCommand = Objects.deepClone(shellCommand); taskDescriptionProperties.dependsOn = dependsOn; +taskDescriptionProperties.hide = Objects.deepClone(hide); taskDescriptionProperties.dependsOrder = dependsOrder; taskDescriptionProperties.identifier = Objects.deepClone(identifier); taskDescriptionProperties.type = Objects.deepClone(taskType); diff --git a/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts b/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts index c5d4058bcb0..0bb00f57620 100644 --- a/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts +++ b/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts @@ -362,6 +362,11 @@ export interface IConfigurationProperties { * The icon's color in the terminal tabs list */ color?: string; + + /** + * Do not show this task in the run task quickpick + */ + hide?: boolean; } export interface ICustomTask extends ICommandProperties, IConfigurationProperties { @@ -1322,7 +1327,8 @@ namespace ConfigurationProperties { { property: 'presentation', type: CommandConfiguration.PresentationOptions }, { property: 'problemMatchers' }, { property: 'options' }, - { property: 'icon' } + { property: 'icon' }, + { property: 'hide' } ]; export function from(this: void, external: IConfigurationProperties & { [key: string]: any }, context: IParseContext, @@ -1350,7 +1356,7 @@ namespace ConfigurationProperties { result.identifier = external.identifier; } result.icon = external.icon; - + result.hide = external.hide; if (external.isBackground !== undefined) { result.isBackground = !!external.isBackground; } @@ -1483,7 +1489,7 @@ namespace ConfiguringTask { type, taskIdentifier, RunOptions.fromConfiguration(external.runOptions), - {} + { hide: external.hide } ); const configuration = ConfigurationProperties.from(external, context, true, source, typeDeclaration.properties); result.addTaskLoadMessages(configuration.errors); @@ -1635,7 +1641,8 @@ namespace CustomTask { { name: configuredProps.configurationProperties.name || contributedTask.configurationProperties.name, identifier: configuredProps.configurationProperties.identifier || contributedTask.configurationProperties.identifier, - icon: configuredProps.configurationProperties.icon + icon: configuredProps.configurationProperties.icon, + hide: configuredProps.configurationProperties.hide }, ); @@ -2119,7 +2126,7 @@ class ConfigurationParser { identifier: name, group: Tasks.TaskGroup.Build, isBackground: isBackground, - problemMatchers: matchers, + problemMatchers: matchers } ); const taskGroupKind = GroupKind.from(fileConfig.group); diff --git a/src/vs/workbench/contrib/tasks/common/tasks.ts b/src/vs/workbench/contrib/tasks/common/tasks.ts index 1b52c33d02a..f4956cc9aef 100644 --- a/src/vs/workbench/contrib/tasks/common/tasks.ts +++ b/src/vs/workbench/contrib/tasks/common/tasks.ts @@ -549,6 +549,11 @@ export interface IConfigurationProperties { * The icon for this task in the terminal tabs list */ icon?: { id?: string; color?: string }; + + /** + * Do not show this task in the run task quickpick + */ + hide?: boolean; } export enum RunOnOptions { @@ -914,6 +919,11 @@ export class ContributedTask extends CommonTask { */ icon: { id?: string; color?: string } | undefined; + /** + * Don't show the task in the run task quickpick + */ + hide?: boolean; + public constructor(id: string, source: IExtensionTaskSource, label: string, type: string | undefined, defines: KeyedTaskIdentifier, command: ICommandConfiguration, hasDefinedMatchers: boolean, runOptions: IRunOptions, configurationProperties: IConfigurationProperties) { @@ -922,6 +932,7 @@ export class ContributedTask extends CommonTask { this.hasDefinedMatchers = hasDefinedMatchers; this.command = command; this.icon = configurationProperties.icon; + this.hide = configurationProperties.hide; } public override clone(): ContributedTask { -- cgit v1.2.3 From f413297170178f16ab218202153b629d59a98be1 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 6 Jul 2022 18:33:04 +0200 Subject: joh/plastic fowl (#154275) * * derive workspace dto with util * be strict when defining reference version ids (must be set to a value or undefined) * relax `ResourceNotebookCellEdit` --- src/vs/editor/browser/services/bulkEditService.ts | 64 ++++++++++++++++------ src/vs/editor/common/languages.ts | 14 ++--- .../codeAction/test/browser/codeAction.test.ts | 2 +- src/vs/monaco.d.ts | 16 +++--- .../workbench/api/browser/mainThreadBulkEdits.ts | 31 +++++------ src/vs/workbench/api/common/extHost.protocol.ts | 47 +++------------- .../api/common/extHostDocumentSaveParticipant.ts | 8 +-- .../workbench/api/common/extHostTypeConverters.ts | 43 +++++++-------- .../api/test/browser/extHostBulkEdits.test.ts | 9 +-- .../browser/extHostDocumentSaveParticipant.test.ts | 6 +- .../api/test/browser/mainThreadEditors.test.ts | 23 ++++---- .../contrib/bulkEdit/browser/bulkCellEdits.ts | 26 +++++++-- .../browser/viewModel/notebookViewModelImpl.ts | 7 ++- .../contrib/notebook/common/notebookCommon.ts | 10 +++- 14 files changed, 159 insertions(+), 147 deletions(-) (limited to 'src/vs') diff --git a/src/vs/editor/browser/services/bulkEditService.ts b/src/vs/editor/browser/services/bulkEditService.ts index 1fa168aedb1..1ec6fde3bfb 100644 --- a/src/vs/editor/browser/services/bulkEditService.ts +++ b/src/vs/editor/browser/services/bulkEditService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { TextEdit, WorkspaceEdit, WorkspaceEditMetadata, WorkspaceFileEdit, WorkspaceFileEditOptions, WorkspaceTextEdit } from 'vs/editor/common/languages'; +import { TextEdit, WorkspaceEdit, WorkspaceEditMetadata, IWorkspaceFileEdit, WorkspaceFileEditOptions, IWorkspaceTextEdit } from 'vs/editor/common/languages'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress'; import { IDisposable } from 'vs/base/common/lifecycle'; @@ -15,49 +15,77 @@ import { CancellationToken } from 'vs/base/common/cancellation'; export const IBulkEditService = createDecorator('IWorkspaceEditService'); -function isWorkspaceFileEdit(thing: any): thing is WorkspaceFileEdit { - return isObject(thing) && (Boolean((thing).newUri) || Boolean((thing).oldUri)); -} - -function isWorkspaceTextEdit(thing: any): thing is WorkspaceTextEdit { - return isObject(thing) && URI.isUri((thing).resource) && isObject((thing).edit); -} - export class ResourceEdit { protected constructor(readonly metadata?: WorkspaceEditMetadata) { } static convert(edit: WorkspaceEdit): ResourceEdit[] { - return edit.edits.map(edit => { - if (isWorkspaceTextEdit(edit)) { - return new ResourceTextEdit(edit.resource, edit.edit, edit.modelVersionId, edit.metadata); + if (ResourceTextEdit.is(edit)) { + return ResourceTextEdit.lift(edit); } - if (isWorkspaceFileEdit(edit)) { - return new ResourceFileEdit(edit.oldUri, edit.newUri, edit.options, edit.metadata); + + if (ResourceFileEdit.is(edit)) { + return ResourceFileEdit.lift(edit); } throw new Error('Unsupported edit'); }); } } -export class ResourceTextEdit extends ResourceEdit { +export class ResourceTextEdit extends ResourceEdit implements IWorkspaceTextEdit { + + static is(candidate: any): candidate is IWorkspaceTextEdit { + if (candidate instanceof ResourceTextEdit) { + return true; + } + return isObject(candidate) + && URI.isUri((candidate).resource) + && isObject((candidate).textEdit); + } + + static lift(edit: IWorkspaceTextEdit): ResourceTextEdit { + if (edit instanceof ResourceTextEdit) { + return edit; + } else { + return new ResourceTextEdit(edit.resource, edit.textEdit, edit.versionId, edit.metadata); + } + } + constructor( readonly resource: URI, readonly textEdit: TextEdit & { insertAsSnippet?: boolean }, - readonly versionId?: number, + readonly versionId: number | undefined = undefined, metadata?: WorkspaceEditMetadata, ) { super(metadata); } } -export class ResourceFileEdit extends ResourceEdit { +export class ResourceFileEdit extends ResourceEdit implements IWorkspaceFileEdit { + + static is(candidate: any): candidate is IWorkspaceFileEdit { + if (candidate instanceof ResourceFileEdit) { + return true; + } else { + return isObject(candidate) + && (Boolean((candidate).newResource) || Boolean((candidate).oldResource)); + } + } + + static lift(edit: IWorkspaceFileEdit): ResourceFileEdit { + if (edit instanceof ResourceFileEdit) { + return edit; + } else { + return new ResourceFileEdit(edit.oldResource, edit.newResource, edit.options, edit.metadata); + } + } + constructor( readonly oldResource: URI | undefined, readonly newResource: URI | undefined, - readonly options?: WorkspaceFileEditOptions, + readonly options: WorkspaceFileEditOptions = {}, metadata?: WorkspaceEditMetadata ) { super(metadata); diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index 0d97ad7329e..10baf2667c9 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -1412,22 +1412,22 @@ export interface WorkspaceFileEditOptions { maxSize?: number; } -export interface WorkspaceFileEdit { - oldUri?: URI; - newUri?: URI; +export interface IWorkspaceFileEdit { + oldResource?: URI; + newResource?: URI; options?: WorkspaceFileEditOptions; metadata?: WorkspaceEditMetadata; } -export interface WorkspaceTextEdit { +export interface IWorkspaceTextEdit { resource: URI; - edit: TextEdit; - modelVersionId?: number; + textEdit: TextEdit & { insertAsSnippet?: boolean }; + versionId: number | undefined; metadata?: WorkspaceEditMetadata; } export interface WorkspaceEdit { - edits: Array; + edits: Array; } export interface Rejection { diff --git a/src/vs/editor/contrib/codeAction/test/browser/codeAction.test.ts b/src/vs/editor/contrib/codeAction/test/browser/codeAction.test.ts index d1be6b9d645..93005d11387 100644 --- a/src/vs/editor/contrib/codeAction/test/browser/codeAction.test.ts +++ b/src/vs/editor/contrib/codeAction/test/browser/codeAction.test.ts @@ -73,7 +73,7 @@ suite('CodeAction', () => { bcd: { diagnostics: [], edit: new class implements languages.WorkspaceEdit { - edits!: languages.WorkspaceTextEdit[]; + edits!: languages.IWorkspaceTextEdit[]; }, title: 'abc' } diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 713083bfe0c..0ff87c1fdb8 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -7015,22 +7015,24 @@ declare namespace monaco.languages { maxSize?: number; } - export interface WorkspaceFileEdit { - oldUri?: Uri; - newUri?: Uri; + export interface IWorkspaceFileEdit { + oldResource?: Uri; + newResource?: Uri; options?: WorkspaceFileEditOptions; metadata?: WorkspaceEditMetadata; } - export interface WorkspaceTextEdit { + export interface IWorkspaceTextEdit { resource: Uri; - edit: TextEdit; - modelVersionId?: number; + textEdit: TextEdit & { + insertAsSnippet?: boolean; + }; + versionId: number | undefined; metadata?: WorkspaceEditMetadata; } export interface WorkspaceEdit { - edits: Array; + edits: Array; } export interface Rejection { diff --git a/src/vs/workbench/api/browser/mainThreadBulkEdits.ts b/src/vs/workbench/api/browser/mainThreadBulkEdits.ts index e3e5d652a16..b47e47a7286 100644 --- a/src/vs/workbench/api/browser/mainThreadBulkEdits.ts +++ b/src/vs/workbench/api/browser/mainThreadBulkEdits.ts @@ -4,29 +4,28 @@ *--------------------------------------------------------------------------------------------*/ import { IBulkEditService, ResourceEdit, ResourceFileEdit, ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService'; -import { IWorkspaceEditDto, MainThreadBulkEditsShape, MainContext, WorkspaceEditType } from 'vs/workbench/api/common/extHost.protocol'; +import { IWorkspaceEditDto, MainThreadBulkEditsShape, MainContext, reviveWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol'; import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers'; import { ILogService } from 'vs/platform/log/common/log'; -import { revive } from 'vs/base/common/marshalling'; import { ResourceNotebookCellEdit } from 'vs/workbench/contrib/bulkEdit/browser/bulkCellEdits'; -import { NotebookDto } from 'vs/workbench/api/browser/mainThreadNotebookDto'; -export function reviveWorkspaceEditDto2(data: IWorkspaceEditDto | undefined): ResourceEdit[] { - if (!data?.edits) { +export function reviveWorkspaceEditDto2(data: IWorkspaceEditDto): ResourceEdit[] { + const edits = reviveWorkspaceEditDto(data)?.edits; + if (!edits) { return []; } - - const result: ResourceEdit[] = []; - for (const edit of revive(data).edits) { - if (edit._type === WorkspaceEditType.File) { - result.push(new ResourceFileEdit(edit.oldUri, edit.newUri, edit.options, edit.metadata)); - } else if (edit._type === WorkspaceEditType.Text) { - result.push(new ResourceTextEdit(edit.resource, edit.edit, edit.modelVersionId, edit.metadata)); - } else if (edit._type === WorkspaceEditType.Cell) { - result.push(new ResourceNotebookCellEdit(edit.resource, NotebookDto.fromCellEditOperationDto(edit.edit), edit.notebookVersionId, edit.metadata)); + return edits.map(edit => { + if (ResourceTextEdit.is(edit)) { + return ResourceTextEdit.lift(edit); } - } - return result; + if (ResourceFileEdit.is(edit)) { + return ResourceFileEdit.lift(edit); + } + if (ResourceNotebookCellEdit.is(edit)) { + return ResourceNotebookCellEdit.lift(edit); + } + throw new Error('Unsupported edit'); + }); } @extHostNamedCustomer(MainContext.MainThreadBulkEdits) diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index a7b203695df..2d062111195 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1587,27 +1587,6 @@ export interface IWorkspaceEditEntryMetadataDto { iconPath?: { id: string } | UriComponents | { light: UriComponents; dark: UriComponents }; } -export const enum WorkspaceEditType { - File = 1, - Text = 2, - Cell = 3, -} - -export interface IWorkspaceFileEditDto { - _type: WorkspaceEditType.File; - oldUri?: UriComponents; - newUri?: UriComponents; - options?: languages.WorkspaceFileEditOptions; - metadata?: IWorkspaceEditEntryMetadataDto; -} - -export interface IWorkspaceTextEditDto { - _type: WorkspaceEditType.Text; - resource: UriComponents; - edit: languages.TextEdit & { insertAsSnippet?: boolean }; - modelVersionId?: number; - metadata?: IWorkspaceEditEntryMetadataDto; -} export type ICellEditOperationDto = notebookCommon.ICellPartialMetadataEdit @@ -1619,31 +1598,19 @@ export type ICellEditOperationDto = cells: NotebookCellDataDto[]; }; -export interface IWorkspaceCellEditDto { - _type: WorkspaceEditType.Cell; - resource: UriComponents; - notebookVersionId?: number; - metadata?: IWorkspaceEditEntryMetadataDto; - edit: ICellEditOperationDto; -} +export type IWorkspaceCellEditDto = Dto> & { cellEdit: ICellEditOperationDto }; + +export type IWorkspaceFileEditDto = Dto; + +export type IWorkspaceTextEditDto = Dto; export interface IWorkspaceEditDto { edits: Array; } -export function reviveWorkspaceEditDto(data: IWorkspaceEditDto | undefined): languages.WorkspaceEdit { +export function reviveWorkspaceEditDto(data: IWorkspaceEditDto | undefined): languages.WorkspaceEdit | undefined { if (data && data.edits) { - for (const edit of data.edits) { - if (typeof (edit).resource === 'object') { - (edit).resource = URI.revive((edit).resource); - } else { - (edit).newUri = URI.revive((edit).newUri); - (edit).oldUri = URI.revive((edit).oldUri); - } - if (edit.metadata && edit.metadata.iconPath) { - edit.metadata = revive(edit.metadata); - } - } + revive(data); } return data; } diff --git a/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts b/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts index 05f7cb963d6..7a90e5db0f9 100644 --- a/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts +++ b/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts @@ -6,7 +6,7 @@ import { Event } from 'vs/base/common/event'; import { URI, UriComponents } from 'vs/base/common/uri'; import { illegalState } from 'vs/base/common/errors'; -import { ExtHostDocumentSaveParticipantShape, IWorkspaceEditDto, WorkspaceEditType, MainThreadBulkEditsShape } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostDocumentSaveParticipantShape, IWorkspaceEditDto, MainThreadBulkEditsShape } from 'vs/workbench/api/common/extHost.protocol'; import { TextEdit } from 'vs/workbench/api/common/extHostTypes'; import { Range, TextDocumentSaveReason, EndOfLine } from 'vs/workbench/api/common/extHostTypeConverters'; import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; @@ -146,12 +146,12 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic if (Array.isArray(value) && (value).every(e => e instanceof TextEdit)) { for (const { newText, newEol, range } of value) { dto.edits.push({ - _type: WorkspaceEditType.Text, resource: document.uri, - edit: { + versionId: undefined, + textEdit: { range: range && Range.from(range), text: newText, - eol: newEol && EndOfLine.from(newEol) + eol: newEol && EndOfLine.from(newEol), } }); } diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index 9b733dc8951..f7917e317d2 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -589,47 +589,44 @@ export namespace WorkspaceEdit { if (entry._type === types.FileEditType.File) { // file operation - result.edits.push({ - _type: extHostProtocol.WorkspaceEditType.File, - oldUri: entry.from, - newUri: entry.to, + result.edits.push({ + oldResource: entry.from, + newResource: entry.to, options: entry.options, metadata: entry.metadata }); } else if (entry._type === types.FileEditType.Text) { - // text edits - const dto = { - _type: extHostProtocol.WorkspaceEditType.Text, + const edit = { resource: entry.uri, - edit: TextEdit.from(entry.edit), - modelVersionId: !toCreate.has(entry.uri) ? versionInfo?.getTextDocumentVersion(entry.uri) : undefined, + textEdit: TextEdit.from(entry.edit), + versionId: !toCreate.has(entry.uri) ? versionInfo?.getTextDocumentVersion(entry.uri) : undefined, metadata: entry.metadata }; if (allowSnippetTextEdit && entry.edit.newText2 instanceof types.SnippetString) { - dto.edit.insertAsSnippet = true; - dto.edit.text = entry.edit.newText2.value; + edit.textEdit.insertAsSnippet = true; + edit.textEdit.text = entry.edit.newText2.value; } - result.edits.push(dto); + result.edits.push(edit); } else if (entry._type === types.FileEditType.Cell) { - result.edits.push({ - _type: extHostProtocol.WorkspaceEditType.Cell, + // cell edit + result.edits.push({ metadata: entry.metadata, resource: entry.uri, - edit: entry.edit, + cellEdit: entry.edit, notebookMetadata: entry.notebookMetadata, notebookVersionId: versionInfo?.getNotebookDocumentVersion(entry.uri) }); } else if (entry._type === types.FileEditType.CellReplace) { - result.edits.push({ - _type: extHostProtocol.WorkspaceEditType.Cell, + // cell replace + result.edits.push({ metadata: entry.metadata, resource: entry.uri, notebookVersionId: versionInfo?.getNotebookDocumentVersion(entry.uri), - edit: { + cellEdit: { editType: notebooks.CellEditType.Replace, index: entry.index, count: entry.count, @@ -645,16 +642,16 @@ export namespace WorkspaceEdit { export function to(value: extHostProtocol.IWorkspaceEditDto) { const result = new types.WorkspaceEdit(); for (const edit of value.edits) { - if ((edit).edit) { + if ((edit).textEdit) { result.replace( URI.revive((edit).resource), - Range.to((edit).edit.range), - (edit).edit.text + Range.to((edit).textEdit.range), + (edit).textEdit.text ); } else { result.renameFile( - URI.revive((edit).oldUri!), - URI.revive((edit).newUri!), + URI.revive((edit).oldResource!), + URI.revive((edit).newResource!), (edit).options ); } diff --git a/src/vs/workbench/api/test/browser/extHostBulkEdits.test.ts b/src/vs/workbench/api/test/browser/extHostBulkEdits.test.ts index 3b393b35347..906405cd6b7 100644 --- a/src/vs/workbench/api/test/browser/extHostBulkEdits.test.ts +++ b/src/vs/workbench/api/test/browser/extHostBulkEdits.test.ts @@ -4,13 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; -import { MainContext, IWorkspaceEditDto, WorkspaceEditType, MainThreadBulkEditsShape } from 'vs/workbench/api/common/extHost.protocol'; +import { MainContext, IWorkspaceEditDto, MainThreadBulkEditsShape, IWorkspaceTextEditDto } from 'vs/workbench/api/common/extHost.protocol'; import { URI } from 'vs/base/common/uri'; import { mock } from 'vs/base/test/common/mock'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { SingleProxyRPCProtocol, TestRPCProtocol } from 'vs/workbench/api/test/common/testRPCProtocol'; import { NullLogService } from 'vs/platform/log/common/log'; -import { assertType } from 'vs/base/common/types'; import { ExtHostBulkEdits } from 'vs/workbench/api/common/extHostBulkEdits'; import { nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; @@ -50,8 +49,7 @@ suite('ExtHostBulkEdits.applyWorkspaceEdit', () => { await bulkEdits.applyWorkspaceEdit(edit, nullExtensionDescription); assert.strictEqual(workspaceResourceEdits.edits.length, 1); const [first] = workspaceResourceEdits.edits; - assertType(first._type === WorkspaceEditType.Text); - assert.strictEqual(first.modelVersionId, 1337); + assert.strictEqual((first).versionId, 1337); }); test('does not use version id if document is not available', async () => { @@ -60,8 +58,7 @@ suite('ExtHostBulkEdits.applyWorkspaceEdit', () => { await bulkEdits.applyWorkspaceEdit(edit, nullExtensionDescription); assert.strictEqual(workspaceResourceEdits.edits.length, 1); const [first] = workspaceResourceEdits.edits; - assertType(first._type === WorkspaceEditType.Text); - assert.ok(typeof first.modelVersionId === 'undefined'); + assert.ok(typeof (first).versionId === 'undefined'); }); }); diff --git a/src/vs/workbench/api/test/browser/extHostDocumentSaveParticipant.test.ts b/src/vs/workbench/api/test/browser/extHostDocumentSaveParticipant.test.ts index 70e338176d7..c50aabb812f 100644 --- a/src/vs/workbench/api/test/browser/extHostDocumentSaveParticipant.test.ts +++ b/src/vs/workbench/api/test/browser/extHostDocumentSaveParticipant.test.ts @@ -266,8 +266,8 @@ suite('ExtHostDocumentSaveParticipant', () => { sub.dispose(); assert.strictEqual(dto.edits.length, 2); - assert.ok((dto.edits[0]).edit); - assert.ok((dto.edits[1]).edit); + assert.ok((dto.edits[0]).textEdit); + assert.ok((dto.edits[1]).textEdit); }); }); @@ -317,7 +317,7 @@ suite('ExtHostDocumentSaveParticipant', () => { for (const edit of dto.edits) { const uri = URI.revive((edit).resource); - const { text, range } = (edit).edit; + const { text, range } = (edit).textEdit; documents.$acceptModelChanged(uri, { changes: [{ range, diff --git a/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts b/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts index dac02ac748e..859c9c28ee8 100644 --- a/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts +++ b/src/vs/workbench/api/test/browser/mainThreadEditors.test.ts @@ -9,7 +9,7 @@ import { TestConfigurationService } from 'vs/platform/configuration/test/common/ import { ModelService } from 'vs/editor/common/services/modelService'; import { TestCodeEditorService } from 'vs/editor/test/browser/editorTestServices'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { IWorkspaceTextEditDto, WorkspaceEditType } from 'vs/workbench/api/common/extHost.protocol'; +import { IWorkspaceTextEditDto } from 'vs/workbench/api/common/extHost.protocol'; import { mock } from 'vs/base/test/common/mock'; import { Event } from 'vs/base/common/event'; import { URI } from 'vs/base/common/uri'; @@ -197,10 +197,9 @@ suite('MainThreadEditors', () => { const model = modelService.createModel('something', null, resource); const workspaceResourceEdit: IWorkspaceTextEditDto = { - _type: WorkspaceEditType.Text, resource: resource, - modelVersionId: model.getVersionId(), - edit: { + versionId: model.getVersionId(), + textEdit: { text: 'asdfg', range: new Range(1, 1, 1, 1) } @@ -219,19 +218,17 @@ suite('MainThreadEditors', () => { const model = modelService.createModel('something', null, resource); const workspaceResourceEdit1: IWorkspaceTextEditDto = { - _type: WorkspaceEditType.Text, resource: resource, - modelVersionId: model.getVersionId(), - edit: { + versionId: model.getVersionId(), + textEdit: { text: 'asdfg', range: new Range(1, 1, 1, 1) } }; const workspaceResourceEdit2: IWorkspaceTextEditDto = { - _type: WorkspaceEditType.Text, resource: resource, - modelVersionId: model.getVersionId(), - edit: { + versionId: model.getVersionId(), + textEdit: { text: 'asdfg', range: new Range(1, 1, 1, 1) } @@ -251,9 +248,9 @@ suite('MainThreadEditors', () => { test(`applyWorkspaceEdit with only resource edit`, () => { return bulkEdits.$tryApplyWorkspaceEdit({ edits: [ - { _type: WorkspaceEditType.File, oldUri: resource, newUri: resource, options: undefined }, - { _type: WorkspaceEditType.File, oldUri: undefined, newUri: resource, options: undefined }, - { _type: WorkspaceEditType.File, oldUri: resource, newUri: undefined, options: undefined } + { oldResource: resource, newResource: resource, options: undefined }, + { oldResource: undefined, newResource: resource, options: undefined }, + { oldResource: resource, newResource: undefined, options: undefined } ] }).then((result) => { assert.strictEqual(result, true); diff --git a/src/vs/workbench/contrib/bulkEdit/browser/bulkCellEdits.ts b/src/vs/workbench/contrib/bulkEdit/browser/bulkCellEdits.ts index 1f533a82ccc..0e870b7b639 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/bulkCellEdits.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/bulkCellEdits.ts @@ -6,20 +6,36 @@ import { groupBy } from 'vs/base/common/arrays'; import { CancellationToken } from 'vs/base/common/cancellation'; import { compare } from 'vs/base/common/strings'; +import { isObject } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { ResourceEdit } from 'vs/editor/browser/services/bulkEditService'; import { WorkspaceEditMetadata } from 'vs/editor/common/languages'; import { IProgress } from 'vs/platform/progress/common/progress'; import { UndoRedoGroup, UndoRedoSource } from 'vs/platform/undoRedo/common/undoRedo'; -import { ICellEditOperation } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { ICellPartialMetadataEdit, ICellReplaceEdit, IDocumentMetadataEdit, IWorkspaceNotebookCellEdit } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookEditorModelResolverService } from 'vs/workbench/contrib/notebook/common/notebookEditorModelResolverService'; -export class ResourceNotebookCellEdit extends ResourceEdit { +export class ResourceNotebookCellEdit extends ResourceEdit implements IWorkspaceNotebookCellEdit { + + static is(candidate: any): candidate is IWorkspaceNotebookCellEdit { + if (candidate instanceof ResourceNotebookCellEdit) { + return true; + } + return URI.isUri((candidate).resource) + && isObject((candidate).cellEdit); + } + + static lift(edit: IWorkspaceNotebookCellEdit): ResourceNotebookCellEdit { + if (edit instanceof ResourceNotebookCellEdit) { + return edit; + } + return new ResourceNotebookCellEdit(edit.resource, edit.cellEdit, edit.notebookVersionId, edit.metadata); + } constructor( readonly resource: URI, - readonly cellEdit: ICellEditOperation, - readonly versionId?: number, + readonly cellEdit: ICellPartialMetadataEdit | IDocumentMetadataEdit | ICellReplaceEdit, + readonly notebookVersionId: number | undefined = undefined, metadata?: WorkspaceEditMetadata ) { super(metadata); @@ -49,7 +65,7 @@ export class BulkCellEdits { const ref = await this._notebookModelService.resolve(first.resource); // check state - if (typeof first.versionId === 'number' && ref.object.notebook.versionId !== first.versionId) { + if (typeof first.notebookVersionId === 'number' && ref.object.notebook.versionId !== first.notebookVersionId) { ref.dispose(); throw new Error(`Notebook '${first.resource}' has changed in the meantime`); } diff --git a/src/vs/workbench/contrib/notebook/browser/viewModel/notebookViewModelImpl.ts b/src/vs/workbench/contrib/notebook/browser/viewModel/notebookViewModelImpl.ts index 951fbe0e2e2..a024bbe93a6 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewModel/notebookViewModelImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewModel/notebookViewModelImpl.ts @@ -17,7 +17,7 @@ import { FindMatch, IModelDecorationOptions, IModelDeltaDecoration, TrackedRange import { MultiModelEditStackElement, SingleModelEditStackElement } from 'vs/editor/common/model/editStack'; import { IntervalNode, IntervalTree } from 'vs/editor/common/model/intervalTree'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; -import { WorkspaceTextEdit } from 'vs/editor/common/languages'; +import { IWorkspaceTextEdit } from 'vs/editor/common/languages'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { FoldingRegions } from 'vs/editor/contrib/folding/browser/foldingRanges'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -924,14 +924,15 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD return; } - const textEdits: WorkspaceTextEdit[] = []; + const textEdits: IWorkspaceTextEdit[] = []; this._lastNotebookEditResource.push(matches[0].cell.uri); matches.forEach(match => { match.matches.forEach((singleMatch, index) => { if ((singleMatch as OutputFindMatch).index === undefined) { textEdits.push({ - edit: { range: (singleMatch as FindMatch).range, text: texts[index] }, + versionId: undefined, + textEdit: { range: (singleMatch as FindMatch).range, text: texts[index] }, resource: match.cell.uri }); } diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index d0ccff06ccd..a95ecc6fb84 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -17,7 +17,7 @@ import { ISplice } from 'vs/base/common/sequence'; import { URI, UriComponents } from 'vs/base/common/uri'; import { ILineChange } from 'vs/editor/common/diff/diffComputer'; import * as editorCommon from 'vs/editor/common/editorCommon'; -import { Command } from 'vs/editor/common/languages'; +import { Command, WorkspaceEditMetadata } from 'vs/editor/common/languages'; import { IReadonlyTextBuffer } from 'vs/editor/common/model'; import { IAccessibilityInformation } from 'vs/platform/accessibility/common/accessibility'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; @@ -497,6 +497,14 @@ export interface ICellMoveEdit { export type IImmediateCellEditOperation = ICellOutputEditByHandle | ICellPartialMetadataEditByHandle | ICellOutputItemEdit | ICellPartialInternalMetadataEdit | ICellPartialInternalMetadataEditByHandle | ICellPartialMetadataEdit; export type ICellEditOperation = IImmediateCellEditOperation | ICellReplaceEdit | ICellOutputEdit | ICellMetadataEdit | ICellPartialMetadataEdit | ICellPartialInternalMetadataEdit | IDocumentMetadataEdit | ICellMoveEdit | ICellOutputItemEdit | ICellLanguageEdit; + +export interface IWorkspaceNotebookCellEdit { + metadata?: WorkspaceEditMetadata; + resource: URI; + notebookVersionId: number | undefined; + cellEdit: ICellPartialMetadataEdit | IDocumentMetadataEdit | ICellReplaceEdit; +} + export interface NotebookData { readonly cells: ICellDto2[]; readonly metadata: NotebookDocumentMetadata; -- cgit v1.2.3 From 09b0f5b54f483b0c3e0bc5bfd70fa6dec437e13e Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Jul 2022 18:44:13 +0200 Subject: skip application scope settings while copying (#154280) --- .../configuration/browser/configurationService.ts | 24 ++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index 10ef3ab6d99..bba9911a158 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -26,7 +26,7 @@ import { JSONEditingService } from 'vs/workbench/services/configuration/common/j import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema'; import { mark } from 'vs/base/common/performance'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; -import { IFileService } from 'vs/platform/files/common/files'; +import { FileOperationError, FileOperationResult, IFileService } from 'vs/platform/files/common/files'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; @@ -43,6 +43,8 @@ import { localize } from 'vs/nls'; import { DidChangeUserDataProfileEvent, IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/policy'; import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { updateIgnoredSettings } from 'vs/platform/userDataSync/common/settingsMerge'; +import { VSBuffer } from 'vs/base/common/buffer'; function getLocalUserConfigurationScopes(userDataProfile: IUserDataProfile, hasRemote: boolean): ConfigurationScope[] | undefined { return userDataProfile.isDefault @@ -714,7 +716,7 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat e.join((async () => { if (e.preserveData) { await Promise.all([ - this.fileService.copy(e.previous.settingsResource, e.profile.settingsResource), + this.copyProfileSettings(e.previous.settingsResource, e.profile.settingsResource), this.fileService.copy(e.previous.tasksResource, e.profile.tasksResource) ]); } @@ -731,6 +733,24 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat })()); } + private async copyProfileSettings(from: URI, to: URI): Promise { + let fromContent: string | undefined; + try { + fromContent = (await this.fileService.readFile(from)).value.toString(); + } catch (error) { + if ((error).fileOperationResult !== FileOperationResult.FILE_NOT_FOUND) { + throw error; + } + } + if (!fromContent) { + return; + } + const allSettings = Registry.as(Extensions.Configuration).getConfigurationProperties(); + const applicationSettings = Object.keys(allSettings).filter(key => allSettings[key]?.scope === ConfigurationScope.APPLICATION); + const toContent = updateIgnoredSettings(fromContent, '{}', applicationSettings, {}); + await this.fileService.writeFile(to, VSBuffer.fromString(toContent)); + } + private onDefaultConfigurationChanged(configurationModel: ConfigurationModel, properties?: string[]): void { if (this.workspace) { const previousData = this._configuration.toData(); -- cgit v1.2.3 From c133b130bfd88a134e1803d60e6ce5d094af6a03 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 6 Jul 2022 12:45:28 -0400 Subject: remove `forEach` for tasks (#154273) * part of #154195 * Update src/vs/workbench/api/browser/mainThreadTask.ts Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com> * Update src/vs/workbench/api/browser/mainThreadTask.ts Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com> --- src/vs/workbench/api/browser/mainThreadTask.ts | 8 +++++--- .../contrib/tasks/browser/runAutomaticTasks.ts | 17 ++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/api/browser/mainThreadTask.ts b/src/vs/workbench/api/browser/mainThreadTask.ts index d6193015b85..e40b95ad866 100644 --- a/src/vs/workbench/api/browser/mainThreadTask.ts +++ b/src/vs/workbench/api/browser/mainThreadTask.ts @@ -434,7 +434,9 @@ export class MainThreadTask implements MainThreadTaskShape { let resolvedDefinition: ITaskDefinitionDTO = execution.task!.definition; if (execution.task?.execution && CustomExecutionDTO.is(execution.task.execution) && event.resolvedVariables) { const dictionary: IStringDictionary = {}; - Array.from(event.resolvedVariables.entries()).forEach(entry => dictionary[entry[0]] = entry[1]); + for (const [key, value] of event.resolvedVariables.entries()) { + dictionary[key] = value; + } resolvedDefinition = await this._configurationResolverService.resolveAnyAsync(task.getWorkspaceFolder(), execution.task.definition, dictionary); } @@ -450,9 +452,9 @@ export class MainThreadTask implements MainThreadTaskShape { } public dispose(): void { - this._providers.forEach((value) => { + for (const value of this._providers.values()) { value.disposable.dispose(); - }); + } this._providers.clear(); } diff --git a/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts b/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts index 3d91091af90..55d63c00125 100644 --- a/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts +++ b/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts @@ -8,7 +8,6 @@ import * as resources from 'vs/base/common/resources'; import { Disposable } from 'vs/base/common/lifecycle'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { ITaskService, IWorkspaceFolderTaskResult } from 'vs/workbench/contrib/tasks/common/taskService'; -import { forEach } from 'vs/base/common/collections'; import { RunOnOptions, Task, TaskRunSource, TaskSource, TaskSourceKind, TASKS_CATEGORY, WorkspaceFileTaskSource, IWorkspaceTaskSource } from 'vs/workbench/contrib/tasks/common/tasks'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; @@ -106,22 +105,22 @@ export class RunAutomaticTasks extends Disposable implements IWorkbenchContribut }); } if (resultElement.configurations) { - forEach(resultElement.configurations.byIdentifier, (configedTask) => { - if (configedTask.value.runOptions.runOn === RunOnOptions.folderOpen) { + for (const configuredTask of Object.values(resultElement.configurations.byIdentifier)) { + if (configuredTask.runOptions.runOn === RunOnOptions.folderOpen) { tasks.push(new Promise(resolve => { - taskService.getTask(resultElement.workspaceFolder, configedTask.value._id, true).then(task => resolve(task)); + taskService.getTask(resultElement.workspaceFolder, configuredTask._id, true).then(task => resolve(task)); })); - if (configedTask.value._label) { - taskNames.push(configedTask.value._label); + if (configuredTask._label) { + taskNames.push(configuredTask._label); } else { - taskNames.push(configedTask.value.configures.task); + taskNames.push(configuredTask.configures.task); } - const location = RunAutomaticTasks._getTaskSource(configedTask.value._source); + const location = RunAutomaticTasks._getTaskSource(configuredTask._source); if (location) { locations.set(location.fsPath, location); } } - }); + } } }); } -- cgit v1.2.3 From cc0dfc9f0e9d398287123013737516298a360e89 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Jul 2022 18:53:03 +0200 Subject: remove application scoped extensions while copying (#154278) --- .../electron-sandbox/nativeExtensionManagementService.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts index 6282bc77cf8..cdd2bdad7db 100644 --- a/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts @@ -7,7 +7,7 @@ import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { IProfileAwareExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc'; import { URI } from 'vs/base/common/uri'; -import { IGalleryExtension, ILocalExtension, InstallOptions, InstallVSIXOptions, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IGalleryExtension, ILocalExtension, InstallOptions, InstallVSIXOptions, Metadata, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionIdentifier, ExtensionType } from 'vs/platform/extensions/common/extensions'; import { Emitter, Event } from 'vs/base/common/event'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; @@ -17,7 +17,7 @@ import { DisposableStore } from 'vs/base/common/lifecycle'; import { DidChangeUserDataProfileEvent, IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; import { EXTENSIONS_RESOURCE_NAME } from 'vs/platform/userDataProfile/common/userDataProfile'; import { joinPath } from 'vs/base/common/resources'; -import { IFileService } from 'vs/platform/files/common/files'; +import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; export class NativeExtensionManagementService extends ExtensionManagementChannelClient implements IProfileAwareExtensionManagementService { @@ -38,7 +38,7 @@ export class NativeExtensionManagementService extends ExtensionManagementChannel constructor( channel: IChannel, @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, - @IFileService private readonly fileService: IFileService, + @IExtensionsProfileScannerService private readonly extensionsProfileScannerService: IExtensionsProfileScannerService, @IUriIdentityService private readonly uriIdentityService: IUriIdentityService, ) { super(channel); @@ -67,10 +67,13 @@ export class NativeExtensionManagementService extends ExtensionManagementChannel private async whenProfileChanged(e: DidChangeUserDataProfileEvent): Promise { const previousExtensionsResource = e.previous.extensionsResource ?? joinPath(e.previous.location, EXTENSIONS_RESOURCE_NAME); + const oldExtensions = await super.getInstalled(ExtensionType.User, previousExtensionsResource); if (e.preserveData) { - await this.fileService.copy(previousExtensionsResource, previousExtensionsResource); + const extensions: [ILocalExtension, Metadata | undefined][] = await Promise.all(oldExtensions + .filter(e => !e.isApplicationScoped) /* remove application scoped extensions */ + .map(async e => ([e, await this.getMetadata(e)]))); + await this.extensionsProfileScannerService.addExtensionsToProfile(extensions, e.profile.extensionsResource!); } else { - const oldExtensions = await super.getInstalled(ExtensionType.User, previousExtensionsResource); const newExtensions = await this.getInstalled(ExtensionType.User); const { added, removed } = delta(oldExtensions, newExtensions, (a, b) => compare(`${ExtensionIdentifier.toKey(a.identifier.id)}@${a.manifest.version}`, `${ExtensionIdentifier.toKey(b.identifier.id)}@${b.manifest.version}`)); if (added.length || removed.length) { -- cgit v1.2.3 From 04d9921d07e1e6145dbbed4303a33479a16d0558 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 10:38:38 -0700 Subject: Add separators to command decoration menu Part of #153382 --- .../terminal/browser/xterm/decorationAddon.ts | 28 +++++++++++++++------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts b/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts index 0d033529f59..d3284f43a86 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts @@ -12,7 +12,7 @@ import { CommandInvalidationReason, ITerminalCapabilityStore, TerminalCapability import { IColorTheme, ICssStyleCollector, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IHoverService } from 'vs/workbench/services/hover/browser/hover'; -import { IAction } from 'vs/base/common/actions'; +import { IAction, Separator } from 'vs/base/common/actions'; import { Emitter } from 'vs/base/common/event'; import { MarkdownString } from 'vs/base/common/htmlContent'; import { localize } from 'vs/nls'; @@ -353,24 +353,34 @@ export class DecorationAddon extends Disposable implements ITerminalAddon { private async _getCommandActions(command: ITerminalCommand): Promise { const actions: IAction[] = []; + if (command.command !== '') { + const label = localize("terminal.rerunCommand", 'Rerun Command'); + actions.push({ + class: undefined, tooltip: label, dispose: () => { }, id: 'terminal.rerunCommand', label, enabled: true, + run: () => this._onDidRequestRunCommand.fire({ command }) + }); + } if (command.hasOutput) { + if (actions.length > 0) { + actions.push(new Separator()); + } + const labelText = localize("terminal.copyOutput", 'Copy Output'); actions.push({ - class: 'copy-output', tooltip: 'Copy Output', dispose: () => { }, id: 'terminal.copyOutput', label: localize("terminal.copyOutput", 'Copy Output'), enabled: true, + class: undefined, tooltip: labelText, dispose: () => { }, id: 'terminal.copyOutput', label: labelText, enabled: true, run: () => this._clipboardService.writeText(command.getOutput()!) }); + const labelHtml = localize("terminal.copyOutputAsHtml", 'Copy Output as HTML'); actions.push({ - class: 'copy-output', tooltip: 'Copy Output as HTML', dispose: () => { }, id: 'terminal.copyOutputAsHtml', label: localize("terminal.copyOutputAsHtml", 'Copy Output as HTML'), enabled: true, + class: undefined, tooltip: labelHtml, dispose: () => { }, id: 'terminal.copyOutputAsHtml', label: labelHtml, enabled: true, run: () => this._onDidRequestRunCommand.fire({ command, copyAsHtml: true }) }); } - if (command.command !== '') { - actions.push({ - class: 'rerun-command', tooltip: 'Rerun Command', dispose: () => { }, id: 'terminal.rerunCommand', label: localize("terminal.rerunCommand", 'Rerun Command'), enabled: true, - run: () => this._onDidRequestRunCommand.fire({ command }) - }); + if (actions.length > 0) { + actions.push(new Separator()); } + const label = localize("terminal.learnShellIntegration", 'Learn About Shell Integration'); actions.push({ - class: 'how-does-this-work', tooltip: 'How does this work?', dispose: () => { }, id: 'terminal.howDoesThisWork', label: localize("terminal.howDoesThisWork", 'How does this work?'), enabled: true, + class: undefined, tooltip: label, dispose: () => { }, id: 'terminal.learnShellIntegration', label, enabled: true, run: () => this._openerService.open('https://code.visualstudio.com/docs/editor/integrated-terminal#_shell-integration') }); return actions; -- cgit v1.2.3 From 891fa893646795ec4995dc29f7c8ad76efbca312 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 10:41:54 -0700 Subject: Add copy command to command decoration menu Fixes #153382 --- .../workbench/contrib/terminal/browser/xterm/decorationAddon.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts b/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts index d3284f43a86..e7e3137ae30 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts @@ -354,11 +354,16 @@ export class DecorationAddon extends Disposable implements ITerminalAddon { private async _getCommandActions(command: ITerminalCommand): Promise { const actions: IAction[] = []; if (command.command !== '') { - const label = localize("terminal.rerunCommand", 'Rerun Command'); + const labelRun = localize("terminal.rerunCommand", 'Rerun Command'); actions.push({ - class: undefined, tooltip: label, dispose: () => { }, id: 'terminal.rerunCommand', label, enabled: true, + class: undefined, tooltip: labelRun, dispose: () => { }, id: 'terminal.rerunCommand', label: labelRun, enabled: true, run: () => this._onDidRequestRunCommand.fire({ command }) }); + const labelCopy = localize("terminal.copyCommand", 'Copy Command'); + actions.push({ + class: undefined, tooltip: labelCopy, dispose: () => { }, id: 'terminal.copyCommand', label: labelCopy, enabled: true, + run: () => this._clipboardService.writeText(command.command) + }); } if (command.hasOutput) { if (actions.length > 0) { -- cgit v1.2.3 From 877f2c3bd0fbc29c701813f57e529e947a1b4d28 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 5 Jul 2022 11:32:21 -0700 Subject: testing: don't make testing a workspace view For #153513 --- src/vs/workbench/contrib/testing/browser/testing.contribution.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/testing/browser/testing.contribution.ts b/src/vs/workbench/contrib/testing/browser/testing.contribution.ts index 3605c75ec80..f6580294960 100644 --- a/src/vs/workbench/contrib/testing/browser/testing.contribution.ts +++ b/src/vs/workbench/contrib/testing/browser/testing.contribution.ts @@ -87,7 +87,6 @@ viewsRegistry.registerViews([{ name: localize('testExplorer', "Test Explorer"), ctorDescriptor: new SyncDescriptor(TestingExplorerView), canToggleVisibility: true, - workspace: true, canMoveView: true, weight: 80, order: -999, -- cgit v1.2.3 From 87635892d81b2eb255fc412927f0ec48e6aef421 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 5 Jul 2022 12:08:42 -0700 Subject: debug/testing: fixup localized commands For #153865 --- .../contrib/debug/browser/callStackView.ts | 4 +- .../contrib/debug/browser/debug.contribution.ts | 29 +++++++------- .../contrib/debug/browser/debugCommands.ts | 37 ++++++++--------- .../contrib/debug/browser/debugToolBar.ts | 4 +- .../contrib/testing/browser/testExplorerActions.ts | 46 +++++++++++----------- .../testing/browser/testingExplorerFilter.ts | 2 +- .../contrib/testing/browser/testingOutputPeek.ts | 8 ++-- 7 files changed, 66 insertions(+), 64 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/debug/browser/callStackView.ts b/src/vs/workbench/contrib/debug/browser/callStackView.ts index 2eb3d65a818..b97d040674f 100644 --- a/src/vs/workbench/contrib/debug/browser/callStackView.ts +++ b/src/vs/workbench/contrib/debug/browser/callStackView.ts @@ -21,7 +21,7 @@ import { DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle' import { posix } from 'vs/base/common/path'; import { commonSuffixLength } from 'vs/base/common/strings'; import { localize } from 'vs/nls'; -import { Icon } from 'vs/platform/action/common/action'; +import { ICommandActionTitle, Icon } from 'vs/platform/action/common/action'; import { createAndFillInActionBarActions, createAndFillInContextMenuActions, MenuEntryActionViewItem, SubmenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { IMenuService, MenuId, MenuItemAction, MenuRegistry, registerAction2, SubmenuItemAction } from 'vs/platform/actions/common/actions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -1120,7 +1120,7 @@ registerAction2(class Collapse extends ViewAction { } }); -function registerCallStackInlineMenuItem(id: string, title: string, icon: Icon, when: ContextKeyExpression, order: number, precondition?: ContextKeyExpression): void { +function registerCallStackInlineMenuItem(id: string, title: string | ICommandActionTitle, icon: Icon, when: ContextKeyExpression, order: number, precondition?: ContextKeyExpression): void { MenuRegistry.appendMenuItem(MenuId.DebugCallStackContext, { group: 'inline', order, diff --git a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts index 11584519c47..bebcecd9455 100644 --- a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts @@ -20,7 +20,7 @@ import { } from 'vs/workbench/contrib/debug/common/debug'; import { DebugToolBar } from 'vs/workbench/contrib/debug/browser/debugToolBar'; import { DebugService } from 'vs/workbench/contrib/debug/browser/debugService'; -import { ADD_CONFIGURATION_ID, TOGGLE_INLINE_BREAKPOINT_ID, COPY_STACK_TRACE_ID, RESTART_SESSION_ID, TERMINATE_THREAD_ID, STEP_OVER_ID, STEP_INTO_ID, STEP_OUT_ID, PAUSE_ID, DISCONNECT_ID, STOP_ID, RESTART_FRAME_ID, CONTINUE_ID, FOCUS_REPL_ID, JUMP_TO_CURSOR_ID, RESTART_LABEL, STEP_INTO_LABEL, STEP_OVER_LABEL, STEP_OUT_LABEL, PAUSE_LABEL, DISCONNECT_LABEL, STOP_LABEL, CONTINUE_LABEL, DEBUG_START_LABEL, DEBUG_START_COMMAND_ID, DEBUG_RUN_LABEL, DEBUG_RUN_COMMAND_ID, EDIT_EXPRESSION_COMMAND_ID, REMOVE_EXPRESSION_COMMAND_ID, SELECT_AND_START_ID, SELECT_AND_START_LABEL, SET_EXPRESSION_COMMAND_ID, DISCONNECT_AND_SUSPEND_ID, DISCONNECT_AND_SUSPEND_LABEL, NEXT_DEBUG_CONSOLE_ID, NEXT_DEBUG_CONSOLE_LABEL, PREV_DEBUG_CONSOLE_ID, PREV_DEBUG_CONSOLE_LABEL, OPEN_LOADED_SCRIPTS_LABEL, SHOW_LOADED_SCRIPTS_ID, DEBUG_QUICK_ACCESS_PREFIX, DEBUG_CONSOLE_QUICK_ACCESS_PREFIX, SELECT_DEBUG_CONSOLE_ID, SELECT_DEBUG_CONSOLE_LABEL, STEP_INTO_TARGET_LABEL, STEP_INTO_TARGET_ID } from 'vs/workbench/contrib/debug/browser/debugCommands'; +import { ADD_CONFIGURATION_ID, TOGGLE_INLINE_BREAKPOINT_ID, COPY_STACK_TRACE_ID, RESTART_SESSION_ID, TERMINATE_THREAD_ID, STEP_OVER_ID, STEP_INTO_ID, STEP_OUT_ID, PAUSE_ID, DISCONNECT_ID, STOP_ID, RESTART_FRAME_ID, CONTINUE_ID, FOCUS_REPL_ID, JUMP_TO_CURSOR_ID, RESTART_LABEL, STEP_INTO_LABEL, STEP_OVER_LABEL, STEP_OUT_LABEL, PAUSE_LABEL, DISCONNECT_LABEL, STOP_LABEL, CONTINUE_LABEL, DEBUG_START_LABEL, DEBUG_START_COMMAND_ID, DEBUG_RUN_LABEL, DEBUG_RUN_COMMAND_ID, EDIT_EXPRESSION_COMMAND_ID, REMOVE_EXPRESSION_COMMAND_ID, SELECT_AND_START_ID, SELECT_AND_START_LABEL, SET_EXPRESSION_COMMAND_ID, DISCONNECT_AND_SUSPEND_ID, DISCONNECT_AND_SUSPEND_LABEL, NEXT_DEBUG_CONSOLE_ID, NEXT_DEBUG_CONSOLE_LABEL, PREV_DEBUG_CONSOLE_ID, PREV_DEBUG_CONSOLE_LABEL, OPEN_LOADED_SCRIPTS_LABEL, SHOW_LOADED_SCRIPTS_ID, DEBUG_QUICK_ACCESS_PREFIX, DEBUG_CONSOLE_QUICK_ACCESS_PREFIX, SELECT_DEBUG_CONSOLE_ID, SELECT_DEBUG_CONSOLE_LABEL, STEP_INTO_TARGET_LABEL, STEP_INTO_TARGET_ID, DEBUG_COMMAND_CATEGORY } from 'vs/workbench/contrib/debug/browser/debugCommands'; import { StatusBarColorProvider } from 'vs/workbench/contrib/debug/browser/statusbarColorProvider'; import { IViewsRegistry, Extensions as ViewExtensions, IViewContainersRegistry, ViewContainerLocation, ViewContainer } from 'vs/workbench/common/views'; import { isMacintosh, isWeb } from 'vs/base/common/platform'; @@ -55,7 +55,7 @@ import { DisassemblyView, DisassemblyViewContribution } from 'vs/workbench/contr import { EditorPaneDescriptor, IEditorPaneRegistry } from 'vs/workbench/browser/editor'; import { DisassemblyViewInput } from 'vs/workbench/contrib/debug/common/disassemblyViewInput'; import { DebugLifecycle } from 'vs/workbench/contrib/debug/common/debugLifecycle'; -import { Icon } from 'vs/platform/action/common/action'; +import { ICommandActionTitle, Icon } from 'vs/platform/action/common/action'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { DebugConsoleQuickAccess } from 'vs/workbench/contrib/debug/browser/debugConsoleQuickAccess'; @@ -98,20 +98,21 @@ registerEditorContribution('editor.contrib.callStack', CallStackEditorContributi registerEditorContribution(BREAKPOINT_EDITOR_CONTRIBUTION_ID, BreakpointEditorContribution); registerEditorContribution(EDITOR_CONTRIBUTION_ID, DebugEditorContribution); -const registerDebugCommandPaletteItem = (id: string, title: string, when?: ContextKeyExpression, precondition?: ContextKeyExpression) => { +const registerDebugCommandPaletteItem = (id: string, title: ICommandActionTitle, when?: ContextKeyExpression, precondition?: ContextKeyExpression) => { MenuRegistry.appendMenuItem(MenuId.CommandPalette, { when: ContextKeyExpr.and(CONTEXT_DEBUGGERS_AVAILABLE, when), group: debugCategory, command: { id, - title: `Debug: ${title}`, + title, + category: DEBUG_COMMAND_CATEGORY, precondition } }); }; registerDebugCommandPaletteItem(RESTART_SESSION_ID, RESTART_LABEL); -registerDebugCommandPaletteItem(TERMINATE_THREAD_ID, nls.localize('terminateThread', "Terminate Thread"), CONTEXT_IN_DEBUG_MODE); +registerDebugCommandPaletteItem(TERMINATE_THREAD_ID, { value: nls.localize('terminateThread', "Terminate Thread"), original: 'Terminate Thread' }, CONTEXT_IN_DEBUG_MODE); registerDebugCommandPaletteItem(STEP_OVER_ID, STEP_OVER_LABEL, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped')); registerDebugCommandPaletteItem(STEP_INTO_ID, STEP_INTO_LABEL, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped')); registerDebugCommandPaletteItem(STEP_INTO_TARGET_ID, STEP_INTO_TARGET_LABEL, CONTEXT_IN_DEBUG_MODE, ContextKeyExpr.and(CONTEXT_STEP_INTO_TARGETS_SUPPORTED, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped'))); @@ -121,13 +122,13 @@ registerDebugCommandPaletteItem(DISCONNECT_ID, DISCONNECT_LABEL, CONTEXT_IN_DEBU registerDebugCommandPaletteItem(DISCONNECT_AND_SUSPEND_ID, DISCONNECT_AND_SUSPEND_LABEL, CONTEXT_IN_DEBUG_MODE, ContextKeyExpr.or(CONTEXT_FOCUSED_SESSION_IS_ATTACH, ContextKeyExpr.and(CONTEXT_SUSPEND_DEBUGGEE_SUPPORTED, CONTEXT_TERMINATE_DEBUGGEE_SUPPORTED))); registerDebugCommandPaletteItem(STOP_ID, STOP_LABEL, CONTEXT_IN_DEBUG_MODE, ContextKeyExpr.or(CONTEXT_FOCUSED_SESSION_IS_ATTACH.toNegated(), CONTEXT_TERMINATE_DEBUGGEE_SUPPORTED)); registerDebugCommandPaletteItem(CONTINUE_ID, CONTINUE_LABEL, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped')); -registerDebugCommandPaletteItem(FOCUS_REPL_ID, nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'debugFocusConsole' }, 'Focus on Debug Console View')); -registerDebugCommandPaletteItem(JUMP_TO_CURSOR_ID, nls.localize('jumpToCursor', "Jump to Cursor"), CONTEXT_JUMP_TO_CURSOR_SUPPORTED); -registerDebugCommandPaletteItem(JUMP_TO_CURSOR_ID, nls.localize('SetNextStatement', "Set Next Statement"), CONTEXT_JUMP_TO_CURSOR_SUPPORTED); -registerDebugCommandPaletteItem(RunToCursorAction.ID, RunToCursorAction.LABEL, ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped'))); -registerDebugCommandPaletteItem(SelectionToReplAction.ID, SelectionToReplAction.LABEL, ContextKeyExpr.and(EditorContextKeys.hasNonEmptySelection, CONTEXT_IN_DEBUG_MODE)); -registerDebugCommandPaletteItem(SelectionToWatchExpressionsAction.ID, SelectionToWatchExpressionsAction.LABEL, ContextKeyExpr.and(EditorContextKeys.hasNonEmptySelection, CONTEXT_IN_DEBUG_MODE)); -registerDebugCommandPaletteItem(TOGGLE_INLINE_BREAKPOINT_ID, nls.localize('inlineBreakpoint', "Inline Breakpoint")); +registerDebugCommandPaletteItem(FOCUS_REPL_ID, { value: nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'debugFocusConsole' }, 'Focus on Debug Console View'), original: 'Focus on Debug Console View' }); +registerDebugCommandPaletteItem(JUMP_TO_CURSOR_ID, { value: nls.localize('jumpToCursor', "Jump to Cursor"), original: 'Jump to Cursor' }, CONTEXT_JUMP_TO_CURSOR_SUPPORTED); +registerDebugCommandPaletteItem(JUMP_TO_CURSOR_ID, { value: nls.localize('SetNextStatement', "Set Next Statement"), original: 'Set Next Statement' }, CONTEXT_JUMP_TO_CURSOR_SUPPORTED); +registerDebugCommandPaletteItem(RunToCursorAction.ID, { value: RunToCursorAction.LABEL, original: 'Run to Cursor' }, ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped'))); +registerDebugCommandPaletteItem(SelectionToReplAction.ID, { value: SelectionToReplAction.LABEL, original: 'Evaluate in Debug Console' }, ContextKeyExpr.and(EditorContextKeys.hasNonEmptySelection, CONTEXT_IN_DEBUG_MODE)); +registerDebugCommandPaletteItem(SelectionToWatchExpressionsAction.ID, { value: SelectionToWatchExpressionsAction.LABEL, original: 'Add to Watch' }, ContextKeyExpr.and(EditorContextKeys.hasNonEmptySelection, CONTEXT_IN_DEBUG_MODE)); +registerDebugCommandPaletteItem(TOGGLE_INLINE_BREAKPOINT_ID, { value: nls.localize('inlineBreakpoint', "Inline Breakpoint"), original: 'Inline Breakpoint' }); registerDebugCommandPaletteItem(DEBUG_START_COMMAND_ID, DEBUG_START_LABEL, ContextKeyExpr.and(CONTEXT_DEBUGGERS_AVAILABLE, CONTEXT_DEBUG_STATE.notEqualsTo(getStateLabel(State.Initializing)))); registerDebugCommandPaletteItem(DEBUG_RUN_COMMAND_ID, DEBUG_RUN_LABEL, ContextKeyExpr.and(CONTEXT_DEBUGGERS_AVAILABLE, CONTEXT_DEBUG_STATE.notEqualsTo(getStateLabel(State.Initializing)))); registerDebugCommandPaletteItem(SELECT_AND_START_ID, SELECT_AND_START_LABEL, ContextKeyExpr.and(CONTEXT_DEBUGGERS_AVAILABLE, CONTEXT_DEBUG_STATE.notEqualsTo(getStateLabel(State.Initializing)))); @@ -138,7 +139,7 @@ registerDebugCommandPaletteItem(SELECT_DEBUG_CONSOLE_ID, SELECT_DEBUG_CONSOLE_LA // Debug callstack context menu -const registerDebugViewMenuItem = (menuId: MenuId, id: string, title: string, order: number, when?: ContextKeyExpression, precondition?: ContextKeyExpression, group = 'navigation', icon?: Icon) => { +const registerDebugViewMenuItem = (menuId: MenuId, id: string, title: string | ICommandActionTitle, order: number, when?: ContextKeyExpression, precondition?: ContextKeyExpression, group = 'navigation', icon?: Icon) => { MenuRegistry.appendMenuItem(menuId, { group, when, @@ -186,7 +187,7 @@ registerDebugViewMenuItem(MenuId.DebugWatchContext, REMOVE_WATCH_EXPRESSIONS_COM // Touch Bar if (isMacintosh) { - const registerTouchBarEntry = (id: string, title: string, order: number, when: ContextKeyExpression | undefined, iconUri: URI) => { + const registerTouchBarEntry = (id: string, title: string | ICommandActionTitle, order: number, when: ContextKeyExpression | undefined, iconUri: URI) => { MenuRegistry.appendMenuItem(MenuId.TouchBarContext, { command: { id, diff --git a/src/vs/workbench/contrib/debug/browser/debugCommands.ts b/src/vs/workbench/contrib/debug/browser/debugCommands.ts index 49eb8197d7a..86fa5b8c01b 100644 --- a/src/vs/workbench/contrib/debug/browser/debugCommands.ts +++ b/src/vs/workbench/contrib/debug/browser/debugCommands.ts @@ -65,26 +65,27 @@ export const NEXT_DEBUG_CONSOLE_ID = 'workbench.action.debug.nextConsole'; export const PREV_DEBUG_CONSOLE_ID = 'workbench.action.debug.prevConsole'; export const SHOW_LOADED_SCRIPTS_ID = 'workbench.action.debug.showLoadedScripts'; -export const RESTART_LABEL = nls.localize('restartDebug', "Restart"); -export const STEP_OVER_LABEL = nls.localize('stepOverDebug', "Step Over"); -export const STEP_INTO_LABEL = nls.localize('stepIntoDebug', "Step Into"); -export const STEP_INTO_TARGET_LABEL = nls.localize('stepIntoTargetDebug', "Step Into Target"); -export const STEP_OUT_LABEL = nls.localize('stepOutDebug', "Step Out"); -export const PAUSE_LABEL = nls.localize('pauseDebug', "Pause"); -export const DISCONNECT_LABEL = nls.localize('disconnect', "Disconnect"); -export const DISCONNECT_AND_SUSPEND_LABEL = nls.localize('disconnectSuspend', "Disconnect and Suspend"); -export const STOP_LABEL = nls.localize('stop', "Stop"); -export const CONTINUE_LABEL = nls.localize('continueDebug', "Continue"); -export const FOCUS_SESSION_LABEL = nls.localize('focusSession', "Focus Session"); -export const SELECT_AND_START_LABEL = nls.localize('selectAndStartDebugging', "Select and Start Debugging"); +export const DEBUG_COMMAND_CATEGORY = 'Debug'; +export const RESTART_LABEL = { value: nls.localize('restartDebug', "Restart"), original: 'Restart' }; +export const STEP_OVER_LABEL = { value: nls.localize('stepOverDebug', "Step Over"), original: 'Step Over' }; +export const STEP_INTO_LABEL = { value: nls.localize('stepIntoDebug', "Step Into"), original: 'Step Into' }; +export const STEP_INTO_TARGET_LABEL = { value: nls.localize('stepIntoTargetDebug', "Step Into Target"), original: 'Step Into Target' }; +export const STEP_OUT_LABEL = { value: nls.localize('stepOutDebug', "Step Out"), original: 'Step Out' }; +export const PAUSE_LABEL = { value: nls.localize('pauseDebug', "Pause"), original: 'Pause' }; +export const DISCONNECT_LABEL = { value: nls.localize('disconnect', "Disconnect"), original: 'Disconnect' }; +export const DISCONNECT_AND_SUSPEND_LABEL = { value: nls.localize('disconnectSuspend', "Disconnect and Suspend"), original: 'Disconnect and Suspend' }; +export const STOP_LABEL = { value: nls.localize('stop', "Stop"), original: 'Stop' }; +export const CONTINUE_LABEL = { value: nls.localize('continueDebug', "Continue"), original: 'Continue' }; +export const FOCUS_SESSION_LABEL = { value: nls.localize('focusSession', "Focus Session"), original: 'Focus Session' }; +export const SELECT_AND_START_LABEL = { value: nls.localize('selectAndStartDebugging', "Select and Start Debugging"), original: 'Select and Start Debugging' }; export const DEBUG_CONFIGURE_LABEL = nls.localize('openLaunchJson', "Open '{0}'", 'launch.json'); -export const DEBUG_START_LABEL = nls.localize('startDebug', "Start Debugging"); -export const DEBUG_RUN_LABEL = nls.localize('startWithoutDebugging', "Start Without Debugging"); -export const NEXT_DEBUG_CONSOLE_LABEL = nls.localize('nextDebugConsole', "Focus Next Debug Console"); -export const PREV_DEBUG_CONSOLE_LABEL = nls.localize('prevDebugConsole', "Focus Previous Debug Console"); -export const OPEN_LOADED_SCRIPTS_LABEL = nls.localize('openLoadedScript', "Open Loaded Script..."); +export const DEBUG_START_LABEL = { value: nls.localize('startDebug', "Start Debugging"), original: 'Start Debugging' }; +export const DEBUG_RUN_LABEL = { value: nls.localize('startWithoutDebugging', "Start Without Debugging"), original: 'Start Without Debugging' }; +export const NEXT_DEBUG_CONSOLE_LABEL = { value: nls.localize('nextDebugConsole', "Focus Next Debug Console"), original: 'Focus Next Debug Console' }; +export const PREV_DEBUG_CONSOLE_LABEL = { value: nls.localize('prevDebugConsole', "Focus Previous Debug Console"), original: 'Focus Previous Debug Console' }; +export const OPEN_LOADED_SCRIPTS_LABEL = { value: nls.localize('openLoadedScript', "Open Loaded Script..."), original: 'Open Loaded Script...' }; -export const SELECT_DEBUG_CONSOLE_LABEL = nls.localize('selectDebugConsole', "Select Debug Console"); +export const SELECT_DEBUG_CONSOLE_LABEL = { value: nls.localize('selectDebugConsole', "Select Debug Console"), original: 'Select Debug Console' }; export const DEBUG_QUICK_ACCESS_PREFIX = 'debug '; export const DEBUG_CONSOLE_QUICK_ACCESS_PREFIX = 'debug consoles '; diff --git a/src/vs/workbench/contrib/debug/browser/debugToolBar.ts b/src/vs/workbench/contrib/debug/browser/debugToolBar.ts index 1f7614bfee7..3fd1c0238b8 100644 --- a/src/vs/workbench/contrib/debug/browser/debugToolBar.ts +++ b/src/vs/workbench/contrib/debug/browser/debugToolBar.ts @@ -16,7 +16,7 @@ import { URI } from 'vs/base/common/uri'; import 'vs/css!./media/debugToolBar'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { localize } from 'vs/nls'; -import { ICommandAction } from 'vs/platform/action/common/action'; +import { ICommandAction, ICommandActionTitle } from 'vs/platform/action/common/action'; import { DropdownWithPrimaryActionViewItem } from 'vs/platform/actions/browser/dropdownWithPrimaryActionViewItem'; import { createActionViewItem, createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { IMenu, IMenuService, MenuId, MenuItemAction, MenuRegistry } from 'vs/platform/actions/common/actions'; @@ -296,7 +296,7 @@ export function createDisconnectMenuItemAction(action: MenuItemAction, disposabl // Debug toolbar const debugViewTitleItems: IDisposable[] = []; -const registerDebugToolBarItem = (id: string, title: string, order: number, icon?: { light?: URI; dark?: URI } | ThemeIcon, when?: ContextKeyExpression, precondition?: ContextKeyExpression, alt?: ICommandAction) => { +const registerDebugToolBarItem = (id: string, title: string | ICommandActionTitle, order: number, icon?: { light?: URI; dark?: URI } | ThemeIcon, when?: ContextKeyExpression, precondition?: ContextKeyExpression, alt?: ICommandAction) => { MenuRegistry.appendMenuItem(MenuId.DebugToolBar, { group: 'navigation', when, diff --git a/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts b/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts index db687ec08b6..556f7f4e65d 100644 --- a/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts +++ b/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts @@ -406,7 +406,7 @@ export class CancelTestRunAction extends Action2 { constructor() { super({ id: TestCommandId.CancelTestRunAction, - title: localize('testing.cancelRun', "Cancel Test Run"), + title: { value: localize('testing.cancelRun', "Cancel Test Run"), original: 'Cancel Test Run' }, icon: icons.testingCancelIcon, keybinding: { weight: KeybindingWeight.WorkbenchContrib, @@ -443,7 +443,7 @@ export class TestingViewAsListAction extends ViewAction { super({ id: TestCommandId.TestingViewAsListAction, viewId: Testing.ExplorerViewId, - title: localize('testing.viewAsList', "View as List"), + title: { value: localize('testing.viewAsList', "View as List"), original: 'View as List' }, toggled: TestingContextKeys.viewMode.isEqualTo(TestExplorerViewMode.List), menu: { id: MenuId.ViewTitle, @@ -467,7 +467,7 @@ export class TestingViewAsTreeAction extends ViewAction { super({ id: TestCommandId.TestingViewAsTreeAction, viewId: Testing.ExplorerViewId, - title: localize('testing.viewAsTree', "View as Tree"), + title: { value: localize('testing.viewAsTree', "View as Tree"), original: 'View as Tree' }, toggled: TestingContextKeys.viewMode.isEqualTo(TestExplorerViewMode.Tree), menu: { id: MenuId.ViewTitle, @@ -492,7 +492,7 @@ export class TestingSortByStatusAction extends ViewAction { super({ id: TestCommandId.TestingSortByStatusAction, viewId: Testing.ExplorerViewId, - title: localize('testing.sortByStatus', "Sort by Status"), + title: { value: localize('testing.sortByStatus', "Sort by Status"), original: 'Sort by Status' }, toggled: TestingContextKeys.viewSorting.isEqualTo(TestExplorerViewSorting.ByStatus), menu: { id: MenuId.ViewTitle, @@ -516,7 +516,7 @@ export class TestingSortByLocationAction extends ViewAction super({ id: TestCommandId.TestingSortByLocationAction, viewId: Testing.ExplorerViewId, - title: localize('testing.sortByLocation', "Sort by Location"), + title: { value: localize('testing.sortByLocation', "Sort by Location"), original: 'Sort by Location' }, toggled: TestingContextKeys.viewSorting.isEqualTo(TestExplorerViewSorting.ByLocation), menu: { id: MenuId.ViewTitle, @@ -540,7 +540,7 @@ export class TestingSortByDurationAction extends ViewAction super({ id: TestCommandId.TestingSortByDurationAction, viewId: Testing.ExplorerViewId, - title: localize('testing.sortByDuration', "Sort by Duration"), + title: { value: localize('testing.sortByDuration', "Sort by Duration"), original: 'Sort by Duration' }, toggled: TestingContextKeys.viewSorting.isEqualTo(TestExplorerViewSorting.ByDuration), menu: { id: MenuId.ViewTitle, @@ -563,7 +563,7 @@ export class ShowMostRecentOutputAction extends Action2 { constructor() { super({ id: TestCommandId.ShowMostRecentOutputAction, - title: localize('testing.showMostRecentOutput', "Show Output"), + title: { value: localize('testing.showMostRecentOutput', "Show Output"), original: 'Show Output' }, category, icon: Codicon.terminal, keybinding: { @@ -594,7 +594,7 @@ export class CollapseAllAction extends ViewAction { super({ id: TestCommandId.CollapseAllAction, viewId: Testing.ExplorerViewId, - title: localize('testing.collapseAll', "Collapse All Tests"), + title: { value: localize('testing.collapseAll', "Collapse All Tests"), original: 'Collapse All Tests' }, icon: Codicon.collapseAll, menu: { id: MenuId.ViewTitle, @@ -617,7 +617,7 @@ export class ClearTestResultsAction extends Action2 { constructor() { super({ id: TestCommandId.ClearTestResultsAction, - title: localize('testing.clearResults', "Clear All Results"), + title: { value: localize('testing.clearResults', "Clear All Results"), original: 'Clear All Results' }, category, icon: Codicon.trash, menu: [{ @@ -646,7 +646,7 @@ export class GoToTest extends Action2 { constructor() { super({ id: TestCommandId.GoToTest, - title: localize('testing.editFocusedTest', "Go to Test"), + title: { value: localize('testing.editFocusedTest', "Go to Test"), original: 'Go to Test' }, icon: Codicon.goToFile, menu: testItemInlineAndInContext(ActionOrder.GoToTest, TestingContextKeys.testItemHasUri.isEqualTo(true)), keybinding: { @@ -742,7 +742,7 @@ export class RunAtCursor extends ExecuteTestAtCursor { constructor() { super({ id: TestCommandId.RunAtCursor, - title: localize('testing.runAtCursor', "Run Test at Cursor"), + title: { value: localize('testing.runAtCursor', "Run Test at Cursor"), original: 'Run Test at Cursor' }, category, keybinding: { weight: KeybindingWeight.WorkbenchContrib, @@ -757,7 +757,7 @@ export class DebugAtCursor extends ExecuteTestAtCursor { constructor() { super({ id: TestCommandId.DebugAtCursor, - title: localize('testing.debugAtCursor', "Debug Test at Cursor"), + title: { value: localize('testing.debugAtCursor', "Debug Test at Cursor"), original: 'Debug Test at Cursor' }, category, keybinding: { weight: KeybindingWeight.WorkbenchContrib, @@ -824,7 +824,7 @@ export class RunCurrentFile extends ExecuteTestsInCurrentFile { constructor() { super({ id: TestCommandId.RunCurrentFile, - title: localize('testing.runCurrentFile', "Run Tests in Current File"), + title: { value: localize('testing.runCurrentFile', "Run Tests in Current File"), original: 'Run Tests in Current File' }, category, keybinding: { weight: KeybindingWeight.WorkbenchContrib, @@ -840,7 +840,7 @@ export class DebugCurrentFile extends ExecuteTestsInCurrentFile { constructor() { super({ id: TestCommandId.DebugCurrentFile, - title: localize('testing.debugCurrentFile', "Debug Tests in Current File"), + title: { value: localize('testing.debugCurrentFile', "Debug Tests in Current File"), original: 'Debug Tests in Current File' }, category, keybinding: { weight: KeybindingWeight.WorkbenchContrib, @@ -948,7 +948,7 @@ export class ReRunFailedTests extends RunOrDebugFailedTests { constructor() { super({ id: TestCommandId.ReRunFailedTests, - title: localize('testing.reRunFailTests', "Rerun Failed Tests"), + title: { value: localize('testing.reRunFailTests', "Rerun Failed Tests"), original: 'Rerun Failed Tests' }, category, keybinding: { weight: KeybindingWeight.WorkbenchContrib, @@ -969,7 +969,7 @@ export class DebugFailedTests extends RunOrDebugFailedTests { constructor() { super({ id: TestCommandId.DebugFailedTests, - title: localize('testing.debugFailTests', "Debug Failed Tests"), + title: { value: localize('testing.debugFailTests', "Debug Failed Tests"), original: 'Debug Failed Tests' }, category, keybinding: { weight: KeybindingWeight.WorkbenchContrib, @@ -990,7 +990,7 @@ export class ReRunLastRun extends RunOrDebugLastRun { constructor() { super({ id: TestCommandId.ReRunLastRun, - title: localize('testing.reRunLastRun', "Rerun Last Run"), + title: { value: localize('testing.reRunLastRun', "Rerun Last Run"), original: 'Rerun Last Run' }, category, keybinding: { weight: KeybindingWeight.WorkbenchContrib, @@ -1011,7 +1011,7 @@ export class DebugLastRun extends RunOrDebugLastRun { constructor() { super({ id: TestCommandId.DebugLastRun, - title: localize('testing.debugLastRun', "Debug Last Run"), + title: { value: localize('testing.debugLastRun', "Debug Last Run"), original: 'Debug Last Run' }, category, keybinding: { weight: KeybindingWeight.WorkbenchContrib, @@ -1032,7 +1032,7 @@ export class SearchForTestExtension extends Action2 { constructor() { super({ id: TestCommandId.SearchForTestExtension, - title: localize('testing.searchForTestExtension', "Search for Test Extension"), + title: { value: localize('testing.searchForTestExtension', "Search for Test Extension"), original: 'Search for Test Extension' }, }); } @@ -1048,7 +1048,7 @@ export class OpenOutputPeek extends Action2 { constructor() { super({ id: TestCommandId.OpenOutputPeek, - title: localize('testing.openOutputPeek', "Peek Output"), + title: { value: localize('testing.openOutputPeek', "Peek Output"), original: 'Peek Output' }, category, keybinding: { weight: KeybindingWeight.WorkbenchContrib, @@ -1070,7 +1070,7 @@ export class ToggleInlineTestOutput extends Action2 { constructor() { super({ id: TestCommandId.ToggleInlineTestOutput, - title: localize('testing.toggleInlineTestOutput', "Toggle Inline Test Output"), + title: { value: localize('testing.toggleInlineTestOutput', "Toggle Inline Test Output"), original: 'Toggle Inline Test Output' }, category, keybinding: { weight: KeybindingWeight.WorkbenchContrib, @@ -1119,7 +1119,7 @@ export class RefreshTestsAction extends Action2 { constructor() { super({ id: TestCommandId.RefreshTestsAction, - title: localize('testing.refreshTests', "Refresh Tests"), + title: { value: localize('testing.refreshTests', "Refresh Tests"), original: 'Refresh Tests' }, category, icon: icons.testingRefreshTests, keybinding: { @@ -1155,7 +1155,7 @@ export class CancelTestRefreshAction extends Action2 { constructor() { super({ id: TestCommandId.CancelTestRefreshAction, - title: localize('testing.cancelTestRefresh', "Cancel Test Refresh"), + title: { value: localize('testing.cancelTestRefresh', "Cancel Test Refresh"), original: 'Cancel Test Refresh' }, category, icon: icons.testingCancelRefreshTests, menu: refreshMenus(true), diff --git a/src/vs/workbench/contrib/testing/browser/testingExplorerFilter.ts b/src/vs/workbench/contrib/testing/browser/testingExplorerFilter.ts index 4d1af363aa7..52d57770b21 100644 --- a/src/vs/workbench/contrib/testing/browser/testingExplorerFilter.ts +++ b/src/vs/workbench/contrib/testing/browser/testingExplorerFilter.ts @@ -252,7 +252,7 @@ registerAction2(class extends Action2 { constructor() { super({ id: TestCommandId.FilterAction, - title: localize('filter', "Filter"), + title: { value: localize('filter', "Filter"), original: 'Filter' }, }); } async run(): Promise { } diff --git a/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts b/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts index c3452de68dd..988ad294015 100644 --- a/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts +++ b/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts @@ -1666,7 +1666,7 @@ export class GoToNextMessageAction extends EditorAction2 { super({ id: GoToNextMessageAction.ID, f1: true, - title: localize('testing.goToNextMessage', "Go to Next Test Failure"), + title: { value: localize('testing.goToNextMessage', "Go to Next Test Failure"), original: 'Go to Next Test Failure' }, icon: Codicon.arrowDown, category: CATEGORIES.Test, keybinding: { @@ -1696,7 +1696,7 @@ export class GoToPreviousMessageAction extends EditorAction2 { super({ id: GoToPreviousMessageAction.ID, f1: true, - title: localize('testing.goToPreviousMessage', "Go to Previous Test Failure"), + title: { value: localize('testing.goToPreviousMessage', "Go to Previous Test Failure"), original: 'Go to Previous Test Failure' }, icon: Codicon.arrowUp, category: CATEGORIES.Test, keybinding: { @@ -1726,7 +1726,7 @@ export class OpenMessageInEditorAction extends EditorAction2 { super({ id: OpenMessageInEditorAction.ID, f1: false, - title: localize('testing.openMessageInEditor', "Open in Editor"), + title: { value: localize('testing.openMessageInEditor', "Open in Editor"), original: 'Open in Editor' }, icon: Codicon.linkExternal, category: CATEGORIES.Test, menu: [{ id: MenuId.TestPeekTitle }], @@ -1744,7 +1744,7 @@ export class ToggleTestingPeekHistory extends EditorAction2 { super({ id: ToggleTestingPeekHistory.ID, f1: true, - title: localize('testing.toggleTestingPeekHistory', "Toggle Test History in Peek"), + title: { value: localize('testing.toggleTestingPeekHistory', "Toggle Test History in Peek"), original: 'Toggle Test History in Peek' }, icon: Codicon.history, category: CATEGORIES.Test, menu: [{ -- cgit v1.2.3 From 934408aea7883601032febd844796f826ca8ecd2 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 6 Jul 2022 11:03:38 -0700 Subject: Debt - `sessionSync` -> `editSessions` (#154289) --- src/vs/base/common/product.ts | 2 +- .../browser/editSessions.contribution.ts | 517 +++++++++++++++++++++ .../browser/editSessionsWorkbenchService.ts | 358 ++++++++++++++ .../contrib/editSessions/common/editSessions.ts | 67 +++ .../editSessions/common/editSessionsLogService.ts | 50 ++ .../editSessions/test/browser/editSessions.test.ts | 134 ++++++ .../browser/sessionSync.contribution.ts | 517 --------------------- .../browser/sessionSyncWorkbenchService.ts | 358 -------------- .../sessionSync/common/editSessionsLogService.ts | 50 -- .../contrib/sessionSync/common/sessionSync.ts | 67 --- .../sessionSync/test/browser/sessionSync.test.ts | 134 ------ src/vs/workbench/workbench.common.main.ts | 2 +- 12 files changed, 1128 insertions(+), 1128 deletions(-) create mode 100644 src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts create mode 100644 src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts create mode 100644 src/vs/workbench/contrib/editSessions/common/editSessions.ts create mode 100644 src/vs/workbench/contrib/editSessions/common/editSessionsLogService.ts create mode 100644 src/vs/workbench/contrib/editSessions/test/browser/editSessions.test.ts delete mode 100644 src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts delete mode 100644 src/vs/workbench/contrib/sessionSync/browser/sessionSyncWorkbenchService.ts delete mode 100644 src/vs/workbench/contrib/sessionSync/common/editSessionsLogService.ts delete mode 100644 src/vs/workbench/contrib/sessionSync/common/sessionSync.ts delete mode 100644 src/vs/workbench/contrib/sessionSync/test/browser/sessionSync.test.ts (limited to 'src/vs') diff --git a/src/vs/base/common/product.ts b/src/vs/base/common/product.ts index 5dcf73fc4a3..0e9dcdcba96 100644 --- a/src/vs/base/common/product.ts +++ b/src/vs/base/common/product.ts @@ -155,7 +155,7 @@ export interface IProductConfiguration { readonly 'configurationSync.store'?: ConfigurationSyncStore; - readonly 'sessionSync.store'?: Omit; + readonly 'editSessions.store'?: Omit; readonly darwinUniversalAssetId?: string; } diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts new file mode 100644 index 00000000000..deb0cb486bc --- /dev/null +++ b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts @@ -0,0 +1,517 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable } from 'vs/base/common/lifecycle'; +import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; +import { Action2, IAction2Options, registerAction2 } from 'vs/platform/actions/common/actions'; +import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; +import { localize } from 'vs/nls'; +import { IEditSessionsWorkbenchService, Change, ChangeType, Folder, EditSession, FileType, EDIT_SESSION_SYNC_CATEGORY, EditSessionSchemaVersion, IEditSessionsLogService } from 'vs/workbench/contrib/editSessions/common/editSessions'; +import { ISCMRepository, ISCMService } from 'vs/workbench/contrib/scm/common/scm'; +import { IFileService } from 'vs/platform/files/common/files'; +import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { URI } from 'vs/base/common/uri'; +import { joinPath, relativePath } from 'vs/base/common/resources'; +import { VSBuffer } from 'vs/base/common/buffer'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress'; +import { EditSessionsWorkbenchService } from 'vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { UserDataSyncErrorCode, UserDataSyncStoreError } from 'vs/platform/userDataSync/common/userDataSync'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { INotificationService } from 'vs/platform/notification/common/notification'; +import { IDialogService, IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { IProductService } from 'vs/platform/product/common/productService'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration'; +import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; +import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; +import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry'; +import { ContextKeyExpr, ContextKeyExpression, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { getVirtualWorkspaceLocation } from 'vs/platform/workspace/common/virtualWorkspace'; +import { Schemas } from 'vs/base/common/network'; +import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys'; +import { isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; +import { EditSessionsLogService } from 'vs/workbench/contrib/editSessions/common/editSessionsLogService'; + +registerSingleton(IEditSessionsLogService, EditSessionsLogService); +registerSingleton(IEditSessionsWorkbenchService, EditSessionsWorkbenchService); + +const continueEditSessionCommand: IAction2Options = { + id: '_workbench.experimental.editSessions.actions.continueEditSession', + title: { value: localize('continue edit session', "Continue Edit Session..."), original: 'Continue Edit Session...' }, + category: EDIT_SESSION_SYNC_CATEGORY, + f1: true +}; +const openLocalFolderCommand: IAction2Options = { + id: '_workbench.experimental.editSessions.actions.continueEditSession.openLocalFolder', + title: { value: localize('continue edit session in local folder', "Open In Local Folder"), original: 'Open In Local Folder' }, + category: EDIT_SESSION_SYNC_CATEGORY, + precondition: IsWebContext +}; +const queryParamName = 'editSessionId'; +const experimentalSettingName = 'workbench.experimental.editSessions.enabled'; + +export class EditSessionsContribution extends Disposable implements IWorkbenchContribution { + + private registered = false; + private continueEditSessionOptions: ContinueEditSessionItem[] = []; + + constructor( + @IEditSessionsWorkbenchService private readonly editSessionsWorkbenchService: IEditSessionsWorkbenchService, + @IFileService private readonly fileService: IFileService, + @IProgressService private readonly progressService: IProgressService, + @IOpenerService private readonly openerService: IOpenerService, + @ITelemetryService private readonly telemetryService: ITelemetryService, + @ISCMService private readonly scmService: ISCMService, + @INotificationService private readonly notificationService: INotificationService, + @IDialogService private readonly dialogService: IDialogService, + @IEditSessionsLogService private readonly logService: IEditSessionsLogService, + @IEnvironmentService private readonly environmentService: IEnvironmentService, + @IProductService private readonly productService: IProductService, + @IConfigurationService private configurationService: IConfigurationService, + @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, + @IQuickInputService private readonly quickInputService: IQuickInputService, + @ICommandService private commandService: ICommandService, + @IContextKeyService private readonly contextKeyService: IContextKeyService, + @IFileDialogService private readonly fileDialogService: IFileDialogService + ) { + super(); + + if (this.environmentService.editSessionId !== undefined) { + void this.applyEditSession(this.environmentService.editSessionId).finally(() => this.environmentService.editSessionId = undefined); + } + + this.configurationService.onDidChangeConfiguration((e) => { + if (e.affectsConfiguration(experimentalSettingName)) { + this.registerActions(); + } + }); + + this.registerActions(); + + continueEditSessionExtPoint.setHandler(extensions => { + const continueEditSessionOptions: ContinueEditSessionItem[] = []; + for (const extension of extensions) { + if (!isProposedApiEnabled(extension.description, 'contribEditSessions')) { + continue; + } + if (!Array.isArray(extension.value)) { + continue; + } + const commands = new Map((extension.description.contributes?.commands ?? []).map(c => [c.command, c])); + for (const contribution of extension.value) { + if (!contribution.command || !contribution.group || !contribution.when) { + continue; + } + const fullCommand = commands.get(contribution.command); + if (!fullCommand) { return; } + + continueEditSessionOptions.push(new ContinueEditSessionItem( + fullCommand.title, + fullCommand.command, + ContextKeyExpr.deserialize(contribution.when) + )); + } + } + this.continueEditSessionOptions = continueEditSessionOptions; + }); + } + + private registerActions() { + if (this.registered || this.configurationService.getValue(experimentalSettingName) !== true) { + this.logService.info(`Skipping registering edit sessions actions as edit sessions are currently disabled. Set ${experimentalSettingName} to enable edit sessions.`); + return; + } + + this.registerContinueEditSessionAction(); + + this.registerApplyLatestEditSessionAction(); + this.registerStoreLatestEditSessionAction(); + + this.registerContinueInLocalFolderAction(); + + this.registered = true; + } + + private registerContinueEditSessionAction() { + const that = this; + this._register(registerAction2(class ContinueEditSessionAction extends Action2 { + constructor() { + super(continueEditSessionCommand); + } + + async run(accessor: ServicesAccessor, workspaceUri: URI | undefined): Promise { + let uri = workspaceUri ?? await that.pickContinueEditSessionDestination(); + if (uri === undefined) { return; } + + // Run the store action to get back a ref + const ref = await that.storeEditSession(false); + + // Append the ref to the URI + if (ref !== undefined) { + const encodedRef = encodeURIComponent(ref); + uri = uri.with({ + query: uri.query.length > 0 ? (uri + `&${queryParamName}=${encodedRef}`) : `${queryParamName}=${encodedRef}` + }); + } else { + that.logService.warn(`Failed to store edit session when invoking ${continueEditSessionCommand.id}.`); + } + + // Open the URI + that.logService.info(`Opening ${uri.toString()}`); + await that.openerService.open(uri, { openExternal: true }); + } + })); + } + + private registerApplyLatestEditSessionAction(): void { + const that = this; + this._register(registerAction2(class ApplyLatestEditSessionAction extends Action2 { + constructor() { + super({ + id: 'workbench.experimental.editSessions.actions.resumeLatest', + title: { value: localize('resume latest.v2', "Resume Latest Edit Session"), original: 'Resume Latest Edit Session' }, + category: EDIT_SESSION_SYNC_CATEGORY, + f1: true, + }); + } + + async run(accessor: ServicesAccessor): Promise { + await that.progressService.withProgress({ + location: ProgressLocation.Notification, + title: localize('applying edit session', 'Applying edit session...') + }, async () => await that.applyEditSession()); + } + })); + } + + private registerStoreLatestEditSessionAction(): void { + const that = this; + this._register(registerAction2(class StoreLatestEditSessionAction extends Action2 { + constructor() { + super({ + id: 'workbench.experimental.editSessions.actions.storeCurrent', + title: { value: localize('store current.v2', "Store Current Edit Session"), original: 'Store Current Edit Session' }, + category: EDIT_SESSION_SYNC_CATEGORY, + f1: true, + }); + } + + async run(accessor: ServicesAccessor): Promise { + await that.progressService.withProgress({ + location: ProgressLocation.Notification, + title: localize('storing edit session', 'Storing edit session...') + }, async () => await that.storeEditSession(true)); + } + })); + } + + async applyEditSession(ref?: string): Promise { + if (ref !== undefined) { + this.logService.info(`Applying edit session with ref ${ref}.`); + } + + const data = await this.editSessionsWorkbenchService.read(ref); + if (!data) { + if (ref === undefined) { + this.notificationService.info(localize('no edit session', 'There are no edit sessions to apply.')); + } else { + this.notificationService.warn(localize('no edit session content for ref', 'Could not apply edit session contents for ID {0}.', ref)); + } + this.logService.info(`Aborting applying edit session as no edit session content is available to be applied from ref ${ref}.`); + return; + } + const editSession = data.editSession; + ref = data.ref; + + if (editSession.version > EditSessionSchemaVersion) { + this.notificationService.error(localize('client too old', "Please upgrade to a newer version of {0} to apply this edit session.", this.productService.nameLong)); + return; + } + + try { + const changes: ({ uri: URI; type: ChangeType; contents: string | undefined })[] = []; + let hasLocalUncommittedChanges = false; + + for (const folder of editSession.folders) { + const folderRoot = this.contextService.getWorkspace().folders.find((f) => f.name === folder.name); + if (!folderRoot) { + this.logService.info(`Skipping applying ${folder.workingChanges.length} changes from edit session with ref ${ref} as no corresponding workspace folder named ${folder.name} is currently open.`); + continue; + } + + for (const repository of this.scmService.repositories) { + if (repository.provider.rootUri !== undefined && + this.contextService.getWorkspaceFolder(repository.provider.rootUri)?.name === folder.name && + this.getChangedResources(repository).length > 0 + ) { + hasLocalUncommittedChanges = true; + break; + } + } + + for (const { relativeFilePath, contents, type } of folder.workingChanges) { + const uri = joinPath(folderRoot.uri, relativeFilePath); + changes.push({ uri: uri, type: type, contents: contents }); + } + } + + if (hasLocalUncommittedChanges) { + // TODO@joyceerhl Provide the option to diff files which would be overwritten by edit session contents + const result = await this.dialogService.confirm({ + message: localize('apply edit session warning', 'Applying your edit session may overwrite your existing uncommitted changes. Do you want to proceed?'), + type: 'warning', + title: EDIT_SESSION_SYNC_CATEGORY.value + }); + if (!result.confirmed) { + return; + } + } + + for (const { uri, type, contents } of changes) { + if (type === ChangeType.Addition) { + await this.fileService.writeFile(uri, VSBuffer.fromString(contents!)); + } else if (type === ChangeType.Deletion && await this.fileService.exists(uri)) { + await this.fileService.del(uri); + } + } + + this.logService.info(`Deleting edit session with ref ${ref} after successfully applying it to current workspace...`); + await this.editSessionsWorkbenchService.delete(ref); + this.logService.info(`Deleted edit session with ref ${ref}.`); + } catch (ex) { + this.logService.error('Failed to apply edit session, reason: ', (ex as Error).toString()); + this.notificationService.error(localize('apply failed', "Failed to apply your edit session.")); + } + } + + async storeEditSession(fromStoreCommand: boolean): Promise { + const folders: Folder[] = []; + let hasEdits = false; + + for (const repository of this.scmService.repositories) { + // Look through all resource groups and compute which files were added/modified/deleted + const trackedUris = this.getChangedResources(repository); // A URI might appear in more than one resource group + + const workingChanges: Change[] = []; + let name = repository.provider.rootUri ? this.contextService.getWorkspaceFolder(repository.provider.rootUri)?.name : undefined; + + for (const uri of trackedUris) { + const workspaceFolder = this.contextService.getWorkspaceFolder(uri); + if (!workspaceFolder) { + this.logService.info(`Skipping working change ${uri.toString()} as no associated workspace folder was found.`); + + continue; + } + + name = name ?? workspaceFolder.name; + const relativeFilePath = relativePath(workspaceFolder.uri, uri) ?? uri.path; + + // Only deal with file contents for now + try { + if (!(await this.fileService.stat(uri)).isFile) { + continue; + } + } catch { } + + hasEdits = true; + + if (await this.fileService.exists(uri)) { + workingChanges.push({ type: ChangeType.Addition, fileType: FileType.File, contents: (await this.fileService.readFile(uri)).value.toString(), relativeFilePath: relativeFilePath }); + } else { + // Assume it's a deletion + workingChanges.push({ type: ChangeType.Deletion, fileType: FileType.File, contents: undefined, relativeFilePath: relativeFilePath }); + } + } + + folders.push({ workingChanges, name: name ?? '' }); + } + + if (!hasEdits) { + this.logService.info('Skipping storing edit session as there are no edits to store.'); + if (fromStoreCommand) { + this.notificationService.info(localize('no edits to store', 'Skipped storing edit session as there are no edits to store.')); + } + return undefined; + } + + const data: EditSession = { folders, version: 1 }; + + try { + this.logService.info(`Storing edit session...`); + const ref = await this.editSessionsWorkbenchService.write(data); + this.logService.info(`Stored edit session with ref ${ref}.`); + return ref; + } catch (ex) { + this.logService.error(`Failed to store edit session, reason: `, (ex as Error).toString()); + + type UploadFailedEvent = { reason: string }; + type UploadFailedClassification = { + owner: 'joyceerhl'; comment: 'Reporting when Continue On server request fails.'; + reason?: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The reason that the server request failed.' }; + }; + + if (ex instanceof UserDataSyncStoreError) { + switch (ex.code) { + case UserDataSyncErrorCode.TooLarge: + // Uploading a payload can fail due to server size limits + this.telemetryService.publicLog2('editSessions.upload.failed', { reason: 'TooLarge' }); + this.notificationService.error(localize('payload too large', 'Your edit session exceeds the size limit and cannot be stored.')); + break; + default: + this.telemetryService.publicLog2('editSessions.upload.failed', { reason: 'unknown' }); + this.notificationService.error(localize('payload failed', 'Your edit session cannot be stored.')); + break; + } + } + } + + return undefined; + } + + private getChangedResources(repository: ISCMRepository) { + const trackedUris = repository.provider.groups.elements.reduce((resources, resourceGroups) => { + resourceGroups.elements.forEach((resource) => resources.add(resource.sourceUri)); + return resources; + }, new Set()); // A URI might appear in more than one resource group + + return [...trackedUris]; + } + + //#region Continue Edit Session extension contribution point + + private registerContinueInLocalFolderAction(): void { + const that = this; + this._register(registerAction2(class ContinueInLocalFolderAction extends Action2 { + constructor() { + super(openLocalFolderCommand); + } + + async run(accessor: ServicesAccessor): Promise { + const selection = await that.fileDialogService.showOpenDialog({ + title: localize('continueEditSession.openLocalFolder.title', 'Select a local folder to continue your edit session in'), + canSelectFolders: true, + canSelectMany: false, + canSelectFiles: false, + availableFileSystems: [Schemas.file] + }); + + return selection?.length !== 1 ? undefined : URI.from({ + scheme: that.productService.urlProtocol, + authority: Schemas.file, + path: selection[0].path + }); + } + })); + } + + private async pickContinueEditSessionDestination(): Promise { + const quickPick = this.quickInputService.createQuickPick(); + + quickPick.title = localize('continueEditSessionPick.title', 'Continue Edit Session...'); + quickPick.placeholder = localize('continueEditSessionPick.placeholder', 'Choose how you would like to continue working'); + quickPick.items = this.createPickItems(); + + const command = await new Promise((resolve, reject) => { + quickPick.onDidHide(() => resolve(undefined)); + + quickPick.onDidAccept((e) => { + const selection = quickPick.activeItems[0].command; + resolve(selection); + quickPick.hide(); + }); + + quickPick.show(); + }); + + quickPick.dispose(); + + if (command === undefined) { + return undefined; + } + + try { + const uri = await this.commandService.executeCommand(command); + return URI.isUri(uri) ? uri : undefined; + } catch (ex) { + return undefined; + } + } + + private createPickItems(): ContinueEditSessionItem[] { + const items = [...this.continueEditSessionOptions].filter((option) => option.when === undefined || this.contextKeyService.contextMatchesRules(option.when)); + + if (getVirtualWorkspaceLocation(this.contextService.getWorkspace()) !== undefined) { + items.push(new ContinueEditSessionItem( + localize('continueEditSessionItem.openInLocalFolder', 'Open In Local Folder'), + openLocalFolderCommand.id, + )); + } + + return items; + } +} + +class ContinueEditSessionItem implements IQuickPickItem { + constructor( + public readonly label: string, + public readonly command: string, + public readonly when?: ContextKeyExpression, + ) { } +} + +interface ICommand { + command: string; + group: string; + when: string; +} + +const continueEditSessionExtPoint = ExtensionsRegistry.registerExtensionPoint({ + extensionPoint: 'continueEditSession', + jsonSchema: { + description: localize('continueEditSessionExtPoint', 'Contributes options for continuing the current edit session in a different environment'), + type: 'array', + items: { + type: 'object', + properties: { + command: { + description: localize('continueEditSessionExtPoint.command', 'Identifier of the command to execute. The command must be declared in the \'commands\'-section and return a URI representing a different environment where the current edit session can be continued.'), + type: 'string' + }, + group: { + description: localize('continueEditSessionExtPoint.group', 'Group into which this item belongs.'), + type: 'string' + }, + when: { + description: localize('continueEditSessionExtPoint.when', 'Condition which must be true to show this item.'), + type: 'string' + } + }, + required: ['command'] + } + } +}); + +//#endregion + +const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); +workbenchRegistry.registerWorkbenchContribution(EditSessionsContribution, LifecyclePhase.Restored); + +Registry.as(Extensions.Configuration).registerConfiguration({ + ...workbenchConfigurationNodeBase, + 'properties': { + 'workbench.experimental.editSessions.enabled': { + 'type': 'boolean', + 'tags': ['experimental', 'usesOnlineServices'], + 'default': false, + 'markdownDescription': localize('editSessionsEnabled', "Controls whether to display cloud-enabled actions to store and resume uncommitted changes when switching between web, desktop, or devices."), + }, + } +}); diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts b/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts new file mode 100644 index 00000000000..af25b5ee15a --- /dev/null +++ b/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts @@ -0,0 +1,358 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable } from 'vs/base/common/lifecycle'; +import { URI } from 'vs/base/common/uri'; +import { localize } from 'vs/nls'; +import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; +import { ContextKeyExpr, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IFileService } from 'vs/platform/files/common/files'; +import { IProductService } from 'vs/platform/product/common/productService'; +import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; +import { IRequestService } from 'vs/platform/request/common/request'; +import { IStorageService, IStorageValueChangeEvent, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; +import { IAuthenticationProvider } from 'vs/platform/userDataSync/common/userDataSync'; +import { UserDataSyncStoreClient } from 'vs/platform/userDataSync/common/userDataSyncStoreService'; +import { AuthenticationSession, AuthenticationSessionsChangeEvent, IAuthenticationService } from 'vs/workbench/services/authentication/common/authentication'; +import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { EDIT_SESSIONS_SIGNED_IN, EditSession, EDIT_SESSION_SYNC_CATEGORY, IEditSessionsWorkbenchService, EDIT_SESSIONS_SIGNED_IN_KEY, IEditSessionsLogService } from 'vs/workbench/contrib/editSessions/common/editSessions'; + +type ExistingSession = IQuickPickItem & { session: AuthenticationSession & { providerId: string } }; +type AuthenticationProviderOption = IQuickPickItem & { provider: IAuthenticationProvider }; + +export class EditSessionsWorkbenchService extends Disposable implements IEditSessionsWorkbenchService { + + _serviceBrand = undefined; + + private serverConfiguration = this.productService['editSessions.store']; + private storeClient: UserDataSyncStoreClient | undefined; + + #authenticationInfo: { sessionId: string; token: string; providerId: string } | undefined; + private static CACHED_SESSION_STORAGE_KEY = 'editSessionAccountPreference'; + + private initialized = false; + private readonly signedInContext: IContextKey; + + constructor( + @IFileService private readonly fileService: IFileService, + @IStorageService private readonly storageService: IStorageService, + @IQuickInputService private readonly quickInputService: IQuickInputService, + @IAuthenticationService private readonly authenticationService: IAuthenticationService, + @IExtensionService private readonly extensionService: IExtensionService, + @IEnvironmentService private readonly environmentService: IEnvironmentService, + @IEditSessionsLogService private readonly logService: IEditSessionsLogService, + @IProductService private readonly productService: IProductService, + @IContextKeyService private readonly contextKeyService: IContextKeyService, + @IRequestService private readonly requestService: IRequestService, + ) { + super(); + + // If the user signs out of the current session, reset our cached auth state in memory and on disk + this._register(this.authenticationService.onDidChangeSessions((e) => this.onDidChangeSessions(e.event))); + + // If another window changes the preferred session storage, reset our cached auth state in memory + this._register(this.storageService.onDidChangeValue(e => this.onDidChangeStorage(e))); + + this.registerResetAuthenticationAction(); + + this.signedInContext = EDIT_SESSIONS_SIGNED_IN.bindTo(this.contextKeyService); + this.signedInContext.set(this.existingSessionId !== undefined); + } + + /** + * + * @param editSession An object representing edit session state to be restored. + * @returns The ref of the stored edit session state. + */ + async write(editSession: EditSession): Promise { + await this.initialize(); + if (!this.initialized) { + throw new Error('Please sign in to store your edit session.'); + } + + return this.storeClient!.write('editSessions', JSON.stringify(editSession), null); + } + + /** + * @param ref: A specific content ref to retrieve content for, if it exists. + * If undefined, this method will return the latest saved edit session, if any. + * + * @returns An object representing the requested or latest edit session state, if any. + */ + async read(ref: string | undefined): Promise<{ ref: string; editSession: EditSession } | undefined> { + await this.initialize(); + if (!this.initialized) { + throw new Error('Please sign in to apply your latest edit session.'); + } + + let content: string | undefined | null; + try { + if (ref !== undefined) { + content = await this.storeClient?.resolveContent('editSessions', ref); + } else { + const result = await this.storeClient?.read('editSessions', null); + content = result?.content; + ref = result?.ref; + } + } catch (ex) { + this.logService.error(ex); + } + + // TODO@joyceerhl Validate session data, check schema version + return (content !== undefined && content !== null && ref !== undefined) ? { ref: ref, editSession: JSON.parse(content) } : undefined; + } + + async delete(ref: string) { + await this.initialize(); + if (!this.initialized) { + throw new Error(`Unable to delete edit session with ref ${ref}.`); + } + + try { + await this.storeClient?.delete('editSessions', ref); + } catch (ex) { + this.logService.error(ex); + } + } + + private async initialize() { + if (this.initialized) { + return; + } + this.initialized = await this.doInitialize(); + this.signedInContext.set(this.initialized); + } + + /** + * + * Ensures that the store client is initialized, + * meaning that authentication is configured and it + * can be used to communicate with the remote storage service + */ + private async doInitialize(): Promise { + // Wait for authentication extensions to be registered + await this.extensionService.whenInstalledExtensionsRegistered(); + + if (!this.serverConfiguration?.url) { + throw new Error('Unable to initialize sessions sync as session sync preference is not configured in product.json.'); + } + + if (!this.storeClient) { + this.storeClient = new UserDataSyncStoreClient(URI.parse(this.serverConfiguration.url), this.productService, this.requestService, this.logService, this.environmentService, this.fileService, this.storageService); + this._register(this.storeClient.onTokenFailed(() => { + this.logService.info('Clearing edit sessions authentication preference because of successive token failures.'); + this.clearAuthenticationPreference(); + })); + } + + // If we already have an existing auth session in memory, use that + if (this.#authenticationInfo !== undefined) { + return true; + } + + // If the user signed in previously and the session is still available, reuse that without prompting the user again + const existingSessionId = this.existingSessionId; + if (existingSessionId) { + this.logService.trace(`Searching for existing authentication session with ID ${existingSessionId}`); + const existing = await this.getExistingSession(); + if (existing !== undefined) { + this.logService.trace(`Found existing authentication session with ID ${existingSessionId}`); + this.#authenticationInfo = { sessionId: existing.session.id, token: existing.session.accessToken, providerId: existing.session.providerId }; + this.storeClient.setAuthToken(this.#authenticationInfo.token, this.#authenticationInfo.providerId); + return true; + } + } + + // Ask the user to pick a preferred account + const session = await this.getAccountPreference(); + if (session !== undefined) { + this.#authenticationInfo = { sessionId: session.id, token: session.accessToken, providerId: session.providerId }; + this.storeClient.setAuthToken(this.#authenticationInfo.token, this.#authenticationInfo.providerId); + this.existingSessionId = session.id; + this.logService.trace(`Saving authentication session preference for ID ${session.id}.`); + return true; + } + + return false; + } + + /** + * + * Prompts the user to pick an authentication option for storing and getting edit sessions. + */ + private async getAccountPreference(): Promise { + const quickpick = this.quickInputService.createQuickPick(); + quickpick.title = localize('account preference', 'Sign In to Use Edit Sessions'); + quickpick.ok = false; + quickpick.placeholder = localize('choose account placeholder', "Select an account to sign in"); + quickpick.ignoreFocusOut = true; + quickpick.items = await this.createQuickpickItems(); + + return new Promise((resolve, reject) => { + quickpick.onDidHide((e) => { + resolve(undefined); + quickpick.dispose(); + }); + + quickpick.onDidAccept(async (e) => { + const selection = quickpick.selectedItems[0]; + const session = 'provider' in selection ? { ...await this.authenticationService.createSession(selection.provider.id, selection.provider.scopes), providerId: selection.provider.id } : selection.session; + resolve(session); + quickpick.hide(); + }); + + quickpick.show(); + }); + } + + private async createQuickpickItems(): Promise<(ExistingSession | AuthenticationProviderOption | IQuickPickSeparator)[]> { + const options: (ExistingSession | AuthenticationProviderOption | IQuickPickSeparator)[] = []; + + options.push({ type: 'separator', label: localize('signed in', "Signed In") }); + + const sessions = await this.getAllSessions(); + options.push(...sessions); + + options.push({ type: 'separator', label: localize('others', "Others") }); + + for (const authenticationProvider of (await this.getAuthenticationProviders())) { + const signedInForProvider = sessions.some(account => account.session.providerId === authenticationProvider.id); + if (!signedInForProvider || this.authenticationService.supportsMultipleAccounts(authenticationProvider.id)) { + const providerName = this.authenticationService.getLabel(authenticationProvider.id); + options.push({ label: localize('sign in using account', "Sign in with {0}", providerName), provider: authenticationProvider }); + } + } + + return options; + } + + /** + * + * Returns all authentication sessions available from {@link getAuthenticationProviders}. + */ + private async getAllSessions() { + const authenticationProviders = await this.getAuthenticationProviders(); + const accounts = new Map(); + let currentSession: ExistingSession | undefined; + + for (const provider of authenticationProviders) { + const sessions = await this.authenticationService.getSessions(provider.id, provider.scopes); + + for (const session of sessions) { + const item = { + label: session.account.label, + description: this.authenticationService.getLabel(provider.id), + session: { ...session, providerId: provider.id } + }; + accounts.set(item.session.account.id, item); + if (this.existingSessionId === session.id) { + currentSession = item; + } + } + } + + if (currentSession !== undefined) { + accounts.set(currentSession.session.account.id, currentSession); + } + + return [...accounts.values()]; + } + + /** + * + * Returns all authentication providers which can be used to authenticate + * to the remote storage service, based on product.json configuration + * and registered authentication providers. + */ + private async getAuthenticationProviders() { + if (!this.serverConfiguration) { + throw new Error('Unable to get configured authentication providers as session sync preference is not configured in product.json.'); + } + + // Get the list of authentication providers configured in product.json + const authenticationProviders = this.serverConfiguration.authenticationProviders; + const configuredAuthenticationProviders = Object.keys(authenticationProviders).reduce((result, id) => { + result.push({ id, scopes: authenticationProviders[id].scopes }); + return result; + }, []); + + // Filter out anything that isn't currently available through the authenticationService + const availableAuthenticationProviders = this.authenticationService.declaredProviders; + + return configuredAuthenticationProviders.filter(({ id }) => availableAuthenticationProviders.some(provider => provider.id === id)); + } + + private get existingSessionId() { + return this.storageService.get(EditSessionsWorkbenchService.CACHED_SESSION_STORAGE_KEY, StorageScope.APPLICATION); + } + + private set existingSessionId(sessionId: string | undefined) { + if (sessionId === undefined) { + this.storageService.remove(EditSessionsWorkbenchService.CACHED_SESSION_STORAGE_KEY, StorageScope.APPLICATION); + } else { + this.storageService.store(EditSessionsWorkbenchService.CACHED_SESSION_STORAGE_KEY, sessionId, StorageScope.APPLICATION, StorageTarget.MACHINE); + } + } + + private async getExistingSession() { + const accounts = await this.getAllSessions(); + return accounts.find((account) => account.session.id === this.existingSessionId); + } + + private async onDidChangeStorage(e: IStorageValueChangeEvent): Promise { + if (e.key === EditSessionsWorkbenchService.CACHED_SESSION_STORAGE_KEY + && e.scope === StorageScope.APPLICATION + ) { + const newSessionId = this.existingSessionId; + const previousSessionId = this.#authenticationInfo?.sessionId; + + if (previousSessionId !== newSessionId) { + this.logService.trace(`Resetting authentication state because authentication session ID preference changed from ${previousSessionId} to ${newSessionId}.`); + this.#authenticationInfo = undefined; + this.initialized = false; + } + } + } + + private clearAuthenticationPreference(): void { + this.#authenticationInfo = undefined; + this.initialized = false; + this.existingSessionId = undefined; + this.signedInContext.set(false); + } + + private onDidChangeSessions(e: AuthenticationSessionsChangeEvent): void { + if (this.#authenticationInfo?.sessionId && e.removed.find(session => session.id === this.#authenticationInfo?.sessionId)) { + this.clearAuthenticationPreference(); + } + } + + private registerResetAuthenticationAction() { + const that = this; + this._register(registerAction2(class ResetEditSessionAuthenticationAction extends Action2 { + constructor() { + super({ + id: 'workbench.editSessions.actions.resetAuth', + title: localize('reset auth', 'Sign Out'), + category: EDIT_SESSION_SYNC_CATEGORY, + precondition: ContextKeyExpr.equals(EDIT_SESSIONS_SIGNED_IN_KEY, true), + menu: [{ + id: MenuId.CommandPalette, + }, + { + id: MenuId.AccountsContext, + group: '2_editSessions', + when: ContextKeyExpr.equals(EDIT_SESSIONS_SIGNED_IN_KEY, true), + }] + }); + } + + run() { + that.clearAuthenticationPreference(); + } + })); + } +} diff --git a/src/vs/workbench/contrib/editSessions/common/editSessions.ts b/src/vs/workbench/contrib/editSessions/common/editSessions.ts new file mode 100644 index 00000000000..789976a50e5 --- /dev/null +++ b/src/vs/workbench/contrib/editSessions/common/editSessions.ts @@ -0,0 +1,67 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize } from 'vs/nls'; +import { ILocalizedString } from 'vs/platform/action/common/action'; +import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { ILogService } from 'vs/platform/log/common/log'; + +export const EDIT_SESSION_SYNC_CATEGORY: ILocalizedString = { + original: 'Edit Sessions', + value: localize('session sync', 'Edit Sessions') +}; + +export const IEditSessionsWorkbenchService = createDecorator('IEditSessionsWorkbenchService'); +export interface IEditSessionsWorkbenchService { + _serviceBrand: undefined; + + read(ref: string | undefined): Promise<{ ref: string; editSession: EditSession } | undefined>; + write(editSession: EditSession): Promise; + delete(ref: string): Promise; +} + +export const IEditSessionsLogService = createDecorator('IEditSessionsLogService'); +export interface IEditSessionsLogService extends ILogService { } + +export enum ChangeType { + Addition = 1, + Deletion = 2, +} + +export enum FileType { + File = 1, +} + +interface Addition { + relativeFilePath: string; + fileType: FileType.File; + contents: string; + type: ChangeType.Addition; +} + +interface Deletion { + relativeFilePath: string; + fileType: FileType.File; + contents: undefined; + type: ChangeType.Deletion; +} + +export type Change = Addition | Deletion; + +export interface Folder { + name: string; + workingChanges: Change[]; +} + +export const EditSessionSchemaVersion = 1; + +export interface EditSession { + version: number; + folders: Folder[]; +} + +export const EDIT_SESSIONS_SIGNED_IN_KEY = 'editSessionsSignedIn'; +export const EDIT_SESSIONS_SIGNED_IN = new RawContextKey(EDIT_SESSIONS_SIGNED_IN_KEY, false); diff --git a/src/vs/workbench/contrib/editSessions/common/editSessionsLogService.ts b/src/vs/workbench/contrib/editSessions/common/editSessionsLogService.ts new file mode 100644 index 00000000000..a18c9e29304 --- /dev/null +++ b/src/vs/workbench/contrib/editSessions/common/editSessionsLogService.ts @@ -0,0 +1,50 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { AbstractLogger, ILogger, ILoggerService } from 'vs/platform/log/common/log'; +import { IEditSessionsLogService } from 'vs/workbench/contrib/editSessions/common/editSessions'; + +export class EditSessionsLogService extends AbstractLogger implements IEditSessionsLogService { + + declare readonly _serviceBrand: undefined; + private readonly logger: ILogger; + + constructor( + @ILoggerService loggerService: ILoggerService, + @IEnvironmentService environmentService: IEnvironmentService + ) { + super(); + this.logger = this._register(loggerService.createLogger(environmentService.editSessionsLogResource, { name: 'editsessions' })); + } + + trace(message: string, ...args: any[]): void { + this.logger.trace(message, ...args); + } + + debug(message: string, ...args: any[]): void { + this.logger.debug(message, ...args); + } + + info(message: string, ...args: any[]): void { + this.logger.info(message, ...args); + } + + warn(message: string, ...args: any[]): void { + this.logger.warn(message, ...args); + } + + error(message: string | Error, ...args: any[]): void { + this.logger.error(message, ...args); + } + + critical(message: string | Error, ...args: any[]): void { + this.logger.critical(message, ...args); + } + + flush(): void { + this.logger.flush(); + } +} diff --git a/src/vs/workbench/contrib/editSessions/test/browser/editSessions.test.ts b/src/vs/workbench/contrib/editSessions/test/browser/editSessions.test.ts new file mode 100644 index 00000000000..b7caca6f077 --- /dev/null +++ b/src/vs/workbench/contrib/editSessions/test/browser/editSessions.test.ts @@ -0,0 +1,134 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { DisposableStore } from 'vs/base/common/lifecycle'; +import { IFileService } from 'vs/platform/files/common/files'; +import { FileService } from 'vs/platform/files/common/fileService'; +import { Schemas } from 'vs/base/common/network'; +import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider'; +import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; +import { NullLogService } from 'vs/platform/log/common/log'; +import { EditSessionsContribution } from 'vs/workbench/contrib/editSessions/browser/editSessions.contribution'; +import { ProgressService } from 'vs/workbench/services/progress/browser/progressService'; +import { IProgressService } from 'vs/platform/progress/common/progress'; +import { ISCMService } from 'vs/workbench/contrib/scm/common/scm'; +import { SCMService } from 'vs/workbench/contrib/scm/common/scmService'; +import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { mock } from 'vs/base/test/common/mock'; +import * as sinon from 'sinon'; +import * as assert from 'assert'; +import { ChangeType, FileType, IEditSessionsLogService, IEditSessionsWorkbenchService } from 'vs/workbench/contrib/editSessions/common/editSessions'; +import { URI } from 'vs/base/common/uri'; +import { joinPath } from 'vs/base/common/resources'; +import { INotificationService } from 'vs/platform/notification/common/notification'; +import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; +import { TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; + +const folderName = 'test-folder'; +const folderUri = URI.file(`/${folderName}`); + +suite('Edit session sync', () => { + let instantiationService: TestInstantiationService; + let editSessionsContribution: EditSessionsContribution; + let fileService: FileService; + let sandbox: sinon.SinonSandbox; + + const disposables = new DisposableStore(); + + suiteSetup(() => { + sandbox = sinon.createSandbox(); + + instantiationService = new TestInstantiationService(); + + // Set up filesystem + const logService = new NullLogService(); + fileService = disposables.add(new FileService(logService)); + const fileSystemProvider = disposables.add(new InMemoryFileSystemProvider()); + fileService.registerProvider(Schemas.file, fileSystemProvider); + + // Stub out all services + instantiationService.stub(IEditSessionsLogService, logService); + instantiationService.stub(IFileService, fileService); + instantiationService.stub(INotificationService, new TestNotificationService()); + instantiationService.stub(IEditSessionsWorkbenchService, new class extends mock() { }); + instantiationService.stub(IProgressService, ProgressService); + instantiationService.stub(ISCMService, SCMService); + instantiationService.stub(IEnvironmentService, TestEnvironmentService); + instantiationService.stub(IConfigurationService, new TestConfigurationService({ workbench: { experimental: { editSessions: { enabled: true } } } })); + instantiationService.stub(IWorkspaceContextService, new class extends mock() { + override getWorkspace() { + return { + id: 'workspace-id', + folders: [{ + uri: folderUri, + name: folderName, + index: 0, + toResource: (relativePath: string) => joinPath(folderUri, relativePath) + }] + }; + } + }); + + // Stub repositories + instantiationService.stub(ISCMService, '_repositories', new Map()); + + editSessionsContribution = instantiationService.createInstance(EditSessionsContribution); + }); + + teardown(() => { + sinon.restore(); + disposables.clear(); + }); + + test('Can apply edit session', async function () { + const fileUri = joinPath(folderUri, 'dir1', 'README.md'); + const fileContents = '# readme'; + const editSession = { + version: 1, + folders: [ + { + name: folderName, + workingChanges: [ + { + relativeFilePath: 'dir1/README.md', + fileType: FileType.File, + contents: fileContents, + type: ChangeType.Addition + } + ] + } + ] + }; + + // Stub sync service to return edit session data + const readStub = sandbox.stub().returns({ editSession, ref: '0' }); + instantiationService.stub(IEditSessionsWorkbenchService, 'read', readStub); + + // Create root folder + await fileService.createFolder(folderUri); + + // Apply edit session + await editSessionsContribution.applyEditSession(); + + // Verify edit session was correctly applied + assert.equal((await fileService.readFile(fileUri)).value.toString(), fileContents); + }); + + test('Edit session not stored if there are no edits', async function () { + const writeStub = sandbox.stub(); + instantiationService.stub(IEditSessionsWorkbenchService, 'write', writeStub); + + // Create root folder + await fileService.createFolder(folderUri); + + await editSessionsContribution.storeEditSession(true); + + // Verify that we did not attempt to write the edit session + assert.equal(writeStub.called, false); + }); +}); diff --git a/src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts b/src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts deleted file mode 100644 index a4cf8be1f5f..00000000000 --- a/src/vs/workbench/contrib/sessionSync/browser/sessionSync.contribution.ts +++ /dev/null @@ -1,517 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Disposable } from 'vs/base/common/lifecycle'; -import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; -import { Action2, IAction2Options, registerAction2 } from 'vs/platform/actions/common/actions'; -import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; -import { localize } from 'vs/nls'; -import { ISessionSyncWorkbenchService, Change, ChangeType, Folder, EditSession, FileType, EDIT_SESSION_SYNC_CATEGORY, EditSessionSchemaVersion, IEditSessionsLogService } from 'vs/workbench/contrib/sessionSync/common/sessionSync'; -import { ISCMRepository, ISCMService } from 'vs/workbench/contrib/scm/common/scm'; -import { IFileService } from 'vs/platform/files/common/files'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { URI } from 'vs/base/common/uri'; -import { joinPath, relativePath } from 'vs/base/common/resources'; -import { VSBuffer } from 'vs/base/common/buffer'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress'; -import { SessionSyncWorkbenchService } from 'vs/workbench/contrib/sessionSync/browser/sessionSyncWorkbenchService'; -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { UserDataSyncErrorCode, UserDataSyncStoreError } from 'vs/platform/userDataSync/common/userDataSync'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { INotificationService } from 'vs/platform/notification/common/notification'; -import { IDialogService, IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; -import { IProductService } from 'vs/platform/product/common/productService'; -import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration'; -import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; -import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; -import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry'; -import { ContextKeyExpr, ContextKeyExpression, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { ICommandService } from 'vs/platform/commands/common/commands'; -import { getVirtualWorkspaceLocation } from 'vs/platform/workspace/common/virtualWorkspace'; -import { Schemas } from 'vs/base/common/network'; -import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys'; -import { isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; -import { EditSessionsLogService } from 'vs/workbench/contrib/sessionSync/common/editSessionsLogService'; - -registerSingleton(IEditSessionsLogService, EditSessionsLogService); -registerSingleton(ISessionSyncWorkbenchService, SessionSyncWorkbenchService); - -const continueEditSessionCommand: IAction2Options = { - id: '_workbench.experimental.editSessions.actions.continueEditSession', - title: { value: localize('continue edit session', "Continue Edit Session..."), original: 'Continue Edit Session...' }, - category: EDIT_SESSION_SYNC_CATEGORY, - f1: true -}; -const openLocalFolderCommand: IAction2Options = { - id: '_workbench.experimental.editSessions.actions.continueEditSession.openLocalFolder', - title: { value: localize('continue edit session in local folder', "Open In Local Folder"), original: 'Open In Local Folder' }, - category: EDIT_SESSION_SYNC_CATEGORY, - precondition: IsWebContext -}; -const queryParamName = 'editSessionId'; -const experimentalSettingName = 'workbench.experimental.editSessions.enabled'; - -export class SessionSyncContribution extends Disposable implements IWorkbenchContribution { - - private registered = false; - private continueEditSessionOptions: ContinueEditSessionItem[] = []; - - constructor( - @ISessionSyncWorkbenchService private readonly sessionSyncWorkbenchService: ISessionSyncWorkbenchService, - @IFileService private readonly fileService: IFileService, - @IProgressService private readonly progressService: IProgressService, - @IOpenerService private readonly openerService: IOpenerService, - @ITelemetryService private readonly telemetryService: ITelemetryService, - @ISCMService private readonly scmService: ISCMService, - @INotificationService private readonly notificationService: INotificationService, - @IDialogService private readonly dialogService: IDialogService, - @IEditSessionsLogService private readonly logService: IEditSessionsLogService, - @IEnvironmentService private readonly environmentService: IEnvironmentService, - @IProductService private readonly productService: IProductService, - @IConfigurationService private configurationService: IConfigurationService, - @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, - @IQuickInputService private readonly quickInputService: IQuickInputService, - @ICommandService private commandService: ICommandService, - @IContextKeyService private readonly contextKeyService: IContextKeyService, - @IFileDialogService private readonly fileDialogService: IFileDialogService - ) { - super(); - - if (this.environmentService.editSessionId !== undefined) { - void this.applyEditSession(this.environmentService.editSessionId).finally(() => this.environmentService.editSessionId = undefined); - } - - this.configurationService.onDidChangeConfiguration((e) => { - if (e.affectsConfiguration(experimentalSettingName)) { - this.registerActions(); - } - }); - - this.registerActions(); - - continueEditSessionExtPoint.setHandler(extensions => { - const continueEditSessionOptions: ContinueEditSessionItem[] = []; - for (const extension of extensions) { - if (!isProposedApiEnabled(extension.description, 'contribEditSessions')) { - continue; - } - if (!Array.isArray(extension.value)) { - continue; - } - const commands = new Map((extension.description.contributes?.commands ?? []).map(c => [c.command, c])); - for (const contribution of extension.value) { - if (!contribution.command || !contribution.group || !contribution.when) { - continue; - } - const fullCommand = commands.get(contribution.command); - if (!fullCommand) { return; } - - continueEditSessionOptions.push(new ContinueEditSessionItem( - fullCommand.title, - fullCommand.command, - ContextKeyExpr.deserialize(contribution.when) - )); - } - } - this.continueEditSessionOptions = continueEditSessionOptions; - }); - } - - private registerActions() { - if (this.registered || this.configurationService.getValue(experimentalSettingName) !== true) { - this.logService.info(`Skipping registering edit sessions actions as edit sessions are currently disabled. Set ${experimentalSettingName} to enable edit sessions.`); - return; - } - - this.registerContinueEditSessionAction(); - - this.registerApplyLatestEditSessionAction(); - this.registerStoreLatestEditSessionAction(); - - this.registerContinueInLocalFolderAction(); - - this.registered = true; - } - - private registerContinueEditSessionAction() { - const that = this; - this._register(registerAction2(class ContinueEditSessionAction extends Action2 { - constructor() { - super(continueEditSessionCommand); - } - - async run(accessor: ServicesAccessor, workspaceUri: URI | undefined): Promise { - let uri = workspaceUri ?? await that.pickContinueEditSessionDestination(); - if (uri === undefined) { return; } - - // Run the store action to get back a ref - const ref = await that.storeEditSession(false); - - // Append the ref to the URI - if (ref !== undefined) { - const encodedRef = encodeURIComponent(ref); - uri = uri.with({ - query: uri.query.length > 0 ? (uri + `&${queryParamName}=${encodedRef}`) : `${queryParamName}=${encodedRef}` - }); - } else { - that.logService.warn(`Failed to store edit session when invoking ${continueEditSessionCommand.id}.`); - } - - // Open the URI - that.logService.info(`Opening ${uri.toString()}`); - await that.openerService.open(uri, { openExternal: true }); - } - })); - } - - private registerApplyLatestEditSessionAction(): void { - const that = this; - this._register(registerAction2(class ApplyLatestEditSessionAction extends Action2 { - constructor() { - super({ - id: 'workbench.experimental.editSessions.actions.resumeLatest', - title: { value: localize('resume latest.v2', "Resume Latest Edit Session"), original: 'Resume Latest Edit Session' }, - category: EDIT_SESSION_SYNC_CATEGORY, - f1: true, - }); - } - - async run(accessor: ServicesAccessor): Promise { - await that.progressService.withProgress({ - location: ProgressLocation.Notification, - title: localize('applying edit session', 'Applying edit session...') - }, async () => await that.applyEditSession()); - } - })); - } - - private registerStoreLatestEditSessionAction(): void { - const that = this; - this._register(registerAction2(class StoreLatestEditSessionAction extends Action2 { - constructor() { - super({ - id: 'workbench.experimental.editSessions.actions.storeCurrent', - title: { value: localize('store current.v2', "Store Current Edit Session"), original: 'Store Current Edit Session' }, - category: EDIT_SESSION_SYNC_CATEGORY, - f1: true, - }); - } - - async run(accessor: ServicesAccessor): Promise { - await that.progressService.withProgress({ - location: ProgressLocation.Notification, - title: localize('storing edit session', 'Storing edit session...') - }, async () => await that.storeEditSession(true)); - } - })); - } - - async applyEditSession(ref?: string): Promise { - if (ref !== undefined) { - this.logService.info(`Applying edit session with ref ${ref}.`); - } - - const data = await this.sessionSyncWorkbenchService.read(ref); - if (!data) { - if (ref === undefined) { - this.notificationService.info(localize('no edit session', 'There are no edit sessions to apply.')); - } else { - this.notificationService.warn(localize('no edit session content for ref', 'Could not apply edit session contents for ID {0}.', ref)); - } - this.logService.info(`Aborting applying edit session as no edit session content is available to be applied from ref ${ref}.`); - return; - } - const editSession = data.editSession; - ref = data.ref; - - if (editSession.version > EditSessionSchemaVersion) { - this.notificationService.error(localize('client too old', "Please upgrade to a newer version of {0} to apply this edit session.", this.productService.nameLong)); - return; - } - - try { - const changes: ({ uri: URI; type: ChangeType; contents: string | undefined })[] = []; - let hasLocalUncommittedChanges = false; - - for (const folder of editSession.folders) { - const folderRoot = this.contextService.getWorkspace().folders.find((f) => f.name === folder.name); - if (!folderRoot) { - this.logService.info(`Skipping applying ${folder.workingChanges.length} changes from edit session with ref ${ref} as no corresponding workspace folder named ${folder.name} is currently open.`); - continue; - } - - for (const repository of this.scmService.repositories) { - if (repository.provider.rootUri !== undefined && - this.contextService.getWorkspaceFolder(repository.provider.rootUri)?.name === folder.name && - this.getChangedResources(repository).length > 0 - ) { - hasLocalUncommittedChanges = true; - break; - } - } - - for (const { relativeFilePath, contents, type } of folder.workingChanges) { - const uri = joinPath(folderRoot.uri, relativeFilePath); - changes.push({ uri: uri, type: type, contents: contents }); - } - } - - if (hasLocalUncommittedChanges) { - // TODO@joyceerhl Provide the option to diff files which would be overwritten by edit session contents - const result = await this.dialogService.confirm({ - message: localize('apply edit session warning', 'Applying your edit session may overwrite your existing uncommitted changes. Do you want to proceed?'), - type: 'warning', - title: EDIT_SESSION_SYNC_CATEGORY.value - }); - if (!result.confirmed) { - return; - } - } - - for (const { uri, type, contents } of changes) { - if (type === ChangeType.Addition) { - await this.fileService.writeFile(uri, VSBuffer.fromString(contents!)); - } else if (type === ChangeType.Deletion && await this.fileService.exists(uri)) { - await this.fileService.del(uri); - } - } - - this.logService.info(`Deleting edit session with ref ${ref} after successfully applying it to current workspace...`); - await this.sessionSyncWorkbenchService.delete(ref); - this.logService.info(`Deleted edit session with ref ${ref}.`); - } catch (ex) { - this.logService.error('Failed to apply edit session, reason: ', (ex as Error).toString()); - this.notificationService.error(localize('apply failed', "Failed to apply your edit session.")); - } - } - - async storeEditSession(fromStoreCommand: boolean): Promise { - const folders: Folder[] = []; - let hasEdits = false; - - for (const repository of this.scmService.repositories) { - // Look through all resource groups and compute which files were added/modified/deleted - const trackedUris = this.getChangedResources(repository); // A URI might appear in more than one resource group - - const workingChanges: Change[] = []; - let name = repository.provider.rootUri ? this.contextService.getWorkspaceFolder(repository.provider.rootUri)?.name : undefined; - - for (const uri of trackedUris) { - const workspaceFolder = this.contextService.getWorkspaceFolder(uri); - if (!workspaceFolder) { - this.logService.info(`Skipping working change ${uri.toString()} as no associated workspace folder was found.`); - - continue; - } - - name = name ?? workspaceFolder.name; - const relativeFilePath = relativePath(workspaceFolder.uri, uri) ?? uri.path; - - // Only deal with file contents for now - try { - if (!(await this.fileService.stat(uri)).isFile) { - continue; - } - } catch { } - - hasEdits = true; - - if (await this.fileService.exists(uri)) { - workingChanges.push({ type: ChangeType.Addition, fileType: FileType.File, contents: (await this.fileService.readFile(uri)).value.toString(), relativeFilePath: relativeFilePath }); - } else { - // Assume it's a deletion - workingChanges.push({ type: ChangeType.Deletion, fileType: FileType.File, contents: undefined, relativeFilePath: relativeFilePath }); - } - } - - folders.push({ workingChanges, name: name ?? '' }); - } - - if (!hasEdits) { - this.logService.info('Skipping storing edit session as there are no edits to store.'); - if (fromStoreCommand) { - this.notificationService.info(localize('no edits to store', 'Skipped storing edit session as there are no edits to store.')); - } - return undefined; - } - - const data: EditSession = { folders, version: 1 }; - - try { - this.logService.info(`Storing edit session...`); - const ref = await this.sessionSyncWorkbenchService.write(data); - this.logService.info(`Stored edit session with ref ${ref}.`); - return ref; - } catch (ex) { - this.logService.error(`Failed to store edit session, reason: `, (ex as Error).toString()); - - type UploadFailedEvent = { reason: string }; - type UploadFailedClassification = { - owner: 'joyceerhl'; comment: 'Reporting when Continue On server request fails.'; - reason?: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The reason that the server request failed.' }; - }; - - if (ex instanceof UserDataSyncStoreError) { - switch (ex.code) { - case UserDataSyncErrorCode.TooLarge: - // Uploading a payload can fail due to server size limits - this.telemetryService.publicLog2('sessionSync.upload.failed', { reason: 'TooLarge' }); - this.notificationService.error(localize('payload too large', 'Your edit session exceeds the size limit and cannot be stored.')); - break; - default: - this.telemetryService.publicLog2('sessionSync.upload.failed', { reason: 'unknown' }); - this.notificationService.error(localize('payload failed', 'Your edit session cannot be stored.')); - break; - } - } - } - - return undefined; - } - - private getChangedResources(repository: ISCMRepository) { - const trackedUris = repository.provider.groups.elements.reduce((resources, resourceGroups) => { - resourceGroups.elements.forEach((resource) => resources.add(resource.sourceUri)); - return resources; - }, new Set()); // A URI might appear in more than one resource group - - return [...trackedUris]; - } - - //#region Continue Edit Session extension contribution point - - private registerContinueInLocalFolderAction(): void { - const that = this; - this._register(registerAction2(class ContinueInLocalFolderAction extends Action2 { - constructor() { - super(openLocalFolderCommand); - } - - async run(accessor: ServicesAccessor): Promise { - const selection = await that.fileDialogService.showOpenDialog({ - title: localize('continueEditSession.openLocalFolder.title', 'Select a local folder to continue your edit session in'), - canSelectFolders: true, - canSelectMany: false, - canSelectFiles: false, - availableFileSystems: [Schemas.file] - }); - - return selection?.length !== 1 ? undefined : URI.from({ - scheme: that.productService.urlProtocol, - authority: Schemas.file, - path: selection[0].path - }); - } - })); - } - - private async pickContinueEditSessionDestination(): Promise { - const quickPick = this.quickInputService.createQuickPick(); - - quickPick.title = localize('continueEditSessionPick.title', 'Continue Edit Session...'); - quickPick.placeholder = localize('continueEditSessionPick.placeholder', 'Choose how you would like to continue working'); - quickPick.items = this.createPickItems(); - - const command = await new Promise((resolve, reject) => { - quickPick.onDidHide(() => resolve(undefined)); - - quickPick.onDidAccept((e) => { - const selection = quickPick.activeItems[0].command; - resolve(selection); - quickPick.hide(); - }); - - quickPick.show(); - }); - - quickPick.dispose(); - - if (command === undefined) { - return undefined; - } - - try { - const uri = await this.commandService.executeCommand(command); - return URI.isUri(uri) ? uri : undefined; - } catch (ex) { - return undefined; - } - } - - private createPickItems(): ContinueEditSessionItem[] { - const items = [...this.continueEditSessionOptions].filter((option) => option.when === undefined || this.contextKeyService.contextMatchesRules(option.when)); - - if (getVirtualWorkspaceLocation(this.contextService.getWorkspace()) !== undefined) { - items.push(new ContinueEditSessionItem( - localize('continueEditSessionItem.openInLocalFolder', 'Open In Local Folder'), - openLocalFolderCommand.id, - )); - } - - return items; - } -} - -class ContinueEditSessionItem implements IQuickPickItem { - constructor( - public readonly label: string, - public readonly command: string, - public readonly when?: ContextKeyExpression, - ) { } -} - -interface ICommand { - command: string; - group: string; - when: string; -} - -const continueEditSessionExtPoint = ExtensionsRegistry.registerExtensionPoint({ - extensionPoint: 'continueEditSession', - jsonSchema: { - description: localize('continueEditSessionExtPoint', 'Contributes options for continuing the current edit session in a different environment'), - type: 'array', - items: { - type: 'object', - properties: { - command: { - description: localize('continueEditSessionExtPoint.command', 'Identifier of the command to execute. The command must be declared in the \'commands\'-section and return a URI representing a different environment where the current edit session can be continued.'), - type: 'string' - }, - group: { - description: localize('continueEditSessionExtPoint.group', 'Group into which this item belongs.'), - type: 'string' - }, - when: { - description: localize('continueEditSessionExtPoint.when', 'Condition which must be true to show this item.'), - type: 'string' - } - }, - required: ['command'] - } - } -}); - -//#endregion - -const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); -workbenchRegistry.registerWorkbenchContribution(SessionSyncContribution, LifecyclePhase.Restored); - -Registry.as(Extensions.Configuration).registerConfiguration({ - ...workbenchConfigurationNodeBase, - 'properties': { - 'workbench.experimental.editSessions.enabled': { - 'type': 'boolean', - 'tags': ['experimental', 'usesOnlineServices'], - 'default': false, - 'markdownDescription': localize('editSessionsEnabled', "Controls whether to display cloud-enabled actions to store and resume uncommitted changes when switching between web, desktop, or devices."), - }, - } -}); diff --git a/src/vs/workbench/contrib/sessionSync/browser/sessionSyncWorkbenchService.ts b/src/vs/workbench/contrib/sessionSync/browser/sessionSyncWorkbenchService.ts deleted file mode 100644 index 1df0ecc3d28..00000000000 --- a/src/vs/workbench/contrib/sessionSync/browser/sessionSyncWorkbenchService.ts +++ /dev/null @@ -1,358 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Disposable } from 'vs/base/common/lifecycle'; -import { URI } from 'vs/base/common/uri'; -import { localize } from 'vs/nls'; -import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; -import { ContextKeyExpr, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IFileService } from 'vs/platform/files/common/files'; -import { IProductService } from 'vs/platform/product/common/productService'; -import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; -import { IRequestService } from 'vs/platform/request/common/request'; -import { IStorageService, IStorageValueChangeEvent, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; -import { IAuthenticationProvider } from 'vs/platform/userDataSync/common/userDataSync'; -import { UserDataSyncStoreClient } from 'vs/platform/userDataSync/common/userDataSyncStoreService'; -import { AuthenticationSession, AuthenticationSessionsChangeEvent, IAuthenticationService } from 'vs/workbench/services/authentication/common/authentication'; -import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { EDIT_SESSIONS_SIGNED_IN, EditSession, EDIT_SESSION_SYNC_CATEGORY, ISessionSyncWorkbenchService, EDIT_SESSIONS_SIGNED_IN_KEY, IEditSessionsLogService } from 'vs/workbench/contrib/sessionSync/common/sessionSync'; - -type ExistingSession = IQuickPickItem & { session: AuthenticationSession & { providerId: string } }; -type AuthenticationProviderOption = IQuickPickItem & { provider: IAuthenticationProvider }; - -export class SessionSyncWorkbenchService extends Disposable implements ISessionSyncWorkbenchService { - - _serviceBrand = undefined; - - private serverConfiguration = this.productService['sessionSync.store']; - private storeClient: UserDataSyncStoreClient | undefined; - - #authenticationInfo: { sessionId: string; token: string; providerId: string } | undefined; - private static CACHED_SESSION_STORAGE_KEY = 'editSessionSyncAccountPreference'; - - private initialized = false; - private readonly signedInContext: IContextKey; - - constructor( - @IFileService private readonly fileService: IFileService, - @IStorageService private readonly storageService: IStorageService, - @IQuickInputService private readonly quickInputService: IQuickInputService, - @IAuthenticationService private readonly authenticationService: IAuthenticationService, - @IExtensionService private readonly extensionService: IExtensionService, - @IEnvironmentService private readonly environmentService: IEnvironmentService, - @IEditSessionsLogService private readonly logService: IEditSessionsLogService, - @IProductService private readonly productService: IProductService, - @IContextKeyService private readonly contextKeyService: IContextKeyService, - @IRequestService private readonly requestService: IRequestService, - ) { - super(); - - // If the user signs out of the current session, reset our cached auth state in memory and on disk - this._register(this.authenticationService.onDidChangeSessions((e) => this.onDidChangeSessions(e.event))); - - // If another window changes the preferred session storage, reset our cached auth state in memory - this._register(this.storageService.onDidChangeValue(e => this.onDidChangeStorage(e))); - - this.registerResetAuthenticationAction(); - - this.signedInContext = EDIT_SESSIONS_SIGNED_IN.bindTo(this.contextKeyService); - this.signedInContext.set(this.existingSessionId !== undefined); - } - - /** - * - * @param editSession An object representing edit session state to be restored. - * @returns The ref of the stored edit session state. - */ - async write(editSession: EditSession): Promise { - await this.initialize(); - if (!this.initialized) { - throw new Error('Please sign in to store your edit session.'); - } - - return this.storeClient!.write('editSessions', JSON.stringify(editSession), null); - } - - /** - * @param ref: A specific content ref to retrieve content for, if it exists. - * If undefined, this method will return the latest saved edit session, if any. - * - * @returns An object representing the requested or latest edit session state, if any. - */ - async read(ref: string | undefined): Promise<{ ref: string; editSession: EditSession } | undefined> { - await this.initialize(); - if (!this.initialized) { - throw new Error('Please sign in to apply your latest edit session.'); - } - - let content: string | undefined | null; - try { - if (ref !== undefined) { - content = await this.storeClient?.resolveContent('editSessions', ref); - } else { - const result = await this.storeClient?.read('editSessions', null); - content = result?.content; - ref = result?.ref; - } - } catch (ex) { - this.logService.error(ex); - } - - // TODO@joyceerhl Validate session data, check schema version - return (content !== undefined && content !== null && ref !== undefined) ? { ref: ref, editSession: JSON.parse(content) } : undefined; - } - - async delete(ref: string) { - await this.initialize(); - if (!this.initialized) { - throw new Error(`Unable to delete edit session with ref ${ref}.`); - } - - try { - await this.storeClient?.delete('editSessions', ref); - } catch (ex) { - this.logService.error(ex); - } - } - - private async initialize() { - if (this.initialized) { - return; - } - this.initialized = await this.doInitialize(); - this.signedInContext.set(this.initialized); - } - - /** - * - * Ensures that the store client is initialized, - * meaning that authentication is configured and it - * can be used to communicate with the remote storage service - */ - private async doInitialize(): Promise { - // Wait for authentication extensions to be registered - await this.extensionService.whenInstalledExtensionsRegistered(); - - if (!this.serverConfiguration?.url) { - throw new Error('Unable to initialize sessions sync as session sync preference is not configured in product.json.'); - } - - if (!this.storeClient) { - this.storeClient = new UserDataSyncStoreClient(URI.parse(this.serverConfiguration.url), this.productService, this.requestService, this.logService, this.environmentService, this.fileService, this.storageService); - this._register(this.storeClient.onTokenFailed(() => { - this.logService.info('Clearing edit sessions authentication preference because of successive token failures.'); - this.clearAuthenticationPreference(); - })); - } - - // If we already have an existing auth session in memory, use that - if (this.#authenticationInfo !== undefined) { - return true; - } - - // If the user signed in previously and the session is still available, reuse that without prompting the user again - const existingSessionId = this.existingSessionId; - if (existingSessionId) { - this.logService.trace(`Searching for existing authentication session with ID ${existingSessionId}`); - const existing = await this.getExistingSession(); - if (existing !== undefined) { - this.logService.trace(`Found existing authentication session with ID ${existingSessionId}`); - this.#authenticationInfo = { sessionId: existing.session.id, token: existing.session.accessToken, providerId: existing.session.providerId }; - this.storeClient.setAuthToken(this.#authenticationInfo.token, this.#authenticationInfo.providerId); - return true; - } - } - - // Ask the user to pick a preferred account - const session = await this.getAccountPreference(); - if (session !== undefined) { - this.#authenticationInfo = { sessionId: session.id, token: session.accessToken, providerId: session.providerId }; - this.storeClient.setAuthToken(this.#authenticationInfo.token, this.#authenticationInfo.providerId); - this.existingSessionId = session.id; - this.logService.trace(`Saving authentication session preference for ID ${session.id}.`); - return true; - } - - return false; - } - - /** - * - * Prompts the user to pick an authentication option for storing and getting edit sessions. - */ - private async getAccountPreference(): Promise { - const quickpick = this.quickInputService.createQuickPick(); - quickpick.title = localize('account preference', 'Sign In to Use Edit Sessions'); - quickpick.ok = false; - quickpick.placeholder = localize('choose account placeholder', "Select an account to sign in"); - quickpick.ignoreFocusOut = true; - quickpick.items = await this.createQuickpickItems(); - - return new Promise((resolve, reject) => { - quickpick.onDidHide((e) => { - resolve(undefined); - quickpick.dispose(); - }); - - quickpick.onDidAccept(async (e) => { - const selection = quickpick.selectedItems[0]; - const session = 'provider' in selection ? { ...await this.authenticationService.createSession(selection.provider.id, selection.provider.scopes), providerId: selection.provider.id } : selection.session; - resolve(session); - quickpick.hide(); - }); - - quickpick.show(); - }); - } - - private async createQuickpickItems(): Promise<(ExistingSession | AuthenticationProviderOption | IQuickPickSeparator)[]> { - const options: (ExistingSession | AuthenticationProviderOption | IQuickPickSeparator)[] = []; - - options.push({ type: 'separator', label: localize('signed in', "Signed In") }); - - const sessions = await this.getAllSessions(); - options.push(...sessions); - - options.push({ type: 'separator', label: localize('others', "Others") }); - - for (const authenticationProvider of (await this.getAuthenticationProviders())) { - const signedInForProvider = sessions.some(account => account.session.providerId === authenticationProvider.id); - if (!signedInForProvider || this.authenticationService.supportsMultipleAccounts(authenticationProvider.id)) { - const providerName = this.authenticationService.getLabel(authenticationProvider.id); - options.push({ label: localize('sign in using account', "Sign in with {0}", providerName), provider: authenticationProvider }); - } - } - - return options; - } - - /** - * - * Returns all authentication sessions available from {@link getAuthenticationProviders}. - */ - private async getAllSessions() { - const authenticationProviders = await this.getAuthenticationProviders(); - const accounts = new Map(); - let currentSession: ExistingSession | undefined; - - for (const provider of authenticationProviders) { - const sessions = await this.authenticationService.getSessions(provider.id, provider.scopes); - - for (const session of sessions) { - const item = { - label: session.account.label, - description: this.authenticationService.getLabel(provider.id), - session: { ...session, providerId: provider.id } - }; - accounts.set(item.session.account.id, item); - if (this.existingSessionId === session.id) { - currentSession = item; - } - } - } - - if (currentSession !== undefined) { - accounts.set(currentSession.session.account.id, currentSession); - } - - return [...accounts.values()]; - } - - /** - * - * Returns all authentication providers which can be used to authenticate - * to the remote storage service, based on product.json configuration - * and registered authentication providers. - */ - private async getAuthenticationProviders() { - if (!this.serverConfiguration) { - throw new Error('Unable to get configured authentication providers as session sync preference is not configured in product.json.'); - } - - // Get the list of authentication providers configured in product.json - const authenticationProviders = this.serverConfiguration.authenticationProviders; - const configuredAuthenticationProviders = Object.keys(authenticationProviders).reduce((result, id) => { - result.push({ id, scopes: authenticationProviders[id].scopes }); - return result; - }, []); - - // Filter out anything that isn't currently available through the authenticationService - const availableAuthenticationProviders = this.authenticationService.declaredProviders; - - return configuredAuthenticationProviders.filter(({ id }) => availableAuthenticationProviders.some(provider => provider.id === id)); - } - - private get existingSessionId() { - return this.storageService.get(SessionSyncWorkbenchService.CACHED_SESSION_STORAGE_KEY, StorageScope.APPLICATION); - } - - private set existingSessionId(sessionId: string | undefined) { - if (sessionId === undefined) { - this.storageService.remove(SessionSyncWorkbenchService.CACHED_SESSION_STORAGE_KEY, StorageScope.APPLICATION); - } else { - this.storageService.store(SessionSyncWorkbenchService.CACHED_SESSION_STORAGE_KEY, sessionId, StorageScope.APPLICATION, StorageTarget.MACHINE); - } - } - - private async getExistingSession() { - const accounts = await this.getAllSessions(); - return accounts.find((account) => account.session.id === this.existingSessionId); - } - - private async onDidChangeStorage(e: IStorageValueChangeEvent): Promise { - if (e.key === SessionSyncWorkbenchService.CACHED_SESSION_STORAGE_KEY - && e.scope === StorageScope.APPLICATION - ) { - const newSessionId = this.existingSessionId; - const previousSessionId = this.#authenticationInfo?.sessionId; - - if (previousSessionId !== newSessionId) { - this.logService.trace(`Resetting authentication state because authentication session ID preference changed from ${previousSessionId} to ${newSessionId}.`); - this.#authenticationInfo = undefined; - this.initialized = false; - } - } - } - - private clearAuthenticationPreference(): void { - this.#authenticationInfo = undefined; - this.initialized = false; - this.existingSessionId = undefined; - this.signedInContext.set(false); - } - - private onDidChangeSessions(e: AuthenticationSessionsChangeEvent): void { - if (this.#authenticationInfo?.sessionId && e.removed.find(session => session.id === this.#authenticationInfo?.sessionId)) { - this.clearAuthenticationPreference(); - } - } - - private registerResetAuthenticationAction() { - const that = this; - this._register(registerAction2(class ResetEditSessionAuthenticationAction extends Action2 { - constructor() { - super({ - id: 'workbench.sessionSync.actions.resetAuth', - title: localize('reset auth', 'Sign Out'), - category: EDIT_SESSION_SYNC_CATEGORY, - precondition: ContextKeyExpr.equals(EDIT_SESSIONS_SIGNED_IN_KEY, true), - menu: [{ - id: MenuId.CommandPalette, - }, - { - id: MenuId.AccountsContext, - group: '2_editSessions', - when: ContextKeyExpr.equals(EDIT_SESSIONS_SIGNED_IN_KEY, true), - }] - }); - } - - run() { - that.clearAuthenticationPreference(); - } - })); - } -} diff --git a/src/vs/workbench/contrib/sessionSync/common/editSessionsLogService.ts b/src/vs/workbench/contrib/sessionSync/common/editSessionsLogService.ts deleted file mode 100644 index 2b3b6bca671..00000000000 --- a/src/vs/workbench/contrib/sessionSync/common/editSessionsLogService.ts +++ /dev/null @@ -1,50 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { AbstractLogger, ILogger, ILoggerService } from 'vs/platform/log/common/log'; -import { IEditSessionsLogService } from 'vs/workbench/contrib/sessionSync/common/sessionSync'; - -export class EditSessionsLogService extends AbstractLogger implements IEditSessionsLogService { - - declare readonly _serviceBrand: undefined; - private readonly logger: ILogger; - - constructor( - @ILoggerService loggerService: ILoggerService, - @IEnvironmentService environmentService: IEnvironmentService - ) { - super(); - this.logger = this._register(loggerService.createLogger(environmentService.editSessionsLogResource, { name: 'editsessions' })); - } - - trace(message: string, ...args: any[]): void { - this.logger.trace(message, ...args); - } - - debug(message: string, ...args: any[]): void { - this.logger.debug(message, ...args); - } - - info(message: string, ...args: any[]): void { - this.logger.info(message, ...args); - } - - warn(message: string, ...args: any[]): void { - this.logger.warn(message, ...args); - } - - error(message: string | Error, ...args: any[]): void { - this.logger.error(message, ...args); - } - - critical(message: string | Error, ...args: any[]): void { - this.logger.critical(message, ...args); - } - - flush(): void { - this.logger.flush(); - } -} diff --git a/src/vs/workbench/contrib/sessionSync/common/sessionSync.ts b/src/vs/workbench/contrib/sessionSync/common/sessionSync.ts deleted file mode 100644 index 538a54a6444..00000000000 --- a/src/vs/workbench/contrib/sessionSync/common/sessionSync.ts +++ /dev/null @@ -1,67 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { localize } from 'vs/nls'; -import { ILocalizedString } from 'vs/platform/action/common/action'; -import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { ILogService } from 'vs/platform/log/common/log'; - -export const EDIT_SESSION_SYNC_CATEGORY: ILocalizedString = { - original: 'Edit Sessions', - value: localize('session sync', 'Edit Sessions') -}; - -export const ISessionSyncWorkbenchService = createDecorator('ISessionSyncWorkbenchService'); -export interface ISessionSyncWorkbenchService { - _serviceBrand: undefined; - - read(ref: string | undefined): Promise<{ ref: string; editSession: EditSession } | undefined>; - write(editSession: EditSession): Promise; - delete(ref: string): Promise; -} - -export const IEditSessionsLogService = createDecorator('IEditSessionsLogService'); -export interface IEditSessionsLogService extends ILogService { } - -export enum ChangeType { - Addition = 1, - Deletion = 2, -} - -export enum FileType { - File = 1, -} - -interface Addition { - relativeFilePath: string; - fileType: FileType.File; - contents: string; - type: ChangeType.Addition; -} - -interface Deletion { - relativeFilePath: string; - fileType: FileType.File; - contents: undefined; - type: ChangeType.Deletion; -} - -export type Change = Addition | Deletion; - -export interface Folder { - name: string; - workingChanges: Change[]; -} - -export const EditSessionSchemaVersion = 1; - -export interface EditSession { - version: number; - folders: Folder[]; -} - -export const EDIT_SESSIONS_SIGNED_IN_KEY = 'editSessionsSignedIn'; -export const EDIT_SESSIONS_SIGNED_IN = new RawContextKey(EDIT_SESSIONS_SIGNED_IN_KEY, false); diff --git a/src/vs/workbench/contrib/sessionSync/test/browser/sessionSync.test.ts b/src/vs/workbench/contrib/sessionSync/test/browser/sessionSync.test.ts deleted file mode 100644 index 140c068d5d0..00000000000 --- a/src/vs/workbench/contrib/sessionSync/test/browser/sessionSync.test.ts +++ /dev/null @@ -1,134 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { DisposableStore } from 'vs/base/common/lifecycle'; -import { IFileService } from 'vs/platform/files/common/files'; -import { FileService } from 'vs/platform/files/common/fileService'; -import { Schemas } from 'vs/base/common/network'; -import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider'; -import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; -import { NullLogService } from 'vs/platform/log/common/log'; -import { SessionSyncContribution } from 'vs/workbench/contrib/sessionSync/browser/sessionSync.contribution'; -import { ProgressService } from 'vs/workbench/services/progress/browser/progressService'; -import { IProgressService } from 'vs/platform/progress/common/progress'; -import { ISCMService } from 'vs/workbench/contrib/scm/common/scm'; -import { SCMService } from 'vs/workbench/contrib/scm/common/scmService'; -import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { mock } from 'vs/base/test/common/mock'; -import * as sinon from 'sinon'; -import * as assert from 'assert'; -import { ChangeType, FileType, IEditSessionsLogService, ISessionSyncWorkbenchService } from 'vs/workbench/contrib/sessionSync/common/sessionSync'; -import { URI } from 'vs/base/common/uri'; -import { joinPath } from 'vs/base/common/resources'; -import { INotificationService } from 'vs/platform/notification/common/notification'; -import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; -import { TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; - -const folderName = 'test-folder'; -const folderUri = URI.file(`/${folderName}`); - -suite('Edit session sync', () => { - let instantiationService: TestInstantiationService; - let sessionSyncContribution: SessionSyncContribution; - let fileService: FileService; - let sandbox: sinon.SinonSandbox; - - const disposables = new DisposableStore(); - - suiteSetup(() => { - sandbox = sinon.createSandbox(); - - instantiationService = new TestInstantiationService(); - - // Set up filesystem - const logService = new NullLogService(); - fileService = disposables.add(new FileService(logService)); - const fileSystemProvider = disposables.add(new InMemoryFileSystemProvider()); - fileService.registerProvider(Schemas.file, fileSystemProvider); - - // Stub out all services - instantiationService.stub(IEditSessionsLogService, logService); - instantiationService.stub(IFileService, fileService); - instantiationService.stub(INotificationService, new TestNotificationService()); - instantiationService.stub(ISessionSyncWorkbenchService, new class extends mock() { }); - instantiationService.stub(IProgressService, ProgressService); - instantiationService.stub(ISCMService, SCMService); - instantiationService.stub(IEnvironmentService, TestEnvironmentService); - instantiationService.stub(IConfigurationService, new TestConfigurationService({ workbench: { experimental: { sessionSync: { enabled: true } } } })); - instantiationService.stub(IWorkspaceContextService, new class extends mock() { - override getWorkspace() { - return { - id: 'workspace-id', - folders: [{ - uri: folderUri, - name: folderName, - index: 0, - toResource: (relativePath: string) => joinPath(folderUri, relativePath) - }] - }; - } - }); - - // Stub repositories - instantiationService.stub(ISCMService, '_repositories', new Map()); - - sessionSyncContribution = instantiationService.createInstance(SessionSyncContribution); - }); - - teardown(() => { - sinon.restore(); - disposables.clear(); - }); - - test('Can apply edit session', async function () { - const fileUri = joinPath(folderUri, 'dir1', 'README.md'); - const fileContents = '# readme'; - const editSession = { - version: 1, - folders: [ - { - name: folderName, - workingChanges: [ - { - relativeFilePath: 'dir1/README.md', - fileType: FileType.File, - contents: fileContents, - type: ChangeType.Addition - } - ] - } - ] - }; - - // Stub sync service to return edit session data - const readStub = sandbox.stub().returns({ editSession, ref: '0' }); - instantiationService.stub(ISessionSyncWorkbenchService, 'read', readStub); - - // Create root folder - await fileService.createFolder(folderUri); - - // Apply edit session - await sessionSyncContribution.applyEditSession(); - - // Verify edit session was correctly applied - assert.equal((await fileService.readFile(fileUri)).value.toString(), fileContents); - }); - - test('Edit session not stored if there are no edits', async function () { - const writeStub = sandbox.stub(); - instantiationService.stub(ISessionSyncWorkbenchService, 'write', writeStub); - - // Create root folder - await fileService.createFolder(folderUri); - - await sessionSyncContribution.storeEditSession(true); - - // Verify that we did not attempt to write the edit session - assert.equal(writeStub.called, false); - }); -}); diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index 3319bbe6143..14407f52692 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -329,7 +329,7 @@ import 'vs/workbench/contrib/userDataSync/browser/userDataSync.contribution'; import 'vs/workbench/contrib/userDataProfile/browser/userDataProfile.contribution'; // Continue Edit Session -import 'vs/workbench/contrib/sessionSync/browser/sessionSync.contribution'; +import 'vs/workbench/contrib/editSessions/browser/editSessions.contribution'; // Code Actions import 'vs/workbench/contrib/codeActions/browser/codeActions.contribution'; -- cgit v1.2.3 From 0586d45c690dab433101b5aa64f6434dd6bd03ba Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 6 Jul 2022 14:41:26 -0400 Subject: replace forEach in resolver service (#154286) * part of #154195 * fix test --- .../browser/baseConfigurationResolverService.ts | 31 +++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts b/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts index 059d8e46456..07053d26b4d 100644 --- a/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts +++ b/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import * as Types from 'vs/base/common/types'; import { Schemas } from 'vs/base/common/network'; import { SideBySideEditor, EditorResourceAccessor } from 'vs/workbench/common/editor'; -import { IStringDictionary, forEach } from 'vs/base/common/collections'; +import { IStringDictionary } from 'vs/base/common/collections'; import { IConfigurationService, IConfigurationOverrides, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IWorkspaceFolder, IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; @@ -157,9 +157,9 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR if (!newMapping) { return false; } - forEach(newMapping, (entry) => { - fullMapping.set(entry.key, entry.value); - }); + for (const [key, value] of Object.entries(newMapping)) { + fullMapping.set(key, value); + } return true; } @@ -256,20 +256,21 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR } } } - this._contributedVariables.forEach((value, contributed: string) => { + for (const contributed of this._contributedVariables.keys()) { if ((variables.indexOf(contributed) < 0) && (object.indexOf('${' + contributed + '}') >= 0)) { variables.push(contributed); } - }); + } } else if (Types.isArray(object)) { - object.forEach(value => { + for (const value of object) { this.findVariables(value, variables); - }); + + } } else if (object) { - Object.keys(object).forEach(key => { - const value = object[key]; + for (const value of Object.values(object)) { this.findVariables(value, variables); - }); + + } } } @@ -315,11 +316,11 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR missingAttribute('description'); } if (Types.isArray(info.options)) { - info.options.forEach(pickOption => { + for (const pickOption of info.options) { if (!Types.isString(pickOption) && !Types.isString(pickOption.value)) { missingAttribute('value'); } - }); + } } else { missingAttribute('options'); } @@ -327,7 +328,7 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR value: string; } const picks = new Array(); - info.options.forEach(pickOption => { + for (const pickOption of info.options) { const value = Types.isString(pickOption) ? pickOption : pickOption.value; const label = Types.isString(pickOption) ? undefined : pickOption.label; @@ -343,7 +344,7 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR } else { picks.push(item); } - }); + } const pickOptions: IPickOptions = { placeHolder: info.description, matchOnDetail: true, ignoreFocusLost: true }; return this.quickInputService.pick(picks, pickOptions, undefined).then(resolvedInput => { if (resolvedInput) { -- cgit v1.2.3 From 0c12daf1faed6f26b9742aec0bcaf27b55b4bf20 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 12:30:25 -0700 Subject: Make run recent command use contiguous filtering Part of #154016 --- .../contrib/terminal/browser/terminalInstance.ts | 81 +++++++++++++--------- 1 file changed, 50 insertions(+), 31 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index edf4d2b4198..bff1bea1b1e 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -965,42 +965,61 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } const outputProvider = this._instantiationService.createInstance(TerminalOutputProvider); const quickPick = this._quickInputService.createQuickPick(); - quickPick.items = items; + const originalItems = items; + quickPick.items = [...originalItems]; quickPick.sortByLabel = false; + quickPick.matchOnLabel = false; quickPick.placeholder = placeholder; - return new Promise(r => { - quickPick.onDidTriggerItemButton(async e => { - if (e.button === removeFromCommandHistoryButton) { - if (type === 'command') { - this._instantiationService.invokeFunction(getCommandHistory)?.remove(e.item.label); - } else { - this._instantiationService.invokeFunction(getDirectoryHistory)?.remove(e.item.label); - } + quickPick.title = 'Run Recent Command'; + quickPick.onDidChangeValue(value => { + quickPick.items = originalItems.filter(item => { + if (item.type === 'separator') { + return true; + } + item.highlights = undefined; + const matchIndex = item.label.indexOf(value); + if (matchIndex !== -1) { + item.highlights = { + label: [{ start: matchIndex, end: matchIndex + value.length }] + }; + return true; + } + return false; + }); + }); + quickPick.onDidTriggerItemButton(async e => { + if (e.button === removeFromCommandHistoryButton) { + if (type === 'command') { + this._instantiationService.invokeFunction(getCommandHistory)?.remove(e.item.label); } else { - const selectedCommand = (e.item as Item).command; - const output = selectedCommand?.getOutput(); - if (output && selectedCommand?.command) { - const textContent = await outputProvider.provideTextContent(URI.from( - { - scheme: TerminalOutputProvider.scheme, - path: `${selectedCommand.command}... ${fromNow(selectedCommand.timestamp, true)}`, - fragment: output, - query: `terminal-output-${selectedCommand.timestamp}-${this.instanceId}` - })); - if (textContent) { - await this._editorService.openEditor({ - resource: textContent.uri - }); - } + this._instantiationService.invokeFunction(getDirectoryHistory)?.remove(e.item.label); + } + } else { + const selectedCommand = (e.item as Item).command; + const output = selectedCommand?.getOutput(); + if (output && selectedCommand?.command) { + const textContent = await outputProvider.provideTextContent(URI.from( + { + scheme: TerminalOutputProvider.scheme, + path: `${selectedCommand.command}... ${fromNow(selectedCommand.timestamp, true)}`, + fragment: output, + query: `terminal-output-${selectedCommand.timestamp}-${this.instanceId}` + })); + if (textContent) { + await this._editorService.openEditor({ + resource: textContent.uri + }); } } - quickPick.hide(); - }); - quickPick.onDidAccept(() => { - const result = quickPick.activeItems[0]; - this.sendText(type === 'cwd' ? `cd ${result.label}` : result.label, !quickPick.keyMods.alt); - quickPick.hide(); - }); + } + quickPick.hide(); + }); + quickPick.onDidAccept(() => { + const result = quickPick.activeItems[0]; + this.sendText(type === 'cwd' ? `cd ${result.label}` : result.label, !quickPick.keyMods.alt); + quickPick.hide(); + }); + return new Promise(r => { quickPick.show(); quickPick.onDidHide(() => r()); }); -- cgit v1.2.3 From 61cf9c4316e22113d0b27a316366f4784cfa8514 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 12:40:12 -0700 Subject: Allow use of contiguous or fuzzy search in run recent --- .../contrib/terminal/browser/terminalInstance.ts | 49 ++++++++++++++-------- 1 file changed, 32 insertions(+), 17 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index bff1bea1b1e..ddd4ffc2729 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -818,7 +818,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._linkManager.openRecentLink(type); } - async runRecent(type: 'command' | 'cwd'): Promise { + async runRecent(type: 'command' | 'cwd', filterMode?: 'fuzzy' | 'contiguous'): Promise { if (!this.xterm) { return; } @@ -968,25 +968,40 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { const originalItems = items; quickPick.items = [...originalItems]; quickPick.sortByLabel = false; - quickPick.matchOnLabel = false; quickPick.placeholder = placeholder; quickPick.title = 'Run Recent Command'; - quickPick.onDidChangeValue(value => { - quickPick.items = originalItems.filter(item => { - if (item.type === 'separator') { - return true; - } - item.highlights = undefined; - const matchIndex = item.label.indexOf(value); - if (matchIndex !== -1) { - item.highlights = { - label: [{ start: matchIndex, end: matchIndex + value.length }] - }; - return true; - } - return false; + quickPick.customButton = true; + quickPick.matchOnLabel = filterMode === 'fuzzy'; + if (filterMode === 'fuzzy') { + quickPick.customLabel = nls.localize('terminal.contiguousSearch', 'Use Contiguous Search'); + quickPick.onDidCustom(() => { + quickPick.hide(); + this.runRecent(type, 'contiguous'); }); - }); + } else { + // contiguous is the default for command + quickPick.onDidChangeValue(value => { + quickPick.items = originalItems.filter(item => { + if (item.type === 'separator') { + return true; + } + item.highlights = undefined; + const matchIndex = item.label.indexOf(value); + if (matchIndex !== -1) { + item.highlights = { + label: [{ start: matchIndex, end: matchIndex + value.length }] + }; + return true; + } + return false; + }); + }); + quickPick.customLabel = nls.localize('terminal.fuzzySearch', 'Use Fuzzy Search'); + quickPick.onDidCustom(() => { + quickPick.hide(); + this.runRecent(type, 'fuzzy'); + }); + } quickPick.onDidTriggerItemButton(async e => { if (e.button === removeFromCommandHistoryButton) { if (type === 'command') { -- cgit v1.2.3 From 6fc821730afb4b00ae23ca71c99b127eb0492f2d Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 12:42:53 -0700 Subject: Carry value over to new search --- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index ddd4ffc2729..2e47d3c4867 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -818,7 +818,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._linkManager.openRecentLink(type); } - async runRecent(type: 'command' | 'cwd', filterMode?: 'fuzzy' | 'contiguous'): Promise { + async runRecent(type: 'command' | 'cwd', filterMode?: 'fuzzy' | 'contiguous', value?: string): Promise { if (!this.xterm) { return; } @@ -969,14 +969,13 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { quickPick.items = [...originalItems]; quickPick.sortByLabel = false; quickPick.placeholder = placeholder; - quickPick.title = 'Run Recent Command'; quickPick.customButton = true; quickPick.matchOnLabel = filterMode === 'fuzzy'; if (filterMode === 'fuzzy') { quickPick.customLabel = nls.localize('terminal.contiguousSearch', 'Use Contiguous Search'); quickPick.onDidCustom(() => { quickPick.hide(); - this.runRecent(type, 'contiguous'); + this.runRecent(type, 'contiguous', quickPick.value); }); } else { // contiguous is the default for command @@ -999,7 +998,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { quickPick.customLabel = nls.localize('terminal.fuzzySearch', 'Use Fuzzy Search'); quickPick.onDidCustom(() => { quickPick.hide(); - this.runRecent(type, 'fuzzy'); + this.runRecent(type, 'fuzzy', quickPick.value); }); } quickPick.onDidTriggerItemButton(async e => { @@ -1034,6 +1033,9 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this.sendText(type === 'cwd' ? `cd ${result.label}` : result.label, !quickPick.keyMods.alt); quickPick.hide(); }); + if (value) { + quickPick.value = value; + } return new Promise(r => { quickPick.show(); quickPick.onDidHide(() => r()); -- cgit v1.2.3 From 465e8b4e57244d90257e57c6158a4f56eeb0d6e9 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 12:54:45 -0700 Subject: Move fuzzy/contiguous filtering into quick pick --- src/vs/base/parts/quickinput/browser/quickInput.ts | 11 +++++ .../parts/quickinput/browser/quickInputList.ts | 48 +++++++++++++++++++++- src/vs/base/parts/quickinput/common/quickInput.ts | 7 ++++ .../contrib/terminal/browser/terminalInstance.ts | 19 +-------- 4 files changed, 65 insertions(+), 20 deletions(-) (limited to 'src/vs') diff --git a/src/vs/base/parts/quickinput/browser/quickInput.ts b/src/vs/base/parts/quickinput/browser/quickInput.ts index 1a496080028..58a09cc29e5 100644 --- a/src/vs/base/parts/quickinput/browser/quickInput.ts +++ b/src/vs/base/parts/quickinput/browser/quickInput.ts @@ -450,6 +450,7 @@ class QuickPick extends QuickInput implements IQuickPi private _matchOnDescription = false; private _matchOnDetail = false; private _matchOnLabel = true; + private _matchOnLabelMode: 'fuzzy' | 'contiguous' = 'fuzzy'; private _sortByLabel = true; private _autoFocusOnList = true; private _keepScrollPosition = false; @@ -595,6 +596,15 @@ class QuickPick extends QuickInput implements IQuickPi this.update(); } + get matchOnLabelMode() { + return this._matchOnLabelMode; + } + + set matchOnLabelMode(matchOnLabelMode: 'fuzzy' | 'contiguous') { + this._matchOnLabelMode = matchOnLabelMode; + this.update(); + } + get sortByLabel() { return this._sortByLabel; } @@ -994,6 +1004,7 @@ class QuickPick extends QuickInput implements IQuickPi this.ui.list.matchOnDescription = this.matchOnDescription; this.ui.list.matchOnDetail = this.matchOnDetail; this.ui.list.matchOnLabel = this.matchOnLabel; + this.ui.list.matchOnLabelMode = this.matchOnLabelMode; this.ui.list.sortByLabel = this.sortByLabel; if (this.itemsUpdated) { this.itemsUpdated = false; diff --git a/src/vs/base/parts/quickinput/browser/quickInputList.ts b/src/vs/base/parts/quickinput/browser/quickInputList.ts index 2ada8ddcc60..610176917d2 100644 --- a/src/vs/base/parts/quickinput/browser/quickInputList.ts +++ b/src/vs/base/parts/quickinput/browser/quickInputList.ts @@ -17,10 +17,11 @@ import { compareAnything } from 'vs/base/common/comparers'; import { memoize } from 'vs/base/common/decorators'; import { Emitter, Event } from 'vs/base/common/event'; import { IMatch } from 'vs/base/common/filters'; -import { matchesFuzzyIconAware, parseLabelWithIcons } from 'vs/base/common/iconLabels'; +import { IParsedLabelWithIcons, matchesFuzzyIconAware, parseLabelWithIcons } from 'vs/base/common/iconLabels'; import { KeyCode } from 'vs/base/common/keyCodes'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; +import { ltrim } from 'vs/base/common/strings'; import { withNullAsUndefined } from 'vs/base/common/types'; import { IQuickInputOptions } from 'vs/base/parts/quickinput/browser/quickInput'; import { getIconClass } from 'vs/base/parts/quickinput/browser/quickInputUtils'; @@ -258,6 +259,7 @@ export class QuickInputList { matchOnDescription = false; matchOnDetail = false; matchOnLabel = true; + matchOnLabelMode: 'fuzzy' | 'contiguous' = 'fuzzy'; matchOnMeta = true; sortByLabel = true; private readonly _onChangedAllVisibleChecked = new Emitter(); @@ -628,7 +630,12 @@ export class QuickInputList { else { let currentSeparator: IQuickPickSeparator | undefined; this.elements.forEach(element => { - const labelHighlights = this.matchOnLabel ? withNullAsUndefined(matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneLabel))) : undefined; + let labelHighlights: IMatch[] | undefined; + if (this.matchOnLabelMode === 'fuzzy') { + labelHighlights = this.matchOnLabel ? withNullAsUndefined(matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneLabel))) : undefined; + } else { + labelHighlights = this.matchOnLabel ? withNullAsUndefined(matchesContiguousIconAware(query, parseLabelWithIcons(element.saneLabel))) : undefined; + } const descriptionHighlights = this.matchOnDescription ? withNullAsUndefined(matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneDescription || ''))) : undefined; const detailHighlights = this.matchOnDetail ? withNullAsUndefined(matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneDetail || ''))) : undefined; const metaHighlights = this.matchOnMeta ? withNullAsUndefined(matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneMeta || ''))) : undefined; @@ -726,6 +733,43 @@ export class QuickInputList { } } +export function matchesContiguousIconAware(query: string, target: IParsedLabelWithIcons, enableSeparateSubstringMatching = false): IMatch[] | null { + + const { text, iconOffsets } = target; + + // Return early if there are no icon markers in the word to match against + if (!iconOffsets || iconOffsets.length === 0) { + return matchesContiguous(query, text, enableSeparateSubstringMatching); + } + + // Trim the word to match against because it could have leading + // whitespace now if the word started with an icon + const wordToMatchAgainstWithoutIconsTrimmed = ltrim(text, ' '); + const leadingWhitespaceOffset = text.length - wordToMatchAgainstWithoutIconsTrimmed.length; + + // match on value without icon + const matches = matchesContiguous(query, wordToMatchAgainstWithoutIconsTrimmed, enableSeparateSubstringMatching); + + // Map matches back to offsets with icon and trimming + if (matches) { + for (const match of matches) { + const iconOffset = iconOffsets[match.start + leadingWhitespaceOffset] /* icon offsets at index */ + leadingWhitespaceOffset /* overall leading whitespace offset */; + match.start += iconOffset; + match.end += iconOffset; + } + } + + return matches; +} + +function matchesContiguous(word: string, wordToMatchAgainst: string, enableSeparateSubstringMatching = false): IMatch[] | null { + const matchIndex = wordToMatchAgainst.indexOf(word); + if (matchIndex !== -1) { + return [{ start: matchIndex, end: matchIndex + word.length }]; + } + return null; +} + function compareEntries(elementA: ListElement, elementB: ListElement, lookFor: string): number { const labelHighlightsA = elementA.labelHighlights || []; diff --git a/src/vs/base/parts/quickinput/common/quickInput.ts b/src/vs/base/parts/quickinput/common/quickInput.ts index bf9979e00b1..34824941387 100644 --- a/src/vs/base/parts/quickinput/common/quickInput.ts +++ b/src/vs/base/parts/quickinput/common/quickInput.ts @@ -292,6 +292,13 @@ export interface IQuickPick extends IQuickInput { matchOnLabel: boolean; + /** + * The mode to filter label with. Fuzzy will use fuzzy searching and + * contiguous will make filter entries that do not contain the exact string + * (including whitespace). This defaults to `'fuzzy'`. + */ + matchOnLabelMode: 'fuzzy' | 'contiguous'; + sortByLabel: boolean; autoFocusOnList: boolean; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 2e47d3c4867..f0e24670756 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -970,7 +970,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { quickPick.sortByLabel = false; quickPick.placeholder = placeholder; quickPick.customButton = true; - quickPick.matchOnLabel = filterMode === 'fuzzy'; + quickPick.matchOnLabelMode = filterMode || 'contiguous'; if (filterMode === 'fuzzy') { quickPick.customLabel = nls.localize('terminal.contiguousSearch', 'Use Contiguous Search'); quickPick.onDidCustom(() => { @@ -978,23 +978,6 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this.runRecent(type, 'contiguous', quickPick.value); }); } else { - // contiguous is the default for command - quickPick.onDidChangeValue(value => { - quickPick.items = originalItems.filter(item => { - if (item.type === 'separator') { - return true; - } - item.highlights = undefined; - const matchIndex = item.label.indexOf(value); - if (matchIndex !== -1) { - item.highlights = { - label: [{ start: matchIndex, end: matchIndex + value.length }] - }; - return true; - } - return false; - }); - }); quickPick.customLabel = nls.localize('terminal.fuzzySearch', 'Use Fuzzy Search'); quickPick.onDidCustom(() => { quickPick.hide(); -- cgit v1.2.3 From 419a7cc1a0bd6be79b27e80eaf7e0dfbb2dd6543 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 6 Jul 2022 13:13:57 -0700 Subject: Register commands correctly with original title, #153865 (#154297) --- .../browser/contrib/cellCommands/cellCommands.ts | 90 +++++++++++++++++----- .../contrib/search/browser/search.contribution.ts | 25 ++++-- 2 files changed, 92 insertions(+), 23 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/cellCommands/cellCommands.ts b/src/vs/workbench/contrib/notebook/browser/contrib/cellCommands/cellCommands.ts index 2adc303d4e1..5074d759b06 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/cellCommands/cellCommands.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/cellCommands/cellCommands.ts @@ -31,7 +31,10 @@ registerAction2(class extends NotebookCellAction { super( { id: MOVE_CELL_UP_COMMAND_ID, - title: localize('notebookActions.moveCellUp', "Move Cell Up"), + title: { + value: localize('notebookActions.moveCellUp', "Move Cell Up"), + original: 'Move Cell Up' + }, icon: icons.moveUpIcon, keybinding: { primary: KeyMod.Alt | KeyCode.UpArrow, @@ -57,7 +60,10 @@ registerAction2(class extends NotebookCellAction { super( { id: MOVE_CELL_DOWN_COMMAND_ID, - title: localize('notebookActions.moveCellDown', "Move Cell Down"), + title: { + value: localize('notebookActions.moveCellDown', "Move Cell Down"), + original: 'Move Cell Down' + }, icon: icons.moveDownIcon, keybinding: { primary: KeyMod.Alt | KeyCode.DownArrow, @@ -83,7 +89,10 @@ registerAction2(class extends NotebookCellAction { super( { id: COPY_CELL_UP_COMMAND_ID, - title: localize('notebookActions.copyCellUp', "Copy Cell Up"), + title: { + value: localize('notebookActions.copyCellUp', "Copy Cell Up"), + original: 'Copy Cell Up' + }, keybinding: { primary: KeyMod.Alt | KeyMod.Shift | KeyCode.UpArrow, when: ContextKeyExpr.and(NOTEBOOK_EDITOR_FOCUSED, InputFocusedContext.toNegated()), @@ -102,7 +111,10 @@ registerAction2(class extends NotebookCellAction { super( { id: COPY_CELL_DOWN_COMMAND_ID, - title: localize('notebookActions.copyCellDown', "Copy Cell Down"), + title: { + value: localize('notebookActions.copyCellDown', "Copy Cell Down"), + original: 'Copy Cell Down' + }, keybinding: { primary: KeyMod.Alt | KeyMod.Shift | KeyCode.DownArrow, when: ContextKeyExpr.and(NOTEBOOK_EDITOR_FOCUSED, InputFocusedContext.toNegated()), @@ -137,7 +149,10 @@ registerAction2(class extends NotebookCellAction { super( { id: SPLIT_CELL_COMMAND_ID, - title: localize('notebookActions.splitCell', "Split Cell"), + title: { + value: localize('notebookActions.splitCell', "Split Cell"), + original: 'Split Cell' + }, menu: { id: MenuId.NotebookCellTitle, when: ContextKeyExpr.and( @@ -212,7 +227,10 @@ registerAction2(class extends NotebookCellAction { super( { id: JOIN_CELL_ABOVE_COMMAND_ID, - title: localize('notebookActions.joinCellAbove', "Join With Previous Cell"), + title: { + value: localize('notebookActions.joinCellAbove', "Join With Previous Cell"), + original: 'Join With Previous Cell' + }, keybinding: { when: NOTEBOOK_EDITOR_FOCUSED, primary: KeyMod.WinCtrl | KeyMod.Alt | KeyMod.Shift | KeyCode.KeyJ, @@ -238,7 +256,10 @@ registerAction2(class extends NotebookCellAction { super( { id: JOIN_CELL_BELOW_COMMAND_ID, - title: localize('notebookActions.joinCellBelow', "Join With Next Cell"), + title: { + value: localize('notebookActions.joinCellBelow', "Join With Next Cell"), + original: 'Join With Next Cell' + }, keybinding: { when: NOTEBOOK_EDITOR_FOCUSED, primary: KeyMod.WinCtrl | KeyMod.Alt | KeyCode.KeyJ, @@ -270,7 +291,10 @@ registerAction2(class ChangeCellToCodeAction extends NotebookMultiCellAction { constructor() { super({ id: CHANGE_CELL_TO_CODE_COMMAND_ID, - title: localize('notebookActions.changeCellToCode', "Change Cell to Code"), + title: { + value: localize('notebookActions.changeCellToCode', "Change Cell to Code"), + original: 'Change Cell to Code' + }, keybinding: { when: ContextKeyExpr.and(NOTEBOOK_EDITOR_FOCUSED, ContextKeyExpr.not(InputFocusedContextKey)), primary: KeyCode.KeyY, @@ -294,7 +318,10 @@ registerAction2(class ChangeCellToMarkdownAction extends NotebookMultiCellAction constructor() { super({ id: CHANGE_CELL_TO_MARKDOWN_COMMAND_ID, - title: localize('notebookActions.changeCellToMarkdown', "Change Cell to Markdown"), + title: { + value: localize('notebookActions.changeCellToMarkdown', "Change Cell to Markdown"), + original: 'Change Cell to Markdown' + }, keybinding: { when: ContextKeyExpr.and(NOTEBOOK_EDITOR_FOCUSED, ContextKeyExpr.not(InputFocusedContextKey)), primary: KeyCode.KeyM, @@ -330,7 +357,10 @@ registerAction2(class CollapseCellInputAction extends NotebookMultiCellAction { constructor() { super({ id: COLLAPSE_CELL_INPUT_COMMAND_ID, - title: localize('notebookActions.collapseCellInput', "Collapse Cell Input"), + title: { + value: localize('notebookActions.collapseCellInput', "Collapse Cell Input"), + original: 'Collapse Cell Input' + }, keybinding: { when: ContextKeyExpr.and(NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_INPUT_COLLAPSED.toNegated(), InputFocusedContext.toNegated()), primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyC), @@ -356,7 +386,10 @@ registerAction2(class ExpandCellInputAction extends NotebookMultiCellAction { constructor() { super({ id: EXPAND_CELL_INPUT_COMMAND_ID, - title: localize('notebookActions.expandCellInput', "Expand Cell Input"), + title: { + value: localize('notebookActions.expandCellInput', "Expand Cell Input"), + original: 'Expand Cell Input' + }, keybinding: { when: ContextKeyExpr.and(NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_INPUT_COLLAPSED), primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyC), @@ -382,7 +415,10 @@ registerAction2(class CollapseCellOutputAction extends NotebookMultiCellAction { constructor() { super({ id: COLLAPSE_CELL_OUTPUT_COMMAND_ID, - title: localize('notebookActions.collapseCellOutput', "Collapse Cell Output"), + title: { + value: localize('notebookActions.collapseCellOutput', "Collapse Cell Output"), + original: 'Collapse Cell Output' + }, keybinding: { when: ContextKeyExpr.and(NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_OUTPUT_COLLAPSED.toNegated(), InputFocusedContext.toNegated(), NOTEBOOK_CELL_HAS_OUTPUTS), primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyCode.KeyT), @@ -404,7 +440,10 @@ registerAction2(class ExpandCellOuputAction extends NotebookMultiCellAction { constructor() { super({ id: EXPAND_CELL_OUTPUT_COMMAND_ID, - title: localize('notebookActions.expandCellOutput', "Expand Cell Output"), + title: { + value: localize('notebookActions.expandCellOutput', "Expand Cell Output"), + original: 'Expand Cell Output' + }, keybinding: { when: ContextKeyExpr.and(NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_OUTPUT_COLLAPSED), primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyCode.KeyT), @@ -427,7 +466,10 @@ registerAction2(class extends NotebookMultiCellAction { super({ id: TOGGLE_CELL_OUTPUTS_COMMAND_ID, precondition: NOTEBOOK_CELL_LIST_FOCUSED, - title: localize('notebookActions.toggleOutputs', "Toggle Outputs"), + title: { + value: localize('notebookActions.toggleOutputs', "Toggle Outputs"), + original: 'Toggle Outputs' + }, description: { description: localize('notebookActions.toggleOutputs', "Toggle Outputs"), args: cellExecutionArgs @@ -457,7 +499,10 @@ registerAction2(class CollapseAllCellInputsAction extends NotebookMultiCellActio constructor() { super({ id: COLLAPSE_ALL_CELL_INPUTS_COMMAND_ID, - title: localize('notebookActions.collapseAllCellInput', "Collapse All Cell Inputs"), + title: { + value: localize('notebookActions.collapseAllCellInput', "Collapse All Cell Inputs"), + original: 'Collapse All Cell Inputs' + }, f1: true, }); } @@ -471,7 +516,10 @@ registerAction2(class ExpandAllCellInputsAction extends NotebookMultiCellAction constructor() { super({ id: EXPAND_ALL_CELL_INPUTS_COMMAND_ID, - title: localize('notebookActions.expandAllCellInput', "Expand All Cell Inputs"), + title: { + value: localize('notebookActions.expandAllCellInput', "Expand All Cell Inputs"), + original: 'Expand All Cell Inputs' + }, f1: true }); } @@ -485,7 +533,10 @@ registerAction2(class CollapseAllCellOutputsAction extends NotebookMultiCellActi constructor() { super({ id: COLLAPSE_ALL_CELL_OUTPUTS_COMMAND_ID, - title: localize('notebookActions.collapseAllCellOutput', "Collapse All Cell Outputs"), + title: { + value: localize('notebookActions.collapseAllCellOutput', "Collapse All Cell Outputs"), + original: 'Collapse All Cell Outputs' + }, f1: true, }); } @@ -499,7 +550,10 @@ registerAction2(class ExpandAllCellOutputsAction extends NotebookMultiCellAction constructor() { super({ id: EXPAND_ALL_CELL_OUTPUTS_COMMAND_ID, - title: localize('notebookActions.expandAllCellOutput', "Expand All Cell Outputs"), + title: { + value: localize('notebookActions.expandAllCellOutput', "Expand All Cell Outputs"), + original: 'Expand All Cell Outputs' + }, f1: true }); } diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index 77782e09059..08f7dc2cf25 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -365,7 +365,10 @@ registerAction2(class CancelSearchAction extends Action2 { constructor() { super({ id: 'search.action.cancel', - title: nls.localize('CancelSearchAction.label', "Cancel Search"), + title: { + value: nls.localize('CancelSearchAction.label', "Cancel Search"), + original: 'Cancel Search' + }, icon: searchStopIcon, category, f1: true, @@ -392,7 +395,10 @@ registerAction2(class RefreshAction extends Action2 { constructor() { super({ id: 'search.action.refreshSearchResults', - title: nls.localize('RefreshAction.label', "Refresh"), + title: { + value: nls.localize('RefreshAction.label', "Refresh"), + original: 'Refresh' + }, icon: searchRefreshIcon, precondition: Constants.ViewHasSearchPatternKey, category, @@ -414,7 +420,10 @@ registerAction2(class CollapseDeepestExpandedLevelAction extends Action2 { constructor() { super({ id: 'search.action.collapseSearchResults', - title: nls.localize('CollapseDeepestExpandedLevelAction.label', "Collapse All"), + title: { + value: nls.localize('CollapseDeepestExpandedLevelAction.label', "Collapse All"), + original: 'Collapse All' + }, category, icon: searchCollapseAllIcon, f1: true, @@ -436,7 +445,10 @@ registerAction2(class ExpandAllAction extends Action2 { constructor() { super({ id: 'search.action.expandSearchResults', - title: nls.localize('ExpandAllAction.label', "Expand All"), + title: { + value: nls.localize('ExpandAllAction.label', "Expand All"), + original: 'Expand All' + }, category, icon: searchExpandAllIcon, f1: true, @@ -458,7 +470,10 @@ registerAction2(class ClearSearchResultsAction extends Action2 { constructor() { super({ id: 'search.action.clearSearchResults', - title: nls.localize('ClearSearchResultsAction.label', "Clear Search Results"), + title: { + value: nls.localize('ClearSearchResultsAction.label', "Clear Search Results"), + original: 'Clear Search Results' + }, category, icon: searchClearIcon, f1: true, -- cgit v1.2.3 From 9c724118aea8f0c4539c745c0474371fdfe21038 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 6 Jul 2022 13:50:18 -0700 Subject: re #153865. ICommandActionTitle for notebook (#154307) --- .../contrib/gettingStarted/notebookGettingStarted.ts | 5 ++++- .../notebook/browser/contrib/troubleshoot/layout.ts | 16 +++++++++++++--- .../notebook/browser/controller/layoutActions.ts | 20 ++++++++++++++++---- 3 files changed, 33 insertions(+), 8 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/gettingStarted/notebookGettingStarted.ts b/src/vs/workbench/contrib/notebook/browser/contrib/gettingStarted/notebookGettingStarted.ts index 3e1c47af18a..2165fa94cc2 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/gettingStarted/notebookGettingStarted.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/gettingStarted/notebookGettingStarted.ts @@ -81,7 +81,10 @@ registerAction2(class NotebookClearNotebookLayoutAction extends Action2 { constructor() { super({ id: 'workbench.notebook.layout.gettingStarted', - title: localize('workbench.notebook.layout.gettingStarted.label', "Reset notebook getting started"), + title: { + value: localize('workbench.notebook.layout.gettingStarted.label', "Reset notebook getting started"), + original: 'Reset notebook getting started' + }, f1: true, precondition: ContextKeyExpr.equals(`config.${NotebookSetting.openGettingStarted}`, true), category: CATEGORIES.Developer, diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/troubleshoot/layout.ts b/src/vs/workbench/contrib/notebook/browser/contrib/troubleshoot/layout.ts index b3af4143741..ab714f85b51 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/troubleshoot/layout.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/troubleshoot/layout.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Disposable, DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { localize } from 'vs/nls'; import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { CATEGORIES } from 'vs/workbench/common/actions'; @@ -121,7 +122,10 @@ registerAction2(class extends Action2 { constructor() { super({ id: 'notebook.toggleLayoutTroubleshoot', - title: 'Toggle Notebook Layout Troubleshoot', + title: { + value: localize('workbench.notebook.toggleLayoutTroubleshoot', "Toggle Layout Troubleshoot"), + original: 'Toggle Notebook Layout Troubleshoot' + }, category: CATEGORIES.Developer, f1: true }); @@ -144,7 +148,10 @@ registerAction2(class extends Action2 { constructor() { super({ id: 'notebook.inspectLayout', - title: 'Inspect Notebook Layout', + title: { + value: localize('workbench.notebook.inspectLayout', "Inspect Notebook Layout"), + original: 'Inspect Notebook Layout' + }, category: CATEGORIES.Developer, f1: true }); @@ -169,7 +176,10 @@ registerAction2(class extends Action2 { constructor() { super({ id: 'notebook.clearNotebookEdtitorTypeCache', - title: 'Clear Notebook Editor Cache', + title: { + value: localize('workbench.notebook.clearNotebookEdtitorTypeCache', "Clear Notebook Editor Type Cache"), + original: 'Clear Notebook Editor Cache' + }, category: CATEGORIES.Developer, f1: true }); diff --git a/src/vs/workbench/contrib/notebook/browser/controller/layoutActions.ts b/src/vs/workbench/contrib/notebook/browser/controller/layoutActions.ts index 4f6a3e489c5..7f6ac0a645b 100644 --- a/src/vs/workbench/contrib/notebook/browser/controller/layoutActions.ts +++ b/src/vs/workbench/contrib/notebook/browser/controller/layoutActions.ts @@ -21,7 +21,10 @@ registerAction2(class NotebookConfigureLayoutAction extends Action2 { constructor() { super({ id: 'workbench.notebook.layout.select', - title: localize('workbench.notebook.layout.select.label', "Select between Notebook Layouts"), + title: { + value: localize('workbench.notebook.layout.select.label', "Select between Notebook Layouts"), + original: 'Select between Notebook Layouts' + }, f1: true, precondition: ContextKeyExpr.equals(`config.${NotebookSetting.openGettingStarted}`, true), category: NOTEBOOK_ACTIONS_CATEGORY, @@ -57,7 +60,10 @@ registerAction2(class NotebookConfigureLayoutAction extends Action2 { constructor() { super({ id: 'workbench.notebook.layout.configure', - title: localize('workbench.notebook.layout.configure.label', "Customize Notebook Layout"), + title: { + value: localize('workbench.notebook.layout.configure.label', "Customize Notebook Layout"), + original: 'Customize Notebook Layout' + }, f1: true, category: NOTEBOOK_ACTIONS_CATEGORY, menu: [ @@ -79,7 +85,10 @@ registerAction2(class NotebookConfigureLayoutFromEditorTitle extends Action2 { constructor() { super({ id: 'workbench.notebook.layout.configure.editorTitle', - title: localize('workbench.notebook.layout.configure.label', "Customize Notebook Layout"), + title: { + value: localize('workbench.notebook.layout.configure.label', "Customize Notebook Layout"), + original: 'Customize Notebook Layout' + }, f1: false, category: NOTEBOOK_ACTIONS_CATEGORY, menu: [ @@ -177,7 +186,10 @@ registerAction2(class SaveMimeTypeDisplayOrder extends Action2 { constructor() { super({ id: 'notebook.saveMimeTypeOrder', - title: localize('notebook.saveMimeTypeOrder', 'Save Mimetype Display Order'), + title: { + value: localize('notebook.saveMimeTypeOrder', 'Save Mimetype Display Order'), + original: 'Save Mimetype Display Order' + }, f1: true, category: NOTEBOOK_ACTIONS_CATEGORY, precondition: NOTEBOOK_IS_ACTIVE_EDITOR, -- cgit v1.2.3 From 2a99db38280d48220b1c15d9bfee7d9ec2ec1666 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 6 Jul 2022 15:42:20 -0700 Subject: Remove collections.forEach (#154314) * Remove collections.forEach Fixes #154195 * return -> continue previously these were in a closure so we need to continue instead of returning --- src/vs/base/common/collections.ts | 14 ----------- src/vs/base/test/common/collections.test.ts | 21 ----------------- src/vs/workbench/api/browser/mainThreadTask.ts | 7 ++---- .../services/actions/common/menusExtensionPoint.ts | 27 +++++++++++----------- .../extensions/common/abstractExtensionService.ts | 9 ++++---- 5 files changed, 19 insertions(+), 59 deletions(-) (limited to 'src/vs') diff --git a/src/vs/base/common/collections.ts b/src/vs/base/common/collections.ts index 1f16cd438ea..d8ee92f757e 100644 --- a/src/vs/base/common/collections.ts +++ b/src/vs/base/common/collections.ts @@ -15,20 +15,6 @@ export type IStringDictionary = Record; */ export type INumberDictionary = Record; -/** - * Iterates over each entry in the provided dictionary. The iterator will stop when the callback returns `false`. - * - * @deprecated Use `Object.entries(x)` with a `for...of` loop. - */ -export function forEach(from: IStringDictionary | INumberDictionary, callback: (entry: { key: any; value: T }) => any): void { - for (const [key, value] of Object.entries(from)) { - const result = callback({ key, value }); - if (result === false) { - return; - } - } -} - /** * Groups the collection into a dictionary based on the provided * group function. diff --git a/src/vs/base/test/common/collections.test.ts b/src/vs/base/test/common/collections.test.ts index 138d7486390..9dfe59a58fe 100644 --- a/src/vs/base/test/common/collections.test.ts +++ b/src/vs/base/test/common/collections.test.ts @@ -8,27 +8,6 @@ import * as collections from 'vs/base/common/collections'; suite('Collections', () => { - test('forEach', () => { - collections.forEach({}, () => assert(false)); - collections.forEach(Object.create(null), () => assert(false)); - - let count = 0; - collections.forEach({ toString: 123 }, () => count++); - assert.strictEqual(count, 1); - - count = 0; - const dict = Object.create(null); - dict['toString'] = 123; - collections.forEach(dict, () => count++); - assert.strictEqual(count, 1); - - collections.forEach(dict, () => false); - - // don't iterate over properties that are not on the object itself - const test = Object.create({ 'derived': true }); - collections.forEach(test, () => assert(false)); - }); - test('groupBy', () => { const group1 = 'a', group2 = 'b'; diff --git a/src/vs/workbench/api/browser/mainThreadTask.ts b/src/vs/workbench/api/browser/mainThreadTask.ts index e40b95ad866..be081d8e61f 100644 --- a/src/vs/workbench/api/browser/mainThreadTask.ts +++ b/src/vs/workbench/api/browser/mainThreadTask.ts @@ -9,7 +9,7 @@ import { URI, UriComponents } from 'vs/base/common/uri'; import { generateUuid } from 'vs/base/common/uuid'; import * as Types from 'vs/base/common/types'; import * as Platform from 'vs/base/common/platform'; -import { IStringDictionary, forEach } from 'vs/base/common/collections'; +import { IStringDictionary } from 'vs/base/common/collections'; import { IDisposable } from 'vs/base/common/lifecycle'; import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; @@ -682,10 +682,7 @@ export class MainThreadTask implements MainThreadTaskShape { const vars: string[] = []; toResolve.variables.forEach(item => vars.push(item)); return Promise.resolve(this._proxy.$resolveVariables(workspaceFolder.uri, { process: toResolve.process, variables: vars })).then(values => { - const partiallyResolvedVars = new Array(); - forEach(values.variables, (entry) => { - partiallyResolvedVars.push(entry.value); - }); + const partiallyResolvedVars = Array.from(Object.values(values.variables)); return new Promise((resolve, reject) => { this._configurationResolverService.resolveWithInteraction(workspaceFolder, partiallyResolvedVars, 'tasks', undefined, target).then(resolvedVars => { if (!resolvedVars) { diff --git a/src/vs/workbench/services/actions/common/menusExtensionPoint.ts b/src/vs/workbench/services/actions/common/menusExtensionPoint.ts index e1b8f018998..3d0d3b0206d 100644 --- a/src/vs/workbench/services/actions/common/menusExtensionPoint.ts +++ b/src/vs/workbench/services/actions/common/menusExtensionPoint.ts @@ -7,7 +7,6 @@ import { localize } from 'vs/nls'; import { isFalsyOrWhitespace } from 'vs/base/common/strings'; import * as resources from 'vs/base/common/resources'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; -import { forEach } from 'vs/base/common/collections'; import { IExtensionPointUser, ExtensionMessageCollector, ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { MenuId, MenuRegistry, IMenuItem, ISubmenuItem } from 'vs/platform/actions/common/actions'; @@ -749,19 +748,19 @@ menusExtensionPoint.setHandler(extensions => { for (const extension of extensions) { const { value, collector } = extension; - forEach(value, entry => { - if (!schema.isValidItems(entry.value, collector)) { - return; + for (const entry of Object.entries(value)) { + if (!schema.isValidItems(entry[1], collector)) { + continue; } - let menu = _apiMenusByKey.get(entry.key); + let menu = _apiMenusByKey.get(entry[0]); if (!menu) { - const submenu = _submenus.get(entry.key); + const submenu = _submenus.get(entry[0]); if (submenu) { menu = { - key: entry.key, + key: entry[0], id: submenu.id, description: '' }; @@ -769,16 +768,16 @@ menusExtensionPoint.setHandler(extensions => { } if (!menu) { - collector.info(localize('menuId.invalid', "`{0}` is not a valid menu identifier", entry.key)); - return; + collector.info(localize('menuId.invalid', "`{0}` is not a valid menu identifier", entry[0])); + continue; } if (menu.proposed && !isProposedApiEnabled(extension.description, menu.proposed)) { - collector.error(localize('proposedAPI.invalid', "{0} is a proposed menu identifier. It requires 'package.json#enabledApiProposals: [\"{1}\"]' and is only available when running out of dev or with the following command line switch: --enable-proposed-api {2}", entry.key, menu.proposed, extension.description.identifier.value)); - return; + collector.error(localize('proposedAPI.invalid', "{0} is a proposed menu identifier. It requires 'package.json#enabledApiProposals: [\"{1}\"]' and is only available when running out of dev or with the following command line switch: --enable-proposed-api {2}", entry[0], menu.proposed, extension.description.identifier.value)); + continue; } - for (const menuItem of entry.value) { + for (const menuItem of entry[1]) { let item: IMenuItem | ISubmenuItem; if (schema.isMenuItem(menuItem)) { @@ -818,7 +817,7 @@ menusExtensionPoint.setHandler(extensions => { } if (submenuRegistrations.has(submenu.id.id)) { - collector.warn(localize('submenuItem.duplicate', "The `{0}` submenu was already contributed to the `{1}` menu.", menuItem.submenu, entry.key)); + collector.warn(localize('submenuItem.duplicate', "The `{0}` submenu was already contributed to the `{1}` menu.", menuItem.submenu, entry[0])); continue; } @@ -840,7 +839,7 @@ menusExtensionPoint.setHandler(extensions => { item.when = ContextKeyExpr.deserialize(menuItem.when); items.push({ id: menu.id, item }); } - }); + } } _menuRegistrations.add(MenuRegistry.appendMenuItems(items)); diff --git a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts index 5314122757d..76589d23182 100644 --- a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts @@ -34,7 +34,6 @@ import { URI } from 'vs/base/common/uri'; import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService'; import { dedupExtensions } from 'vs/workbench/services/extensions/common/extensionsUtil'; import { ApiProposalName, allApiProposals } from 'vs/workbench/services/extensions/common/extensionsApiProposals'; -import { forEach } from 'vs/base/common/collections'; import { ILogService } from 'vs/platform/log/common/log'; import { IExtensionHostExitInfo, IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle'; @@ -1479,9 +1478,9 @@ class ProposedApiController { // NEW world - product.json spells out what proposals each extension can use if (productService.extensionEnabledApiProposals) { - forEach(productService.extensionEnabledApiProposals, entry => { - const key = ExtensionIdentifier.toKey(entry.key); - const proposalNames = entry.value.filter(name => { + for (const [k, value] of Object.entries(productService.extensionEnabledApiProposals)) { + const key = ExtensionIdentifier.toKey(k); + const proposalNames = value.filter(name => { if (!allApiProposals[name]) { _logService.warn(`Via 'product.json#extensionEnabledApiProposals' extension '${key}' wants API proposal '${name}' but that proposal DOES NOT EXIST. Likely, the proposal has been finalized (check 'vscode.d.ts') or was abandoned.`); return false; @@ -1489,7 +1488,7 @@ class ProposedApiController { return true; }); this._productEnabledExtensions.set(key, proposalNames); - }); + } } } -- cgit v1.2.3 From 3d3bfced969d0ffd1fdc7a1938cc26bbd64d9d42 Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Wed, 6 Jul 2022 15:46:56 -0700 Subject: Commands for Navigating Call Stack (#154117) Commands to navigate the call stack Fixes #149975 --- .../contrib/debug/browser/debug.contribution.ts | 7 +- .../contrib/debug/browser/debugCommands.ts | 140 ++++++++++++++++++++- .../contrib/debug/browser/debugSession.ts | 2 +- src/vs/workbench/contrib/debug/common/debug.ts | 2 + .../workbench/contrib/debug/common/debugModel.ts | 26 +++- 5 files changed, 172 insertions(+), 5 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts index bebcecd9455..54d0f0a0e7c 100644 --- a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts @@ -20,7 +20,7 @@ import { } from 'vs/workbench/contrib/debug/common/debug'; import { DebugToolBar } from 'vs/workbench/contrib/debug/browser/debugToolBar'; import { DebugService } from 'vs/workbench/contrib/debug/browser/debugService'; -import { ADD_CONFIGURATION_ID, TOGGLE_INLINE_BREAKPOINT_ID, COPY_STACK_TRACE_ID, RESTART_SESSION_ID, TERMINATE_THREAD_ID, STEP_OVER_ID, STEP_INTO_ID, STEP_OUT_ID, PAUSE_ID, DISCONNECT_ID, STOP_ID, RESTART_FRAME_ID, CONTINUE_ID, FOCUS_REPL_ID, JUMP_TO_CURSOR_ID, RESTART_LABEL, STEP_INTO_LABEL, STEP_OVER_LABEL, STEP_OUT_LABEL, PAUSE_LABEL, DISCONNECT_LABEL, STOP_LABEL, CONTINUE_LABEL, DEBUG_START_LABEL, DEBUG_START_COMMAND_ID, DEBUG_RUN_LABEL, DEBUG_RUN_COMMAND_ID, EDIT_EXPRESSION_COMMAND_ID, REMOVE_EXPRESSION_COMMAND_ID, SELECT_AND_START_ID, SELECT_AND_START_LABEL, SET_EXPRESSION_COMMAND_ID, DISCONNECT_AND_SUSPEND_ID, DISCONNECT_AND_SUSPEND_LABEL, NEXT_DEBUG_CONSOLE_ID, NEXT_DEBUG_CONSOLE_LABEL, PREV_DEBUG_CONSOLE_ID, PREV_DEBUG_CONSOLE_LABEL, OPEN_LOADED_SCRIPTS_LABEL, SHOW_LOADED_SCRIPTS_ID, DEBUG_QUICK_ACCESS_PREFIX, DEBUG_CONSOLE_QUICK_ACCESS_PREFIX, SELECT_DEBUG_CONSOLE_ID, SELECT_DEBUG_CONSOLE_LABEL, STEP_INTO_TARGET_LABEL, STEP_INTO_TARGET_ID, DEBUG_COMMAND_CATEGORY } from 'vs/workbench/contrib/debug/browser/debugCommands'; +import { ADD_CONFIGURATION_ID, TOGGLE_INLINE_BREAKPOINT_ID, COPY_STACK_TRACE_ID, RESTART_SESSION_ID, TERMINATE_THREAD_ID, STEP_OVER_ID, STEP_INTO_ID, STEP_OUT_ID, PAUSE_ID, DISCONNECT_ID, STOP_ID, RESTART_FRAME_ID, CONTINUE_ID, FOCUS_REPL_ID, JUMP_TO_CURSOR_ID, RESTART_LABEL, STEP_INTO_LABEL, STEP_OVER_LABEL, STEP_OUT_LABEL, PAUSE_LABEL, DISCONNECT_LABEL, STOP_LABEL, CONTINUE_LABEL, DEBUG_START_LABEL, DEBUG_START_COMMAND_ID, DEBUG_RUN_LABEL, DEBUG_RUN_COMMAND_ID, EDIT_EXPRESSION_COMMAND_ID, REMOVE_EXPRESSION_COMMAND_ID, SELECT_AND_START_ID, SELECT_AND_START_LABEL, SET_EXPRESSION_COMMAND_ID, DISCONNECT_AND_SUSPEND_ID, DISCONNECT_AND_SUSPEND_LABEL, NEXT_DEBUG_CONSOLE_ID, NEXT_DEBUG_CONSOLE_LABEL, PREV_DEBUG_CONSOLE_ID, PREV_DEBUG_CONSOLE_LABEL, OPEN_LOADED_SCRIPTS_LABEL, SHOW_LOADED_SCRIPTS_ID, DEBUG_QUICK_ACCESS_PREFIX, DEBUG_CONSOLE_QUICK_ACCESS_PREFIX, SELECT_DEBUG_CONSOLE_ID, SELECT_DEBUG_CONSOLE_LABEL, STEP_INTO_TARGET_LABEL, STEP_INTO_TARGET_ID, CALLSTACK_TOP_ID, CALLSTACK_TOP_LABEL, CALLSTACK_BOTTOM_LABEL, CALLSTACK_UP_LABEL, CALLSTACK_BOTTOM_ID, CALLSTACK_UP_ID, CALLSTACK_DOWN_ID, CALLSTACK_DOWN_LABEL, DEBUG_COMMAND_CATEGORY } from 'vs/workbench/contrib/debug/browser/debugCommands'; import { StatusBarColorProvider } from 'vs/workbench/contrib/debug/browser/statusbarColorProvider'; import { IViewsRegistry, Extensions as ViewExtensions, IViewContainersRegistry, ViewContainerLocation, ViewContainer } from 'vs/workbench/common/views'; import { isMacintosh, isWeb } from 'vs/base/common/platform'; @@ -136,7 +136,10 @@ registerDebugCommandPaletteItem(NEXT_DEBUG_CONSOLE_ID, NEXT_DEBUG_CONSOLE_LABEL) registerDebugCommandPaletteItem(PREV_DEBUG_CONSOLE_ID, PREV_DEBUG_CONSOLE_LABEL); registerDebugCommandPaletteItem(SHOW_LOADED_SCRIPTS_ID, OPEN_LOADED_SCRIPTS_LABEL, CONTEXT_IN_DEBUG_MODE); registerDebugCommandPaletteItem(SELECT_DEBUG_CONSOLE_ID, SELECT_DEBUG_CONSOLE_LABEL); - +registerDebugCommandPaletteItem(CALLSTACK_TOP_ID, CALLSTACK_TOP_LABEL, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped')); +registerDebugCommandPaletteItem(CALLSTACK_BOTTOM_ID, CALLSTACK_BOTTOM_LABEL, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped')); +registerDebugCommandPaletteItem(CALLSTACK_UP_ID, CALLSTACK_UP_LABEL, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped')); +registerDebugCommandPaletteItem(CALLSTACK_DOWN_ID, CALLSTACK_DOWN_LABEL, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped')); // Debug callstack context menu const registerDebugViewMenuItem = (menuId: MenuId, id: string, title: string | ICommandActionTitle, order: number, when?: ContextKeyExpression, precondition?: ContextKeyExpression, group = 'navigation', icon?: Icon) => { diff --git a/src/vs/workbench/contrib/debug/browser/debugCommands.ts b/src/vs/workbench/contrib/debug/browser/debugCommands.ts index 86fa5b8c01b..25da3464ac6 100644 --- a/src/vs/workbench/contrib/debug/browser/debugCommands.ts +++ b/src/vs/workbench/contrib/debug/browser/debugCommands.ts @@ -9,7 +9,7 @@ import { List } from 'vs/base/browser/ui/list/listWidget'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IListService } from 'vs/platform/list/browser/listService'; import { IDebugService, IEnablement, CONTEXT_BREAKPOINTS_FOCUSED, CONTEXT_WATCH_EXPRESSIONS_FOCUSED, CONTEXT_VARIABLES_FOCUSED, EDITOR_CONTRIBUTION_ID, IDebugEditorContribution, CONTEXT_IN_DEBUG_MODE, CONTEXT_EXPRESSION_SELECTED, IConfig, IStackFrame, IThread, IDebugSession, CONTEXT_DEBUG_STATE, IDebugConfiguration, CONTEXT_JUMP_TO_CURSOR_SUPPORTED, REPL_VIEW_ID, CONTEXT_DEBUGGERS_AVAILABLE, State, getStateLabel, CONTEXT_BREAKPOINT_INPUT_FOCUSED, CONTEXT_FOCUSED_SESSION_IS_ATTACH, VIEWLET_ID, CONTEXT_DISASSEMBLY_VIEW_FOCUS, CONTEXT_IN_DEBUG_REPL, CONTEXT_STEP_INTO_TARGETS_SUPPORTED } from 'vs/workbench/contrib/debug/common/debug'; -import { Expression, Variable, Breakpoint, FunctionBreakpoint, DataBreakpoint } from 'vs/workbench/contrib/debug/common/debugModel'; +import { Expression, Variable, Breakpoint, FunctionBreakpoint, DataBreakpoint, Thread } from 'vs/workbench/contrib/debug/common/debugModel'; import { IExtensionsViewPaneContainer, VIEWLET_ID as EXTENSIONS_VIEWLET_ID } from 'vs/workbench/contrib/extensions/common/extensions'; import { ICodeEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; @@ -64,6 +64,10 @@ export const REMOVE_EXPRESSION_COMMAND_ID = 'debug.removeWatchExpression'; export const NEXT_DEBUG_CONSOLE_ID = 'workbench.action.debug.nextConsole'; export const PREV_DEBUG_CONSOLE_ID = 'workbench.action.debug.prevConsole'; export const SHOW_LOADED_SCRIPTS_ID = 'workbench.action.debug.showLoadedScripts'; +export const CALLSTACK_TOP_ID = 'workbench.action.debug.callStackTop'; +export const CALLSTACK_BOTTOM_ID = 'workbench.action.debug.callStackBottom'; +export const CALLSTACK_UP_ID = 'workbench.action.debug.callStackUp'; +export const CALLSTACK_DOWN_ID = 'workbench.action.debug.callStackDown'; export const DEBUG_COMMAND_CATEGORY = 'Debug'; export const RESTART_LABEL = { value: nls.localize('restartDebug', "Restart"), original: 'Restart' }; @@ -84,6 +88,10 @@ export const DEBUG_RUN_LABEL = { value: nls.localize('startWithoutDebugging', "S export const NEXT_DEBUG_CONSOLE_LABEL = { value: nls.localize('nextDebugConsole', "Focus Next Debug Console"), original: 'Focus Next Debug Console' }; export const PREV_DEBUG_CONSOLE_LABEL = { value: nls.localize('prevDebugConsole', "Focus Previous Debug Console"), original: 'Focus Previous Debug Console' }; export const OPEN_LOADED_SCRIPTS_LABEL = { value: nls.localize('openLoadedScript', "Open Loaded Script..."), original: 'Open Loaded Script...' }; +export const CALLSTACK_TOP_LABEL = { value: nls.localize('callStackTop', "Navigate to Top of Call Stack"), original: 'Navigate to Top of Call Stack' }; +export const CALLSTACK_BOTTOM_LABEL = { value: nls.localize('callStackBottom', "Navigate to Bottom of Call Stack"), original: 'Navigate to Bottom of Call Stack' }; +export const CALLSTACK_UP_LABEL = { value: nls.localize('callStackUp', "Navigate Up Call Stack"), original: 'Navigate Up Call Stack' }; +export const CALLSTACK_DOWN_LABEL = { value: nls.localize('callStackDown', "Navigate Down Call Stack"), original: 'Navigate Down Call Stack' }; export const SELECT_DEBUG_CONSOLE_LABEL = { value: nls.localize('selectDebugConsole', "Select Debug Console"), original: 'Select Debug Console' }; @@ -180,6 +188,103 @@ async function changeDebugConsoleFocus(accessor: ServicesAccessor, next: boolean } } +async function navigateCallStack(debugService: IDebugService, down: boolean) { + const frame = debugService.getViewModel().focusedStackFrame; + if (frame) { + + let callStack = frame.thread.getCallStack(); + let index = callStack.findIndex(elem => elem.frameId === frame.frameId); + let nextVisibleFrame; + if (down) { + if (index >= callStack.length - 1) { + if ((frame.thread).reachedEndOfCallStack) { + goToTopOfCallStack(debugService); + return; + } else { + await debugService.getModel().fetchCallstack(frame.thread, 20); + callStack = frame.thread.getCallStack(); + index = callStack.findIndex(elem => elem.frameId === frame.frameId); + } + } + nextVisibleFrame = findNextVisibleFrame(true, callStack, index); + } else { + if (index <= 0) { + goToBottomOfCallStack(debugService); + return; + } + nextVisibleFrame = findNextVisibleFrame(false, callStack, index); + } + + if (nextVisibleFrame) { + debugService.focusStackFrame(nextVisibleFrame); + } + } +} + +async function goToBottomOfCallStack(debugService: IDebugService) { + const thread = debugService.getViewModel().focusedThread; + if (thread) { + await debugService.getModel().fetchCallstack(thread); + const callStack = thread.getCallStack(); + if (callStack.length > 0) { + const nextVisibleFrame = findNextVisibleFrame(false, callStack, 0); // must consider the next frame up first, which will be the last frame + if (nextVisibleFrame) { + debugService.focusStackFrame(nextVisibleFrame); + } + } + } +} + +function goToTopOfCallStack(debugService: IDebugService) { + const thread = debugService.getViewModel().focusedThread; + + if (thread) { + debugService.focusStackFrame(thread.getTopStackFrame()); + } +} + +/** + * Finds next frame that is not skipped by SkipFiles. Skips frame at index and starts searching at next. + * Must satisfy `0 <= startIndex <= callStack - 1` + * @param down specifies whether to search downwards if the current file is skipped. + * @param callStack the call stack to search + * @param startIndex the index to start the search at + */ +function findNextVisibleFrame(down: boolean, callStack: readonly IStackFrame[], startIndex: number) { + + if (startIndex >= callStack.length) { + startIndex = callStack.length - 1; + } else if (startIndex < 0) { + startIndex = 0; + } + + let index = startIndex; + + let currFrame; + do { + if (down) { + if (index === callStack.length - 1) { + index = 0; + } else { + index++; + } + } else { + if (index === 0) { + index = callStack.length - 1; + } else { + index--; + } + } + + currFrame = callStack[index]; + if (!(currFrame.source.presentationHint === 'deemphasize' || currFrame.presentationHint === 'deemphasize')) { + return currFrame; + } + } while (index !== startIndex); // end loop when we've just checked the start index, since that should be the last one checked + + return undefined; +} + // These commands are used in call stack context menu, call stack inline actions, command palette, debug toolbar, mac native touch bar // When the command is exectued in the context of a thread(context menu on a thread, inline call stack action) we pass the thread id // Otherwise when it is executed "globaly"(using the touch bar, debug toolbar, command palette) we do not pass any id and just take whatever is the focussed thread @@ -261,6 +366,39 @@ CommandsRegistry.registerCommand({ } }); + +CommandsRegistry.registerCommand({ + id: CALLSTACK_TOP_ID, + handler: async (accessor: ServicesAccessor, _: string, context: CallStackContext | unknown) => { + const debugService = accessor.get(IDebugService); + goToTopOfCallStack(debugService); + } +}); + +CommandsRegistry.registerCommand({ + id: CALLSTACK_BOTTOM_ID, + handler: async (accessor: ServicesAccessor, _: string, context: CallStackContext | unknown) => { + const debugService = accessor.get(IDebugService); + await goToBottomOfCallStack(debugService); + } +}); + +CommandsRegistry.registerCommand({ + id: CALLSTACK_UP_ID, + handler: async (accessor: ServicesAccessor, _: string, context: CallStackContext | unknown) => { + const debugService = accessor.get(IDebugService); + navigateCallStack(debugService, false); + } +}); + +CommandsRegistry.registerCommand({ + id: CALLSTACK_DOWN_ID, + handler: async (accessor: ServicesAccessor, _: string, context: CallStackContext | unknown) => { + const debugService = accessor.get(IDebugService); + navigateCallStack(debugService, true); + } +}); + MenuRegistry.appendMenuItem(MenuId.EditorContext, { command: { id: JUMP_TO_CURSOR_ID, diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index 4a53a4e0c93..de26f713ef0 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -955,7 +955,7 @@ export class DebugSession implements IDebugSession { if (thread) { // Call fetch call stack twice, the first only return the top stack frame. // Second retrieves the rest of the call stack. For performance reasons #25605 - const promises = this.model.fetchCallStack(thread); + const promises = this.model.refreshTopOfCallstack(thread); const focus = async () => { if (focusedThreadDoesNotExist || (!event.body.preserveFocusHint && thread.getCallStack().length)) { const focusedStackFrame = this.debugService.getViewModel().focusedStackFrame; diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index baac9206484..a8397f69aef 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -602,6 +602,8 @@ export interface IDebugModel extends ITreeElement { onDidChangeBreakpoints: Event; onDidChangeCallStack: Event; onDidChangeWatchExpressions: Event; + + fetchCallstack(thread: IThread, levels?: number): Promise; } /** diff --git a/src/vs/workbench/contrib/debug/common/debugModel.ts b/src/vs/workbench/contrib/debug/common/debugModel.ts index 4b20e069cd2..1f50eb36368 100644 --- a/src/vs/workbench/contrib/debug/common/debugModel.ts +++ b/src/vs/workbench/contrib/debug/common/debugModel.ts @@ -1244,7 +1244,31 @@ export class DebugModel implements IDebugModel { } } - fetchCallStack(thread: Thread): { topCallStack: Promise; wholeCallStack: Promise } { + /** + * Update the call stack and notify the call stack view that changes have occurred. + */ + async fetchCallstack(thread: IThread, levels?: number): Promise { + + if ((thread).reachedEndOfCallStack) { + return; + } + + const totalFrames = thread.stoppedDetails?.totalFrames; + const remainingFrames = (typeof totalFrames === 'number') ? (totalFrames - thread.getCallStack().length) : undefined; + + if (!levels || (remainingFrames && levels > remainingFrames)) { + levels = remainingFrames; + } + + if (levels && levels > 0) { + await (thread).fetchCallStack(levels); + this._onDidChangeCallStack.fire(); + } + + return; + } + + refreshTopOfCallstack(thread: Thread): { topCallStack: Promise; wholeCallStack: Promise } { if (thread.session.capabilities.supportsDelayedStackTraceLoading) { // For improved performance load the first stack frame and then load the rest async. let topCallStack = Promise.resolve(); -- cgit v1.2.3 From a6238ac59c487435fb5810986771999f1d6ea8bb Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 15:15:03 -0700 Subject: Add icon in defaultIcon description --- src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index c1f9c0af306..acdd4ce698d 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -58,6 +58,7 @@ const terminalConfiguration: IConfigurationNode = { description: localize('terminal.integrated.tabs.defaultIcon', "Controls the terminal tab's default icon."), type: 'string', enum: Codicon.getAll().map(icon => icon.id), + markdownEnumDescriptions: Array.from(Codicon.getAll(), icon => `$(${icon.id})`), default: undefined, }, [TerminalSettingId.TabsEnabled]: { -- cgit v1.2.3 From 510656a44a5dfa3ad63190f0641018d858e222a9 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:02:50 -0700 Subject: Replace all Terminal codicon references with default icon --- .../common/terminalPlatformConfiguration.ts | 38 +++++++++++++--------- .../contrib/terminal/browser/terminalActions.ts | 3 +- .../contrib/terminal/browser/terminalIcon.ts | 7 ++-- .../contrib/terminal/browser/terminalInstance.ts | 5 ++- .../terminal/browser/terminalProfileQuickpick.ts | 5 +-- .../browser/terminalProfileResolverService.ts | 17 +++++++--- .../terminal/browser/terminalQuickAccess.ts | 6 ++-- .../contrib/terminal/browser/terminalTabsList.ts | 2 +- .../contrib/terminal/browser/terminalView.ts | 10 +++--- .../workbench/contrib/terminal/common/terminal.ts | 2 ++ .../terminal/common/terminalConfiguration.ts | 24 ++++---------- .../test/browser/workbenchTestServices.ts | 6 ++-- 12 files changed, 72 insertions(+), 53 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminalPlatformConfiguration.ts b/src/vs/platform/terminal/common/terminalPlatformConfiguration.ts index 9dc40ebec2c..79db8443a33 100644 --- a/src/vs/platform/terminal/common/terminalPlatformConfiguration.ts +++ b/src/vs/platform/terminal/common/terminalPlatformConfiguration.ts @@ -12,6 +12,27 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IExtensionTerminalProfile, ITerminalProfile, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; import { createProfileSchemaEnums } from 'vs/platform/terminal/common/terminalProfiles'; +export const terminalColorSchema: IJSONSchema = { + type: ['string', 'null'], + enum: [ + 'terminal.ansiBlack', + 'terminal.ansiRed', + 'terminal.ansiGreen', + 'terminal.ansiYellow', + 'terminal.ansiBlue', + 'terminal.ansiMagenta', + 'terminal.ansiCyan', + 'terminal.ansiWhite' + ], + default: null +}; + +export const terminalIconSchema: IJSONSchema = { + type: 'string', + enum: Array.from(Codicon.getAll(), icon => icon.id), + markdownEnumDescriptions: Array.from(Codicon.getAll(), icon => `$(${icon.id})`), +}; + const terminalProfileBaseProperties: IJSONSchemaMap = { args: { description: localize('terminalProfile.args', 'An optional set of arguments to run the shell executable with.'), @@ -26,24 +47,11 @@ const terminalProfileBaseProperties: IJSONSchemaMap = { }, icon: { description: localize('terminalProfile.icon', 'A codicon ID to associate with this terminal.'), - type: 'string', - enum: Array.from(Codicon.getAll(), icon => icon.id), - markdownEnumDescriptions: Array.from(Codicon.getAll(), icon => `$(${icon.id})`), + ...terminalIconSchema }, color: { description: localize('terminalProfile.color', 'A theme color ID to associate with this terminal.'), - type: ['string', 'null'], - enum: [ - 'terminal.ansiBlack', - 'terminal.ansiRed', - 'terminal.ansiGreen', - 'terminal.ansiYellow', - 'terminal.ansiBlue', - 'terminal.ansiMagenta', - 'terminal.ansiCyan', - 'terminal.ansiWhite' - ], - default: null + ...terminalColorSchema }, env: { markdownDescription: localize('terminalProfile.env', "An object with environment variables that will be added to the terminal profile process. Set to `null` to delete environment variables from the base environment."), diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 0c70784c0e3..540f153ea32 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -1709,6 +1709,7 @@ export function registerTerminalActions() { const themeService = accessor.get(IThemeService); const groupService = accessor.get(ITerminalGroupService); const notificationService = accessor.get(INotificationService); + const picks: ITerminalQuickPickItem[] = []; if (groupService.instances.length <= 1) { notificationService.warn(localize('workbench.action.terminal.join.insufficientTerminals', 'Insufficient terminals for the join action')); @@ -1718,7 +1719,7 @@ export function registerTerminalActions() { for (const terminal of otherInstances) { const group = groupService.getGroupForInstance(terminal); if (group?.terminalInstances.length === 1) { - const iconId = getIconId(terminal); + const iconId = getIconId(accessor, terminal); const label = `$(${iconId}): ${terminal.title}`; const iconClasses: string[] = []; const colorClass = getColorClass(terminal); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalIcon.ts b/src/vs/workbench/contrib/terminal/browser/terminalIcon.ts index b098cc3ece1..89acbedfa80 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalIcon.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalIcon.ts @@ -3,14 +3,15 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Codicon } from 'vs/base/common/codicons'; import { hash } from 'vs/base/common/hash'; import { URI } from 'vs/base/common/uri'; +import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IExtensionTerminalProfile, ITerminalProfile } from 'vs/platform/terminal/common/terminal'; import { getIconRegistry } from 'vs/platform/theme/common/iconRegistry'; import { ColorScheme } from 'vs/platform/theme/common/theme'; import { IColorTheme, ThemeIcon } from 'vs/platform/theme/common/themeService'; import { ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { ITerminalProfileResolverService } from 'vs/workbench/contrib/terminal/common/terminal'; import { ansiColorMap } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; @@ -116,9 +117,9 @@ export function getUriClasses(terminal: ITerminalInstance | IExtensionTerminalPr return iconClasses; } -export function getIconId(terminal: ITerminalInstance | IExtensionTerminalProfile | ITerminalProfile): string { +export function getIconId(accessor: ServicesAccessor, terminal: ITerminalInstance | IExtensionTerminalProfile | ITerminalProfile): string { if (!terminal.icon || (terminal.icon instanceof Object && !('id' in terminal.icon))) { - return Codicon.terminal.id; + return accessor.get(ITerminalProfileResolverService).getDefaultIcon().id; } return typeof terminal.icon === 'string' ? terminal.icon : terminal.icon.id; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index edf4d2b4198..a02e18413dc 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -86,6 +86,7 @@ import type { IMarker, ITerminalAddon, Terminal as XTermTerminal } from 'xterm'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IGenericMarkProperties } from 'vs/platform/terminal/common/terminalProcess'; import { ICommandService } from 'vs/platform/commands/common/commands'; +import { getIconRegistry } from 'vs/platform/theme/common/iconRegistry'; const enum Constants { /** @@ -548,7 +549,9 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { private _getIcon(): TerminalIcon | undefined { if (!this._icon) { - this._icon = this._processManager.processState >= ProcessState.Launching ? Codicon.terminal : undefined; + this._icon = this._processManager.processState >= ProcessState.Launching + ? getIconRegistry().getIcon(this._configurationService.getValue(TerminalSettingId.TabsDefaultIcon)) + : undefined; } return this._icon; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProfileQuickpick.ts b/src/vs/workbench/contrib/terminal/browser/terminalProfileQuickpick.ts index e715b730b66..e67654f2c70 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProfileQuickpick.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProfileQuickpick.ts @@ -11,7 +11,7 @@ import { getUriClasses, getColorClass, getColorStyleElement } from 'vs/workbench import { configureTerminalProfileIcon } from 'vs/workbench/contrib/terminal/browser/terminalIcons'; import * as nls from 'vs/nls'; import { IThemeService, ThemeIcon } from 'vs/platform/theme/common/themeService'; -import { ITerminalProfileService } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalProfileResolverService, ITerminalProfileService } from 'vs/workbench/contrib/terminal/common/terminal'; import { IQuickPickTerminalObject, ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal'; import { IPickerQuickAccessItem } from 'vs/platform/quickinput/browser/pickerQuickAccess'; import { getIconRegistry } from 'vs/platform/theme/common/iconRegistry'; @@ -22,6 +22,7 @@ type DefaultProfileName = string; export class TerminalProfileQuickpick { constructor( @ITerminalProfileService private readonly _terminalProfileService: ITerminalProfileService, + @ITerminalProfileResolverService private readonly _terminalProfileResolverService: ITerminalProfileResolverService, @IConfigurationService private readonly _configurationService: IConfigurationService, @IQuickInputService private readonly _quickInputService: IQuickInputService, @IThemeService private readonly _themeService: IThemeService @@ -155,7 +156,7 @@ export class TerminalProfileQuickpick { } } if (!icon || !getIconRegistry().getIcon(icon.id)) { - icon = Codicon.terminal; + icon = this._terminalProfileResolverService.getDefaultIcon(); } const uriClasses = getUriClasses(contributed, this._themeService.getColorTheme().type, true); const colorClass = getColorClass(contributed); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts index 1554d580f33..2abd550fedc 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts @@ -97,11 +97,11 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro resolveIcon(shellLaunchConfig: IShellLaunchConfig, os: OperatingSystem): void { if (shellLaunchConfig.icon) { - shellLaunchConfig.icon = this._getCustomIcon(shellLaunchConfig.icon) || Codicon.terminal; + shellLaunchConfig.icon = this._getCustomIcon(shellLaunchConfig.icon) || this.getDefaultIcon(); return; } if (shellLaunchConfig.customPtyImplementation) { - shellLaunchConfig.icon = Codicon.terminal; + shellLaunchConfig.icon = this.getDefaultIcon(); return; } if (shellLaunchConfig.executable) { @@ -111,6 +111,13 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro if (defaultProfile) { shellLaunchConfig.icon = defaultProfile.icon; } + if (!shellLaunchConfig.icon) { + shellLaunchConfig.icon = this.getDefaultIcon(); + } + } + + getDefaultIcon(): TerminalIcon & ThemeIcon { + return this._iconRegistry.getIcon(this._configurationService.getValue(TerminalSettingId.TabsDefaultIcon)) || Codicon.terminal; } async resolveShellLaunchConfig(shellLaunchConfig: IShellLaunchConfig, options: IShellLaunchConfigResolveOptions): Promise { @@ -138,10 +145,11 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro // Verify the icon is valid, and fallback correctly to the generic terminal id if there is // an issue + console.log('icon', this._configurationService.getValue(TerminalSettingId.TabsDefaultIcon)); shellLaunchConfig.icon = this._getCustomIcon(shellLaunchConfig.icon) || this._getCustomIcon(resolvedProfile.icon) - || this._iconRegistry.getIcon(this._configurationService.getValue(TerminalSettingId.TabsDefaultIcon)) - || Codicon.terminal; + || this.getDefaultIcon(); + console.log('icon2', shellLaunchConfig.icon); // Override the name if specified if (resolvedProfile.overrideName) { @@ -240,6 +248,7 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro if (defaultProfileName && typeof defaultProfileName === 'string') { return this._terminalProfileService.availableProfiles.find(e => e.profileName === defaultProfileName); } + return undefined; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalQuickAccess.ts b/src/vs/workbench/contrib/terminal/browser/terminalQuickAccess.ts index af7953a3268..71bdeeb5de4 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalQuickAccess.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalQuickAccess.ts @@ -16,6 +16,7 @@ import { getColorClass, getIconId, getUriClasses } from 'vs/workbench/contrib/te import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings'; import { TerminalLocation } from 'vs/platform/terminal/common/terminal'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; let terminalPicks: Array = []; export class TerminalQuickAccessProvider extends PickerQuickAccessProvider { @@ -27,7 +28,8 @@ export class TerminalQuickAccessProvider extends PickerQuickAccessProvider 1 ? `${groupInfo.groupIndex + 1}.${terminalIndex + 1}` diff --git a/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts b/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts index d9fc17533ed..14890b1b9bf 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts @@ -309,7 +309,7 @@ class TerminalTabsRenderer implements IListRenderer; getDefaultShell(options: IShellLaunchConfigResolveOptions): Promise; getDefaultShellArgs(options: IShellLaunchConfigResolveOptions): Promise; + getDefaultIcon(): TerminalIcon & ThemeIcon; getEnvironment(remoteAuthority: string | undefined): Promise; createProfileFromShellAndShellArgs(shell?: unknown, shellArgs?: unknown): Promise; } diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index acdd4ce698d..5c982b8dc56 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -10,6 +10,7 @@ import { TerminalLocationString, TerminalSettingId } from 'vs/platform/terminal/ import { isMacintosh, isWindows } from 'vs/base/common/platform'; import { Registry } from 'vs/platform/registry/common/platform'; import { Codicon } from 'vs/base/common/codicons'; +import { terminalColorSchema, terminalIconSchema } from 'vs/platform/terminal/common/terminalPlatformConfiguration'; const terminalDescriptors = '\n- ' + [ '`\${cwd}`: ' + localize("cwd", "the terminal's current working directory"), @@ -40,26 +41,13 @@ const terminalConfiguration: IConfigurationNode = { default: false }, [TerminalSettingId.TabsDefaultColor]: { - description: localize('terminal.integrated.tabs.defaultColor', "Controls the terminal tab icon's default color."), - type: 'string', - enum: [ - 'terminal.ansiBlack', - 'terminal.ansiRed', - 'terminal.ansiGreen', - 'terminal.ansiYellow', - 'terminal.ansiBlue', - 'terminal.ansiMagenta', - 'terminal.ansiCyan', - 'terminal.ansiWhite' - ], - default: undefined, + description: localize('terminal.integrated.tabs.defaultColor', "A theme color ID to associate with terminals by default."), + ...terminalColorSchema }, [TerminalSettingId.TabsDefaultIcon]: { - description: localize('terminal.integrated.tabs.defaultIcon', "Controls the terminal tab's default icon."), - type: 'string', - enum: Codicon.getAll().map(icon => icon.id), - markdownEnumDescriptions: Array.from(Codicon.getAll(), icon => `$(${icon.id})`), - default: undefined, + description: localize('terminal.integrated.tabs.defaultIcon', "A codicon ID to associate with terminals by default."), + ...terminalIconSchema, + default: Codicon.terminal.id, }, [TerminalSettingId.TabsEnabled]: { description: localize('terminal.integrated.tabs.enabled', 'Controls whether terminal tabs display as a list to the side of the terminal. When this is disabled a dropdown will display instead.'), diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index caa62c81497..f7e9543fb3f 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -35,7 +35,7 @@ import { TestConfigurationService } from 'vs/platform/configuration/test/common/ import { MenuBarVisibility, IWindowOpenable, IOpenWindowOptions, IOpenEmptyWindowOptions } from 'vs/platform/window/common/window'; import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IThemeService, ThemeIcon } from 'vs/platform/theme/common/themeService'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { ITextResourceConfigurationService, ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfiguration'; import { IPosition, Position as EditorPosition } from 'vs/editor/common/core/position'; @@ -122,7 +122,7 @@ import { SideBySideEditor } from 'vs/workbench/browser/parts/editor/sideBySideEd import { IEnterWorkspaceResult, IRecent, IRecentlyOpened, IWorkspaceFolderCreationData, IWorkspacesService } from 'vs/platform/workspaces/common/workspaces'; import { IWorkspaceTrustManagementService, IWorkspaceTrustRequestService } from 'vs/platform/workspace/common/workspaceTrust'; import { TestWorkspaceTrustManagementService, TestWorkspaceTrustRequestService } from 'vs/workbench/services/workspaces/test/common/testWorkspaceTrustService'; -import { IExtensionTerminalProfile, IShellLaunchConfig, ITerminalProfile, TerminalLocation, TerminalShellType } from 'vs/platform/terminal/common/terminal'; +import { IExtensionTerminalProfile, IShellLaunchConfig, ITerminalProfile, TerminalIcon, TerminalLocation, TerminalShellType } from 'vs/platform/terminal/common/terminal'; import { ICreateTerminalOptions, IDeserializedTerminalEditorInput, ITerminalEditorService, ITerminalGroup, ITerminalGroupService, ITerminalInstance, ITerminalInstanceService, TerminalEditorLocation } from 'vs/workbench/contrib/terminal/browser/terminal'; import { assertIsDefined, isArray } from 'vs/base/common/types'; import { IRegisterContributedProfileArgs, IShellLaunchConfigResolveOptions, ITerminalBackend, ITerminalProfileProvider, ITerminalProfileResolverService, ITerminalProfileService } from 'vs/workbench/contrib/terminal/common/terminal'; @@ -165,6 +165,7 @@ import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/co import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; import { EnablementState, IExtensionManagementServer, IScannedExtension, IWebExtensionsScannerService, IWorkbenchExtensionEnablementService, IWorkbenchExtensionManagementService, ScanOptions } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { InstallVSIXOptions, ILocalExtension, IGalleryExtension, InstallOptions, IExtensionIdentifier, UninstallOptions, IExtensionsControlManifest, IGalleryMetadata, IExtensionManagementParticipant } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { Codicon } from 'vs/base/common/codicons'; export function createFileEditorInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined, undefined, undefined, undefined, undefined); @@ -1863,6 +1864,7 @@ export class TestTerminalProfileResolverService implements ITerminalProfileResol async getDefaultProfile(options: IShellLaunchConfigResolveOptions): Promise { return { path: '/default', profileName: 'Default', isDefault: true }; } async getDefaultShell(options: IShellLaunchConfigResolveOptions): Promise { return '/default'; } async getDefaultShellArgs(options: IShellLaunchConfigResolveOptions): Promise { return []; } + getDefaultIcon(): TerminalIcon & ThemeIcon { return Codicon.terminal; } async getEnvironment(): Promise { return env; } getSafeConfigValue(key: string, os: OperatingSystem): unknown | undefined { return undefined; } getSafeConfigValueFullKey(key: string): unknown | undefined { return undefined; } -- cgit v1.2.3 From 22f3f6064e9fc2cf8247932436e7f910641370af Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:29:08 -0700 Subject: Move some text out of localization string for integrated terminal settings (#154318) Fixes #154317 --- .../terminal/common/terminalConfiguration.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index 83a67239048..95fb4b4e3e6 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -34,7 +34,7 @@ const terminalConfiguration: IConfigurationNode = { type: 'object', properties: { [TerminalSettingId.SendKeybindingsToShell]: { - markdownDescription: localize('terminal.integrated.sendKeybindingsToShell', "Dispatches most keybindings to the terminal instead of the workbench, overriding `#terminal.integrated.commandsToSkipShell#`, which can be used alternatively for fine tuning."), + markdownDescription: localize('terminal.integrated.sendKeybindingsToShell', "Dispatches most keybindings to the terminal instead of the workbench, overriding {0}, which can be used alternatively for fine tuning.", '`#terminal.integrated.commandsToSkipShell#`'), type: 'boolean', default: false }, @@ -106,17 +106,17 @@ const terminalConfiguration: IConfigurationNode = { [TerminalSettingId.ShellIntegrationDecorationIconSuccess]: { type: 'string', default: 'primitive-dot', - markdownDescription: localize('terminal.integrated.shellIntegration.decorationIconSuccess', "Controls the icon that will be used for each command in terminals with shell integration enabled that do not have an associated exit code. Set to `''` to hide the icon or disable decorations with `#terminal.integrated.shellIntegration.decorationsEnabled#`") + markdownDescription: localize('terminal.integrated.shellIntegration.decorationIconSuccess', "Controls the icon that will be used for each command in terminals with shell integration enabled that do not have an associated exit code. Set to {0} to hide the icon or disable decorations with {1}.", '`\'\'`', '`#terminal.integrated.shellIntegration.decorationsEnabled#`') }, [TerminalSettingId.ShellIntegrationDecorationIconError]: { type: 'string', default: 'error-small', - markdownDescription: localize('terminal.integrated.shellIntegration.decorationIconError', "Controls the icon that will be used for each command in terminals with shell integration enabled that do have an associated exit code. Set to `''` to hide the icon or disable decorations with `#terminal.integrated.shellIntegration.decorationsEnabled#`.") + markdownDescription: localize('terminal.integrated.shellIntegration.decorationIconError', "Controls the icon that will be used for each command in terminals with shell integration enabled that do have an associated exit code. Set to {0} to hide the icon or disable decorations with {1}.", '`\'\'`', '`#terminal.integrated.shellIntegration.decorationsEnabled#`') }, [TerminalSettingId.ShellIntegrationDecorationIcon]: { type: 'string', default: 'circle-outline', - markdownDescription: localize('terminal.integrated.shellIntegration.decorationIcon', "Controls the icon that will be used for skipped/empty commands. Set to `''` to hide the icon or disable decorations with `#terminal.integrated.shellIntegration.decorationsEnabled#`") + markdownDescription: localize('terminal.integrated.shellIntegration.decorationIcon', "Controls the icon that will be used for skipped/empty commands. Set to {0} to hide the icon or disable decorations with {1}.", '`\'\'`', '`#terminal.integrated.shellIntegration.decorationsEnabled#`') }, [TerminalSettingId.TabsFocusMode]: { type: 'string', @@ -139,7 +139,7 @@ const terminalConfiguration: IConfigurationNode = { default: false }, [TerminalSettingId.AltClickMovesCursor]: { - markdownDescription: localize('terminal.integrated.altClickMovesCursor', "If enabled, alt/option + click will reposition the prompt cursor to underneath the mouse when `#editor.multiCursorModifier#` is set to `'alt'` (the default value). This may not work reliably depending on your shell."), + markdownDescription: localize('terminal.integrated.altClickMovesCursor', "If enabled, alt/option + click will reposition the prompt cursor to underneath the mouse when {0} is set to {1} (the default value). This may not work reliably depending on your shell.", '`#editor.multiCursorModifier#`', '`\'alt\'`'), type: 'boolean', default: true }, @@ -159,7 +159,7 @@ const terminalConfiguration: IConfigurationNode = { default: true }, [TerminalSettingId.FontFamily]: { - markdownDescription: localize('terminal.integrated.fontFamily', "Controls the font family of the terminal, this defaults to `#editor.fontFamily#`'s value."), + markdownDescription: localize('terminal.integrated.fontFamily', "Controls the font family of the terminal, this defaults to {0}'s value.", '`#editor.fontFamily#`'), type: 'string' }, // TODO: Support font ligatures @@ -254,7 +254,7 @@ const terminalConfiguration: IConfigurationNode = { default: TerminalCursorStyle.BLOCK }, [TerminalSettingId.CursorWidth]: { - markdownDescription: localize('terminal.integrated.cursorWidth', "Controls the width of the cursor when `#terminal.integrated.cursorStyle#` is set to `line`."), + markdownDescription: localize('terminal.integrated.cursorWidth', "Controls the width of the cursor when {0} is set to {1}.", '`#terminal.integrated.cursorStyle#`', '`line`'), type: 'number', default: 1 }, @@ -354,7 +354,8 @@ const terminalConfiguration: IConfigurationNode = { 'terminal.integrated.commandsToSkipShell', "A set of command IDs whose keybindings will not be sent to the shell but instead always be handled by VS Code. This allows keybindings that would normally be consumed by the shell to act instead the same as when the terminal is not focused, for example `Ctrl+P` to launch Quick Open.\n\n \n\nMany commands are skipped by default. To override a default and pass that command's keybinding to the shell instead, add the command prefixed with the `-` character. For example add `-workbench.action.quickOpen` to allow `Ctrl+P` to reach the shell.\n\n \n\nThe following list of default skipped commands is truncated when viewed in Settings Editor. To see the full list, {1} and search for the first command from the list below.\n\n \n\nDefault Skipped Commands:\n\n{0}", DEFAULT_COMMANDS_TO_SKIP_SHELL.sort().map(command => `- ${command}`).join('\n'), - `[${localize('openDefaultSettingsJson', "open the default settings JSON")}](command:workbench.action.openRawDefaultSettings '${localize('openDefaultSettingsJson.capitalized', "Open Default Settings (JSON)")}')` + `[${localize('openDefaultSettingsJson', "open the default settings JSON")}](command:workbench.action.openRawDefaultSettings '${localize('openDefaultSettingsJson.capitalized', "Open Default Settings (JSON)")}')`, + ), type: 'array', items: { @@ -363,7 +364,7 @@ const terminalConfiguration: IConfigurationNode = { default: [] }, [TerminalSettingId.AllowChords]: { - markdownDescription: localize('terminal.integrated.allowChords', "Whether or not to allow chord keybindings in the terminal. Note that when this is true and the keystroke results in a chord it will bypass `#terminal.integrated.commandsToSkipShell#`, setting this to false is particularly useful when you want ctrl+k to go to your shell (not VS Code)."), + markdownDescription: localize('terminal.integrated.allowChords', "Whether or not to allow chord keybindings in the terminal. Note that when this is true and the keystroke results in a chord it will bypass {0}, setting this to false is particularly useful when you want ctrl+k to go to your shell (not VS Code).", '`#terminal.integrated.commandsToSkipShell#`'), type: 'boolean', default: true }, @@ -464,7 +465,7 @@ const terminalConfiguration: IConfigurationNode = { default: 30, }, [TerminalSettingId.LocalEchoEnabled]: { - markdownDescription: localize('terminal.integrated.localEchoEnabled', "When local echo should be enabled. This will override `#terminal.integrated.localEchoLatencyThreshold#`"), + markdownDescription: localize('terminal.integrated.localEchoEnabled', "When local echo should be enabled. This will override {0}", '`#terminal.integrated.localEchoLatencyThreshold#`'), type: 'string', enum: ['on', 'off', 'auto'], enumDescriptions: [ -- cgit v1.2.3 From c4b08408c8e9ed572e29e1d106c8d9d105716e41 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:30:46 -0700 Subject: Fix compile --- src/vs/workbench/contrib/terminal/browser/terminalView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalView.ts b/src/vs/workbench/contrib/terminal/browser/terminalView.ts index ed41d6eac2a..f3f77734984 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalView.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalView.ts @@ -375,7 +375,7 @@ class SingleTerminalTabActionViewItem extends MenuEntryActionViewItem { @ITerminalGroupService private readonly _terminalGroupService: ITerminalGroupService, @IContextMenuService private readonly _contextMenuService: IContextMenuService, @ICommandService private readonly _commandService: ICommandService, - @IConfigurationService configurationService: IConfigurationService + @IConfigurationService configurationService: IConfigurationService, @IInstantiationService private readonly _instantiationService: IInstantiationService, ) { super(new MenuItemAction( -- cgit v1.2.3 From 2a5d381d162212f47c495eacf2e84a372a74f5ef Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 6 Jul 2022 20:15:58 -0400 Subject: only show output button when a command's markers haven't been disposed of (#154220) * fix #154215 * make hasOutput a function * fix test * Update src/vs/workbench/contrib/terminal/browser/terminalProfileService.ts * actually fix tests --- src/vs/platform/terminal/common/capabilities/capabilities.ts | 2 +- .../terminal/common/capabilities/commandDetectionCapability.ts | 4 ++-- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 2 +- .../workbench/contrib/terminal/browser/xterm/decorationAddon.ts | 2 +- src/vs/workbench/contrib/terminal/common/terminal.ts | 2 +- .../terminal/test/browser/links/terminalLinkOpeners.test.ts | 6 +++--- .../contrib/terminal/test/browser/xterm/decorationAddon.test.ts | 8 ++++---- 7 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/capabilities/capabilities.ts b/src/vs/platform/terminal/common/capabilities/capabilities.ts index d398dccd0ac..1cfbab58a30 100644 --- a/src/vs/platform/terminal/common/capabilities/capabilities.ts +++ b/src/vs/platform/terminal/common/capabilities/capabilities.ts @@ -198,7 +198,7 @@ export interface ITerminalCommand { executedMarker?: IXtermMarker; commandStartLineContent?: string; getOutput(): string | undefined; - hasOutput: boolean; + hasOutput(): boolean; genericMarkProperties?: IGenericMarkProperties; } diff --git a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts index 95aa53d305c..7194815abb1 100644 --- a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts +++ b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts @@ -457,7 +457,7 @@ export class CommandDetectionCapability implements ICommandDetectionCapability { cwd: this._cwd, exitCode: this._exitCode, commandStartLineContent: this._currentCommand.commandStartLineContent, - hasOutput: !!(executedMarker && endMarker && executedMarker?.line < endMarker!.line), + hasOutput: () => !executedMarker?.isDisposed && !endMarker?.isDisposed && !!(executedMarker && endMarker && executedMarker?.line < endMarker!.line), getOutput: () => getOutputForCommand(executedMarker, endMarker, buffer), genericMarkProperties: options?.genericMarkProperties }; @@ -579,7 +579,7 @@ export class CommandDetectionCapability implements ICommandDetectionCapability { cwd: e.cwd, commandStartLineContent: e.commandStartLineContent, exitCode: e.exitCode, - hasOutput: !!(executedMarker && endMarker && executedMarker.line < endMarker.line), + hasOutput: () => !executedMarker?.isDisposed && !endMarker?.isDisposed && !!(executedMarker && endMarker && executedMarker.line < endMarker.line), getOutput: () => getOutputForCommand(executedMarker, endMarker, buffer), genericMarkProperties: e.genericMarkProperties }; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index edf4d2b4198..6c3e3c9f25c 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -877,7 +877,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { description, id: entry.timestamp.toString(), command: entry, - buttons: entry.hasOutput ? buttons : undefined + buttons: entry.hasOutput() ? buttons : undefined }); commandMap.add(label); } diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts b/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts index e7e3137ae30..45b820a935c 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts @@ -365,7 +365,7 @@ export class DecorationAddon extends Disposable implements ITerminalAddon { run: () => this._clipboardService.writeText(command.command) }); } - if (command.hasOutput) { + if (command.hasOutput()) { if (actions.length > 0) { actions.push(new Separator()); } diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 8346edc1b8e..109988ca671 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -341,7 +341,7 @@ export interface ITerminalCommand { cwd?: string; exitCode?: number; marker?: IXtermMarker; - hasOutput: boolean; + hasOutput(): boolean; getOutput(): string | undefined; genericMarkProperties?: IGenericMarkProperties; } diff --git a/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkOpeners.test.ts b/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkOpeners.test.ts index e7eea1e62fc..225dd72bbdc 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkOpeners.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkOpeners.test.ts @@ -110,7 +110,7 @@ suite('Workbench - TerminalLinkOpeners', () => { marker: { line: 0 } as Partial as any, - hasOutput: true + hasOutput() { return true; } }]); fileService.setFiles([ URI.from({ scheme: Schemas.file, path: '/initial/cwd/foo/bar.txt' }), @@ -188,7 +188,7 @@ suite('Workbench - TerminalLinkOpeners', () => { marker: { line: 0 } as Partial as any, - hasOutput: true + hasOutput() { return true; } }]); await opener.open({ text: 'file.txt', @@ -237,7 +237,7 @@ suite('Workbench - TerminalLinkOpeners', () => { marker: { line: 0 } as Partial as any, - hasOutput: true + hasOutput() { return true; } }]); await opener.open({ text: 'file.txt', diff --git a/src/vs/workbench/contrib/terminal/test/browser/xterm/decorationAddon.test.ts b/src/vs/workbench/contrib/terminal/test/browser/xterm/decorationAddon.test.ts index 80802218586..3ea312e1e1e 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/xterm/decorationAddon.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/xterm/decorationAddon.test.ts @@ -56,21 +56,21 @@ suite('DecorationAddon', () => { suite('registerDecoration', async () => { test('should throw when command has no marker', async () => { - throws(() => decorationAddon.registerCommandDecoration({ command: 'cd src', timestamp: Date.now(), hasOutput: false } as ITerminalCommand)); + throws(() => decorationAddon.registerCommandDecoration({ command: 'cd src', timestamp: Date.now(), hasOutput: () => false } as ITerminalCommand)); }); test('should return undefined when marker has been disposed of', async () => { const marker = xterm.registerMarker(1); marker?.dispose(); - strictEqual(decorationAddon.registerCommandDecoration({ command: 'cd src', marker, timestamp: Date.now(), hasOutput: false } as ITerminalCommand), undefined); + strictEqual(decorationAddon.registerCommandDecoration({ command: 'cd src', marker, timestamp: Date.now(), hasOutput: () => false } as ITerminalCommand), undefined); }); test('should return undefined when command is just empty chars', async () => { const marker = xterm.registerMarker(1); marker?.dispose(); - strictEqual(decorationAddon.registerCommandDecoration({ command: ' ', marker, timestamp: Date.now(), hasOutput: false } as ITerminalCommand), undefined); + strictEqual(decorationAddon.registerCommandDecoration({ command: ' ', marker, timestamp: Date.now(), hasOutput: () => false } as ITerminalCommand), undefined); }); test('should return decoration when marker has not been disposed of', async () => { const marker = xterm.registerMarker(2); - notEqual(decorationAddon.registerCommandDecoration({ command: 'cd src', marker, timestamp: Date.now(), hasOutput: false } as ITerminalCommand), undefined); + notEqual(decorationAddon.registerCommandDecoration({ command: 'cd src', marker, timestamp: Date.now(), hasOutput: () => false } as ITerminalCommand), undefined); }); }); }); -- cgit v1.2.3 From d5d6e089978695d51760b35a64510d8d0e999534 Mon Sep 17 00:00:00 2001 From: MonadChains Date: Thu, 7 Jul 2022 02:16:10 +0200 Subject: Add command to copy output of the last command (#152097) (#153235) * Add command to copy output of the last command (#152097) * Polish changes, casing, wording, etc. Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com> --- src/vs/workbench/contrib/terminal/browser/terminal.ts | 6 ++++++ .../workbench/contrib/terminal/browser/terminalActions.ts | 14 ++++++++++++++ .../contrib/terminal/browser/terminalInstance.ts | 15 +++++++++++++++ src/vs/workbench/contrib/terminal/common/terminal.ts | 2 ++ 4 files changed, 37 insertions(+) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 3b0b1e1e250..8f2474b5dcd 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -678,6 +678,12 @@ export interface ITerminalInstance { */ copySelection(asHtml?: boolean, command?: ITerminalCommand): Promise; + + /** + * Copies the ouput of the last command + */ + copyLastCommandOutput(): Promise; + /** * Current selection in the terminal. */ diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 0c70784c0e3..2f7da096e88 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -327,6 +327,20 @@ export function registerTerminalActions() { } } }); + registerAction2(class extends Action2 { + constructor() { + super({ + id: TerminalCommandId.CopyLastCommand, + title: { value: localize('workbench.action.terminal.copyLastCommand', 'Copy Last Command'), original: 'Copy Last Command' }, + f1: true, + category, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) + }); + } + async run(accessor: ServicesAccessor): Promise { + await accessor.get(ITerminalService).activeInstance?.copyLastCommandOutput(); + } + }); registerAction2(class extends Action2 { constructor() { super({ diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 6c3e3c9f25c..995d7d64cd8 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1239,6 +1239,21 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } } + async copyLastCommandOutput(): Promise { + const commands = this.capabilities.get(TerminalCapability.CommandDetection)?.commands; + if (!commands || commands.length === 0) { + return; + } + const command = commands[commands.length - 1]; + if (!command?.hasOutput) { + return; + } + const output = command.getOutput(); + if (output) { + await this._clipboardService.writeText(output); + } + } + get selection(): string | undefined { return this.xterm && this.hasSelection() ? this.xterm.raw.getSelection() : undefined; } diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 109988ca671..52e3969a13a 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -476,6 +476,7 @@ export const enum TerminalCommandId { OpenFileLink = 'workbench.action.terminal.openFileLink', OpenWebLink = 'workbench.action.terminal.openUrlLink', RunRecentCommand = 'workbench.action.terminal.runRecentCommand', + CopyLastCommand = 'workbench.action.terminal.copyLastCommand', GoToRecentDirectory = 'workbench.action.terminal.goToRecentDirectory', CopySelection = 'workbench.action.terminal.copySelection', CopySelectionAsHtml = 'workbench.action.terminal.copySelectionAsHtml', @@ -574,6 +575,7 @@ export const DEFAULT_COMMANDS_TO_SKIP_SHELL: string[] = [ TerminalCommandId.Clear, TerminalCommandId.CopySelection, TerminalCommandId.CopySelectionAsHtml, + TerminalCommandId.CopyLastCommand, TerminalCommandId.DeleteToLineStart, TerminalCommandId.DeleteWordLeft, TerminalCommandId.DeleteWordRight, -- cgit v1.2.3 From a3153bb9dc4816c4f4034686997a6232b923769f Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 6 Jul 2022 20:25:03 -0400 Subject: Update src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts --- .../workbench/contrib/terminal/browser/terminalProfileResolverService.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts index 2abd550fedc..33e242184de 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts @@ -145,7 +145,6 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro // Verify the icon is valid, and fallback correctly to the generic terminal id if there is // an issue - console.log('icon', this._configurationService.getValue(TerminalSettingId.TabsDefaultIcon)); shellLaunchConfig.icon = this._getCustomIcon(shellLaunchConfig.icon) || this._getCustomIcon(resolvedProfile.icon) || this.getDefaultIcon(); -- cgit v1.2.3 From d39ef2fc829dffe33ff7b9c341d787bb1198ef63 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 6 Jul 2022 20:25:24 -0400 Subject: Update src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts --- .../workbench/contrib/terminal/browser/terminalProfileResolverService.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts index 33e242184de..f920f87442f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts @@ -148,7 +148,6 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro shellLaunchConfig.icon = this._getCustomIcon(shellLaunchConfig.icon) || this._getCustomIcon(resolvedProfile.icon) || this.getDefaultIcon(); - console.log('icon2', shellLaunchConfig.icon); // Override the name if specified if (resolvedProfile.overrideName) { -- cgit v1.2.3 From 2d9947ba4e53c0889c07e3a415572ec8bad1529e Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 6 Jul 2022 20:47:00 -0400 Subject: more specific setting names --- src/vs/platform/terminal/common/terminal.ts | 4 ++-- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 2 +- .../contrib/terminal/browser/terminalProfileResolverService.ts | 4 ++-- src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 4ef5e51de3e..0619e9e87fa 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -40,8 +40,8 @@ export const enum TerminalSettingId { DefaultProfileMacOs = 'terminal.integrated.defaultProfile.osx', DefaultProfileWindows = 'terminal.integrated.defaultProfile.windows', UseWslProfiles = 'terminal.integrated.useWslProfiles', - TabsDefaultColor = 'terminal.integrated.tabs.defaultColor', - TabsDefaultIcon = 'terminal.integrated.tabs.defaultIcon', + TabsDefaultIconColor = 'terminal.integrated.tabs.defaultIconColor', + TabsDefaultIconId = 'terminal.integrated.tabs.defaultIconId', TabsEnabled = 'terminal.integrated.tabs.enabled', TabsEnableAnimation = 'terminal.integrated.tabs.enableAnimation', TabsHideCondition = 'terminal.integrated.tabs.hideCondition', diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index a02e18413dc..b392eb5bd70 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -550,7 +550,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { private _getIcon(): TerminalIcon | undefined { if (!this._icon) { this._icon = this._processManager.processState >= ProcessState.Launching - ? getIconRegistry().getIcon(this._configurationService.getValue(TerminalSettingId.TabsDefaultIcon)) + ? getIconRegistry().getIcon(this._configurationService.getValue(TerminalSettingId.TabsDefaultIconId)) : undefined; } return this._icon; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts index f920f87442f..b133c8e5d8d 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts @@ -117,7 +117,7 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro } getDefaultIcon(): TerminalIcon & ThemeIcon { - return this._iconRegistry.getIcon(this._configurationService.getValue(TerminalSettingId.TabsDefaultIcon)) || Codicon.terminal; + return this._iconRegistry.getIcon(this._configurationService.getValue(TerminalSettingId.TabsDefaultIconId)) || Codicon.terminal; } async resolveShellLaunchConfig(shellLaunchConfig: IShellLaunchConfig, options: IShellLaunchConfigResolveOptions): Promise { @@ -157,7 +157,7 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro // Apply the color shellLaunchConfig.color = shellLaunchConfig.color || resolvedProfile.color - || this._configurationService.getValue(TerminalSettingId.TabsDefaultColor); + || this._configurationService.getValue(TerminalSettingId.TabsDefaultIconColor); // Resolve useShellEnvironment based on the setting if it's not set if (shellLaunchConfig.useShellEnvironment === undefined) { diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index 5c982b8dc56..0458ff05172 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -40,12 +40,12 @@ const terminalConfiguration: IConfigurationNode = { type: 'boolean', default: false }, - [TerminalSettingId.TabsDefaultColor]: { - description: localize('terminal.integrated.tabs.defaultColor', "A theme color ID to associate with terminals by default."), + [TerminalSettingId.TabsDefaultIconColor]: { + description: localize('terminal.integrated.tabs.defaultIconColor', "A theme color ID to associate with terminals by default."), ...terminalColorSchema }, - [TerminalSettingId.TabsDefaultIcon]: { - description: localize('terminal.integrated.tabs.defaultIcon', "A codicon ID to associate with terminals by default."), + [TerminalSettingId.TabsDefaultIconId]: { + description: localize('terminal.integrated.tabs.defaultIconId', "A codicon ID to associate with terminals by default."), ...terminalIconSchema, default: Codicon.terminal.id, }, -- cgit v1.2.3 From 91b82c0f0b9d0c9a9135252663522a563be3f6eb Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 6 Jul 2022 21:59:27 -0400 Subject: increase barrier for available profiles to be ready (#154290) * fix #138999 Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com> --- src/vs/workbench/contrib/terminal/browser/terminalProfileService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProfileService.ts b/src/vs/workbench/contrib/terminal/browser/terminalProfileService.ts index 60c49b4b34b..7bdc8975d82 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProfileService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProfileService.ts @@ -67,7 +67,7 @@ export class TerminalProfileService implements ITerminalProfileService { // Wait up to 5 seconds for profiles to be ready so it's assured that we know the actual // default terminal before launching the first terminal. This isn't expected to ever take // this long. - this._profilesReadyBarrier = new AutoOpenBarrier(5000); + this._profilesReadyBarrier = new AutoOpenBarrier(20000); this.refreshAvailableProfiles(); this._setupConfigListener(); } -- cgit v1.2.3 From 374066b82984c3bf8afaa4828147ec29bd883bc8 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 6 Jul 2022 19:06:36 -0700 Subject: re #153743. Move codicon out of translation string (#154323) --- .../notebook/browser/contrib/editorStatusBar/editorStatusBar.ts | 2 +- .../contrib/notebook/browser/controller/insertCellActions.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/editorStatusBar/editorStatusBar.ts b/src/vs/workbench/contrib/notebook/browser/contrib/editorStatusBar/editorStatusBar.ts index 285dae8f94e..53ce0466795 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/editorStatusBar/editorStatusBar.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/editorStatusBar/editorStatusBar.ts @@ -243,7 +243,7 @@ registerAction2(class extends Action2 { quickPickItems.push({ id: 'installSuggested', description: suggestedExtension.displayName ?? suggestedExtension.extensionId, - label: nls.localize('installSuggestedKernel', '$({0}) Install suggested extensions', Codicon.lightbulb.id), + label: `$(${Codicon.lightbulb.id}) ` + nls.localize('installSuggestedKernel', 'Install suggested extensions'), }); } // there is no kernel, show the install from marketplace diff --git a/src/vs/workbench/contrib/notebook/browser/controller/insertCellActions.ts b/src/vs/workbench/contrib/notebook/browser/controller/insertCellActions.ts index 6a85c41a24a..454b565d71e 100644 --- a/src/vs/workbench/contrib/notebook/browser/controller/insertCellActions.ts +++ b/src/vs/workbench/contrib/notebook/browser/controller/insertCellActions.ts @@ -224,7 +224,7 @@ registerAction2(class InsertMarkdownCellAtTopAction extends NotebookAction { MenuRegistry.appendMenuItem(MenuId.NotebookCellBetween, { command: { id: INSERT_CODE_CELL_BELOW_COMMAND_ID, - title: localize('notebookActions.menu.insertCode', "$(add) Code"), + title: '$(add) ' + localize('notebookActions.menu.insertCode', "Code"), tooltip: localize('notebookActions.menu.insertCode.tooltip', "Add Code Cell") }, order: 0, @@ -269,7 +269,7 @@ MenuRegistry.appendMenuItem(MenuId.NotebookToolbar, { MenuRegistry.appendMenuItem(MenuId.NotebookCellListTop, { command: { id: INSERT_CODE_CELL_AT_TOP_COMMAND_ID, - title: localize('notebookActions.menu.insertCode', "$(add) Code"), + title: '$(add) ' + localize('notebookActions.menu.insertCode', "Code"), tooltip: localize('notebookActions.menu.insertCode.tooltip', "Add Code Cell") }, order: 0, @@ -299,7 +299,7 @@ MenuRegistry.appendMenuItem(MenuId.NotebookCellListTop, { MenuRegistry.appendMenuItem(MenuId.NotebookCellBetween, { command: { id: INSERT_MARKDOWN_CELL_BELOW_COMMAND_ID, - title: localize('notebookActions.menu.insertMarkdown', "$(add) Markdown"), + title: '$(add) ' + localize('notebookActions.menu.insertMarkdown', "Markdown"), tooltip: localize('notebookActions.menu.insertMarkdown.tooltip', "Add Markdown Cell") }, order: 1, @@ -331,7 +331,7 @@ MenuRegistry.appendMenuItem(MenuId.NotebookToolbar, { MenuRegistry.appendMenuItem(MenuId.NotebookCellListTop, { command: { id: INSERT_MARKDOWN_CELL_AT_TOP_COMMAND_ID, - title: localize('notebookActions.menu.insertMarkdown', "$(add) Markdown"), + title: '$(add) ' + localize('notebookActions.menu.insertMarkdown', "Markdown"), tooltip: localize('notebookActions.menu.insertMarkdown.tooltip', "Add Markdown Cell") }, order: 1, -- cgit v1.2.3 From ffdb7543feb9abccee23d2b3064bb5bd3d8593a7 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 6 Jul 2022 19:13:51 -0700 Subject: Correct conditional calling func instead of comparing Part of #152097 --- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 995d7d64cd8..370ed54dd2d 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1245,7 +1245,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { return; } const command = commands[commands.length - 1]; - if (!command?.hasOutput) { + if (!command?.hasOutput()) { return; } const output = command.getOutput(); -- cgit v1.2.3 From 93d1f7c88157cc4594ff7154b0f2ad6efc4db08c Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 6 Jul 2022 22:17:44 -0400 Subject: use user's `.zsh_history` (#154300) --- .../workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh index a94e7c11c71..595c1261e18 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh @@ -21,6 +21,10 @@ if [[ "$VSCODE_INJECTION" == "1" ]]; then . $USER_ZDOTDIR/.zshrc ZDOTDIR=$VSCODE_ZDOTDIR fi + + if [[ -f $USER_ZDOTDIR/.zsh_history ]]; then + HISTFILE=$USER_ZDOTDIR/.zsh_history + fi fi # Shell integration was disabled by the shell, exit without warning assuming either the shell has -- cgit v1.2.3 From d6114a70bea1c9163c7c3538e31243affd3b9fd4 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Wed, 6 Jul 2022 22:23:30 -0400 Subject: Remove app insights (#154296) * Remove app insights * Update product service to remove asimovKey --- src/vs/base/common/product.ts | 2 - .../sharedProcess/sharedProcessMain.ts | 9 +- src/vs/code/node/cliProcessMain.ts | 10 +- .../telemetry/browser/appInsightsAppender.ts | 77 ------------ src/vs/platform/telemetry/common/1dsAppender.ts | 4 +- src/vs/platform/telemetry/node/1dsAppender.ts | 2 +- .../platform/telemetry/node/appInsightsAppender.ts | 121 ------------------- .../test/electron-browser/1dsAppender.test.ts | 132 ++++++++++++++++++++ .../electron-browser/appInsightsAppender.test.ts | 133 --------------------- src/vs/server/node/serverServices.ts | 14 +-- .../workbench/contrib/debug/node/telemetryApp.ts | 4 +- .../services/telemetry/browser/telemetryService.ts | 13 +- 12 files changed, 153 insertions(+), 368 deletions(-) delete mode 100644 src/vs/platform/telemetry/browser/appInsightsAppender.ts delete mode 100644 src/vs/platform/telemetry/node/appInsightsAppender.ts create mode 100644 src/vs/platform/telemetry/test/electron-browser/1dsAppender.test.ts delete mode 100644 src/vs/platform/telemetry/test/electron-browser/appInsightsAppender.test.ts (limited to 'src/vs') diff --git a/src/vs/base/common/product.ts b/src/vs/base/common/product.ts index 0e9dcdcba96..1ae8079810e 100644 --- a/src/vs/base/common/product.ts +++ b/src/vs/base/common/product.ts @@ -99,9 +99,7 @@ export interface IProductConfiguration { readonly enableTelemetry?: boolean; readonly openToWelcomeMainPage?: boolean; readonly aiConfig?: { - readonly asimovKey: string; readonly ariaKey: string; - readonly preferAria: boolean; }; readonly sendASmile?: { diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index f166be81aeb..9cf505e2470 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -64,7 +64,6 @@ import { TelemetryAppenderChannel } from 'vs/platform/telemetry/common/telemetry import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogAppender'; import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { supportsTelemetry, ITelemetryAppender, NullAppender, NullTelemetryService, getPiiPathsFromEnvironment } from 'vs/platform/telemetry/common/telemetryUtils'; -import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender'; import { CustomEndpointTelemetryService } from 'vs/platform/telemetry/node/customEndpointTelemetryService'; import { LocalReconnectConstants, TerminalIpcChannels, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; import { ILocalPtyService } from 'vs/platform/terminal/electron-sandbox/terminal'; @@ -282,16 +281,10 @@ class SharedProcessMain extends Disposable { const logAppender = new TelemetryLogAppender(loggerService, environmentService); appenders.push(logAppender); const { installSourcePath } = environmentService; - const internalTesting = configurationService.getValue('telemetry.internalTesting'); - if (internalTesting && productService.aiConfig?.ariaKey) { + if (productService.aiConfig?.ariaKey) { const collectorAppender = new OneDataSystemWebAppender(configurationService, 'monacoworkbench', null, productService.aiConfig.ariaKey); this._register(toDisposable(() => collectorAppender.flush())); // Ensure the 1DS appender is disposed so that it flushes remaining data appenders.push(collectorAppender); - } else if (productService.aiConfig && productService.aiConfig.asimovKey) { - // Application Insights - const appInsightsAppender = new AppInsightsAppender('monacoworkbench', null, productService.aiConfig.asimovKey); - this._register(toDisposable(() => appInsightsAppender.flush())); // Ensure the AI appender is disposed so that it flushes remaining data - appenders.push(appInsightsAppender); } telemetryService = new TelemetryService({ diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index bc4ca25f492..79c5b02e686 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -53,7 +53,7 @@ import { resolveCommonProperties } from 'vs/platform/telemetry/common/commonProp import { ITelemetryService, machineIdKey } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { supportsTelemetry, NullTelemetryService, getPiiPathsFromEnvironment } from 'vs/platform/telemetry/common/telemetryUtils'; -import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender'; +import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender'; import { buildTelemetryMessage } from 'vs/platform/telemetry/node/telemetry'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; @@ -104,7 +104,7 @@ class CliMain extends Disposable { }); } - private async initServices(): Promise<[IInstantiationService, AppInsightsAppender[]]> { + private async initServices(): Promise<[IInstantiationService, OneDataSystemAppender[]]> { const services = new ServiceCollection(); // Product @@ -186,10 +186,10 @@ class CliMain extends Disposable { services.set(ILanguagePackService, new SyncDescriptor(NativeLanguagePackService)); // Telemetry - const appenders: AppInsightsAppender[] = []; + const appenders: OneDataSystemAppender[] = []; if (supportsTelemetry(productService, environmentService)) { - if (productService.aiConfig && productService.aiConfig.asimovKey) { - appenders.push(new AppInsightsAppender('monacoworkbench', null, productService.aiConfig.asimovKey)); + if (productService.aiConfig && productService.aiConfig.ariaKey) { + appenders.push(new OneDataSystemAppender(configurationService, 'monacoworkbench', null, productService.aiConfig.ariaKey)); } const { installSourcePath } = environmentService; diff --git a/src/vs/platform/telemetry/browser/appInsightsAppender.ts b/src/vs/platform/telemetry/browser/appInsightsAppender.ts deleted file mode 100644 index cd4b32c13af..00000000000 --- a/src/vs/platform/telemetry/browser/appInsightsAppender.ts +++ /dev/null @@ -1,77 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import type { ApplicationInsights } from '@microsoft/applicationinsights-web'; -import { ITelemetryAppender, validateTelemetryData } from 'vs/platform/telemetry/common/telemetryUtils'; - -export class WebAppInsightsAppender implements ITelemetryAppender { - private _aiClient: ApplicationInsights | undefined; - private _aiClientLoaded = false; - private _telemetryCache: { eventName: string; data: any }[] = []; - - constructor(private _eventPrefix: string, aiKey: string) { - const endpointUrl = 'https://vscode.vortex.data.microsoft.com/collect/v1'; - import('@microsoft/applicationinsights-web').then(aiLibrary => { - this._aiClient = new aiLibrary.ApplicationInsights({ - config: { - instrumentationKey: aiKey, - endpointUrl, - disableAjaxTracking: true, - disableExceptionTracking: true, - disableFetchTracking: true, - disableCorrelationHeaders: true, - disableCookiesUsage: true, - autoTrackPageVisitTime: false, - emitLineDelimitedJson: true, - }, - }); - this._aiClient.loadAppInsights(); - // Client is loaded we can now flush the cached events - this._aiClientLoaded = true; - this._telemetryCache.forEach(cacheEntry => this.log(cacheEntry.eventName, cacheEntry.data)); - this._telemetryCache = []; - - // If we cannot access the endpoint this most likely means it's being blocked - // and we should not attempt to send any telemetry. - fetch(endpointUrl, { method: 'POST' }).catch(() => (this._aiClient = undefined)); - }).catch(err => { - console.error(err); - }); - } - - /** - * Logs a telemetry event with eventName and data - * @param eventName The event name - * @param data The data associated with the events - */ - public log(eventName: string, data: any): void { - if (!this._aiClient && this._aiClientLoaded) { - return; - } else if (!this._aiClient && !this._aiClientLoaded) { - this._telemetryCache.push({ eventName, data }); - return; - } - - data = validateTelemetryData(data); - - // Web does not expect properties and measurements so we must - // spread them out. This is different from desktop which expects them - data = { ...data.properties, ...data.measurements }; - - // undefined assertion is ok since above two if statements cover both cases - this._aiClient!.trackEvent({ name: this._eventPrefix + '/' + eventName }, data); - } - - /** - * Flushes all the telemetry data still in the buffer - */ - public flush(): Promise { - if (this._aiClient) { - this._aiClient.flush(); - this._aiClient = undefined; - } - return Promise.resolve(undefined); - } -} diff --git a/src/vs/platform/telemetry/common/1dsAppender.ts b/src/vs/platform/telemetry/common/1dsAppender.ts index 8023931f50f..ba7cac9d693 100644 --- a/src/vs/platform/telemetry/common/1dsAppender.ts +++ b/src/vs/platform/telemetry/common/1dsAppender.ts @@ -63,7 +63,7 @@ export abstract class AbstractOneDataSystemAppender implements ITelemetryAppende protected readonly endPointUrl = endpointUrl; constructor( - private readonly _configurationService: IConfigurationService, + private readonly _configurationService: IConfigurationService | undefined, private _eventPrefix: string, private _defaultData: { [key: string]: any } | null, iKeyOrClientFactory: string | (() => AppInsightsCore), // allow factory function for testing @@ -92,7 +92,7 @@ export abstract class AbstractOneDataSystemAppender implements ITelemetryAppende } if (!this._asyncAiCore) { - const isInternal = this._configurationService.getValue('telemetry.internalTesting'); + const isInternal = this._configurationService?.getValue('telemetry.internalTesting'); this._asyncAiCore = getClient(this._aiCoreOrKey, isInternal, this._xhrOverride); } diff --git a/src/vs/platform/telemetry/node/1dsAppender.ts b/src/vs/platform/telemetry/node/1dsAppender.ts index 2e7b1b6f491..c7b6442cf7a 100644 --- a/src/vs/platform/telemetry/node/1dsAppender.ts +++ b/src/vs/platform/telemetry/node/1dsAppender.ts @@ -13,7 +13,7 @@ import { AbstractOneDataSystemAppender } from 'vs/platform/telemetry/common/1dsA export class OneDataSystemAppender extends AbstractOneDataSystemAppender { constructor( - configurationService: IConfigurationService, + configurationService: IConfigurationService | undefined, eventPrefix: string, defaultData: { [key: string]: any } | null, iKeyOrClientFactory: string | (() => AppInsightsCore), // allow factory function for testing diff --git a/src/vs/platform/telemetry/node/appInsightsAppender.ts b/src/vs/platform/telemetry/node/appInsightsAppender.ts deleted file mode 100644 index d5fc5987438..00000000000 --- a/src/vs/platform/telemetry/node/appInsightsAppender.ts +++ /dev/null @@ -1,121 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import type { TelemetryClient } from 'applicationinsights'; -import { onUnexpectedError } from 'vs/base/common/errors'; -import { mixin } from 'vs/base/common/objects'; -import { ITelemetryAppender, validateTelemetryData } from 'vs/platform/telemetry/common/telemetryUtils'; - -async function getClient(aiKey: string): Promise { - const appInsights = await import('applicationinsights'); - let client: TelemetryClient; - if (appInsights.defaultClient) { - client = new appInsights.TelemetryClient(aiKey); - client.channel.setUseDiskRetryCaching(true); - } else { - appInsights.setup(aiKey) - .setAutoCollectRequests(false) - .setAutoCollectPerformance(false) - .setAutoCollectExceptions(false) - .setAutoCollectDependencies(false) - .setAutoDependencyCorrelation(false) - .setAutoCollectConsole(false) - .setInternalLogging(false, false) - .setUseDiskRetryCaching(true) - .start(); - client = appInsights.defaultClient; - } - - if (aiKey.indexOf('AIF-') === 0) { - client.config.endpointUrl = 'https://mobile.events.data.microsoft.com/collect/v1'; - } - return client; -} - - -export class AppInsightsAppender implements ITelemetryAppender { - - private _aiClient: string | TelemetryClient | undefined; - private _asyncAIClient: Promise | null; - - constructor( - private _eventPrefix: string, - private _defaultData: { [key: string]: any } | null, - aiKeyOrClientFactory: string | (() => TelemetryClient), // allow factory function for testing - ) { - if (!this._defaultData) { - this._defaultData = Object.create(null); - } - - if (typeof aiKeyOrClientFactory === 'function') { - this._aiClient = aiKeyOrClientFactory(); - } else { - this._aiClient = aiKeyOrClientFactory; - } - this._asyncAIClient = null; - } - - private _withAIClient(callback: (aiClient: TelemetryClient) => void): void { - if (!this._aiClient) { - return; - } - - if (typeof this._aiClient !== 'string') { - callback(this._aiClient); - return; - } - - if (!this._asyncAIClient) { - this._asyncAIClient = getClient(this._aiClient); - } - - this._asyncAIClient.then( - (aiClient) => { - callback(aiClient); - }, - (err) => { - onUnexpectedError(err); - console.error(err); - } - ); - } - - log(eventName: string, data?: any): void { - if (!this._aiClient) { - return; - } - data = mixin(data, this._defaultData); - data = validateTelemetryData(data); - - // Attemps to suppress https://github.com/microsoft/vscode/issues/140624 - try { - this._withAIClient((aiClient) => aiClient.trackEvent({ - name: this._eventPrefix + '/' + eventName, - properties: data.properties, - measurements: data.measurements - })); - } catch { } - } - - flush(): Promise { - if (this._aiClient) { - return new Promise(resolve => { - this._withAIClient((aiClient) => { - // Attempts to suppress https://github.com/microsoft/vscode/issues/140624 - try { - aiClient.flush({ - callback: () => { - // all data flushed - this._aiClient = undefined; - resolve(undefined); - } - }); - } catch { } - }); - }); - } - return Promise.resolve(undefined); - } -} diff --git a/src/vs/platform/telemetry/test/electron-browser/1dsAppender.test.ts b/src/vs/platform/telemetry/test/electron-browser/1dsAppender.test.ts new file mode 100644 index 00000000000..3b734414796 --- /dev/null +++ b/src/vs/platform/telemetry/test/electron-browser/1dsAppender.test.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { AppInsightsCore } from '@microsoft/1ds-core-js'; +import * as assert from 'assert'; +import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender'; + +class AppInsightsCoreMock extends AppInsightsCore { + public override config: any; + public events: any[] = []; + public IsTrackingPageView: boolean = false; + public exceptions: any[] = []; + + constructor() { + super(); + } + + public override track(event: any) { + this.events.push(event.baseData); + } + + public override flush(options: any): void { + // called on dispose + } +} + +suite('AIAdapter', () => { + let appInsightsMock: AppInsightsCoreMock; + let adapter: OneDataSystemAppender; + const prefix = 'prefix'; + + + setup(() => { + appInsightsMock = new AppInsightsCoreMock(); + adapter = new OneDataSystemAppender(undefined, prefix, undefined!, () => appInsightsMock); + }); + + teardown(() => { + adapter.flush(); + }); + + test('Simple event', () => { + adapter.log('testEvent'); + + assert.strictEqual(appInsightsMock.events.length, 1); + assert.strictEqual(appInsightsMock.events[0].name, `${prefix}/testEvent`); + }); + + test('addional data', () => { + adapter = new OneDataSystemAppender(undefined, prefix, { first: '1st', second: 2, third: true }, () => appInsightsMock); + adapter.log('testEvent'); + + assert.strictEqual(appInsightsMock.events.length, 1); + const [first] = appInsightsMock.events; + assert.strictEqual(first.name, `${prefix}/testEvent`); + assert.strictEqual(first.properties!['first'], '1st'); + assert.strictEqual(first.measurements!['second'], 2); + assert.strictEqual(first.measurements!['third'], 1); + }); + + test('property limits', () => { + let reallyLongPropertyName = 'abcdefghijklmnopqrstuvwxyz'; + for (let i = 0; i < 6; i++) { + reallyLongPropertyName += 'abcdefghijklmnopqrstuvwxyz'; + } + assert(reallyLongPropertyName.length > 150); + + let reallyLongPropertyValue = 'abcdefghijklmnopqrstuvwxyz012345678901234567890123'; + for (let i = 0; i < 400; i++) { + reallyLongPropertyValue += 'abcdefghijklmnopqrstuvwxyz012345678901234567890123'; + } + assert(reallyLongPropertyValue.length > 8192); + + const data = Object.create(null); + data[reallyLongPropertyName] = '1234'; + data['reallyLongPropertyValue'] = reallyLongPropertyValue; + adapter.log('testEvent', data); + + assert.strictEqual(appInsightsMock.events.length, 1); + + for (const prop in appInsightsMock.events[0].properties!) { + assert(prop.length < 150); + assert(appInsightsMock.events[0].properties![prop].length < 8192); + } + }); + + test('Different data types', () => { + const date = new Date(); + adapter.log('testEvent', { favoriteDate: date, likeRed: false, likeBlue: true, favoriteNumber: 1, favoriteColor: 'blue', favoriteCars: ['bmw', 'audi', 'ford'] }); + + assert.strictEqual(appInsightsMock.events.length, 1); + assert.strictEqual(appInsightsMock.events[0].name, `${prefix}/testEvent`); + assert.strictEqual(appInsightsMock.events[0].properties!['favoriteColor'], 'blue'); + assert.strictEqual(appInsightsMock.events[0].measurements!['likeRed'], 0); + assert.strictEqual(appInsightsMock.events[0].measurements!['likeBlue'], 1); + assert.strictEqual(appInsightsMock.events[0].properties!['favoriteDate'], date.toISOString()); + assert.strictEqual(appInsightsMock.events[0].properties!['favoriteCars'], JSON.stringify(['bmw', 'audi', 'ford'])); + assert.strictEqual(appInsightsMock.events[0].measurements!['favoriteNumber'], 1); + }); + + test('Nested data', () => { + adapter.log('testEvent', { + window: { + title: 'some title', + measurements: { + width: 100, + height: 200 + } + }, + nestedObj: { + nestedObj2: { + nestedObj3: { + testProperty: 'test', + } + }, + testMeasurement: 1 + } + }); + + assert.strictEqual(appInsightsMock.events.length, 1); + assert.strictEqual(appInsightsMock.events[0].name, `${prefix}/testEvent`); + + assert.strictEqual(appInsightsMock.events[0].properties!['window.title'], 'some title'); + assert.strictEqual(appInsightsMock.events[0].measurements!['window.measurements.width'], 100); + assert.strictEqual(appInsightsMock.events[0].measurements!['window.measurements.height'], 200); + + assert.strictEqual(appInsightsMock.events[0].properties!['nestedObj.nestedObj2.nestedObj3'], JSON.stringify({ 'testProperty': 'test' })); + assert.strictEqual(appInsightsMock.events[0].measurements!['nestedObj.testMeasurement'], 1); + }); + +}); diff --git a/src/vs/platform/telemetry/test/electron-browser/appInsightsAppender.test.ts b/src/vs/platform/telemetry/test/electron-browser/appInsightsAppender.test.ts deleted file mode 100644 index 09f1f611da9..00000000000 --- a/src/vs/platform/telemetry/test/electron-browser/appInsightsAppender.test.ts +++ /dev/null @@ -1,133 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -import { Contracts, TelemetryClient } from 'applicationinsights'; -import * as assert from 'assert'; -import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender'; - -class AppInsightsMock extends TelemetryClient { - public override config: any; - public override channel: any; - public events: Contracts.EventTelemetry[] = []; - public IsTrackingPageView: boolean = false; - public exceptions: any[] = []; - - constructor() { - super('testKey'); - } - - public override trackEvent(event: any) { - this.events.push(event); - } - - public override flush(options: any): void { - // called on dispose - } -} - -suite('AIAdapter', () => { - let appInsightsMock: AppInsightsMock; - let adapter: AppInsightsAppender; - const prefix = 'prefix'; - - - setup(() => { - appInsightsMock = new AppInsightsMock(); - adapter = new AppInsightsAppender(prefix, undefined!, () => appInsightsMock); - }); - - teardown(() => { - adapter.flush(); - }); - - test('Simple event', () => { - adapter.log('testEvent'); - - assert.strictEqual(appInsightsMock.events.length, 1); - assert.strictEqual(appInsightsMock.events[0].name, `${prefix}/testEvent`); - }); - - test('addional data', () => { - adapter = new AppInsightsAppender(prefix, { first: '1st', second: 2, third: true }, () => appInsightsMock); - adapter.log('testEvent'); - - assert.strictEqual(appInsightsMock.events.length, 1); - const [first] = appInsightsMock.events; - assert.strictEqual(first.name, `${prefix}/testEvent`); - assert.strictEqual(first.properties!['first'], '1st'); - assert.strictEqual(first.measurements!['second'], 2); - assert.strictEqual(first.measurements!['third'], 1); - }); - - test('property limits', () => { - let reallyLongPropertyName = 'abcdefghijklmnopqrstuvwxyz'; - for (let i = 0; i < 6; i++) { - reallyLongPropertyName += 'abcdefghijklmnopqrstuvwxyz'; - } - assert(reallyLongPropertyName.length > 150); - - let reallyLongPropertyValue = 'abcdefghijklmnopqrstuvwxyz012345678901234567890123'; - for (let i = 0; i < 400; i++) { - reallyLongPropertyValue += 'abcdefghijklmnopqrstuvwxyz012345678901234567890123'; - } - assert(reallyLongPropertyValue.length > 8192); - - const data = Object.create(null); - data[reallyLongPropertyName] = '1234'; - data['reallyLongPropertyValue'] = reallyLongPropertyValue; - adapter.log('testEvent', data); - - assert.strictEqual(appInsightsMock.events.length, 1); - - for (const prop in appInsightsMock.events[0].properties!) { - assert(prop.length < 150); - assert(appInsightsMock.events[0].properties![prop].length < 8192); - } - }); - - test('Different data types', () => { - const date = new Date(); - adapter.log('testEvent', { favoriteDate: date, likeRed: false, likeBlue: true, favoriteNumber: 1, favoriteColor: 'blue', favoriteCars: ['bmw', 'audi', 'ford'] }); - - assert.strictEqual(appInsightsMock.events.length, 1); - assert.strictEqual(appInsightsMock.events[0].name, `${prefix}/testEvent`); - assert.strictEqual(appInsightsMock.events[0].properties!['favoriteColor'], 'blue'); - assert.strictEqual(appInsightsMock.events[0].measurements!['likeRed'], 0); - assert.strictEqual(appInsightsMock.events[0].measurements!['likeBlue'], 1); - assert.strictEqual(appInsightsMock.events[0].properties!['favoriteDate'], date.toISOString()); - assert.strictEqual(appInsightsMock.events[0].properties!['favoriteCars'], JSON.stringify(['bmw', 'audi', 'ford'])); - assert.strictEqual(appInsightsMock.events[0].measurements!['favoriteNumber'], 1); - }); - - test('Nested data', () => { - adapter.log('testEvent', { - window: { - title: 'some title', - measurements: { - width: 100, - height: 200 - } - }, - nestedObj: { - nestedObj2: { - nestedObj3: { - testProperty: 'test', - } - }, - testMeasurement: 1 - } - }); - - assert.strictEqual(appInsightsMock.events.length, 1); - assert.strictEqual(appInsightsMock.events[0].name, `${prefix}/testEvent`); - - assert.strictEqual(appInsightsMock.events[0].properties!['window.title'], 'some title'); - assert.strictEqual(appInsightsMock.events[0].measurements!['window.measurements.width'], 100); - assert.strictEqual(appInsightsMock.events[0].measurements!['window.measurements.height'], 200); - - assert.strictEqual(appInsightsMock.events[0].properties!['nestedObj.nestedObj2.nestedObj3'], JSON.stringify({ 'testProperty': 'test' })); - assert.strictEqual(appInsightsMock.events[0].measurements!['nestedObj.testMeasurement'], 1); - }); - -}); diff --git a/src/vs/server/node/serverServices.ts b/src/vs/server/node/serverServices.ts index 797f29fd9e5..c20bd776c55 100644 --- a/src/vs/server/node/serverServices.ts +++ b/src/vs/server/node/serverServices.ts @@ -50,7 +50,6 @@ import { resolveCommonProperties } from 'vs/platform/telemetry/common/commonProp import { ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService'; import { getPiiPathsFromEnvironment, ITelemetryAppender, NullAppender, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; -import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender'; import ErrorTelemetry from 'vs/platform/telemetry/node/errorTelemetry'; import { IPtyService, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; import { PtyHostService } from 'vs/platform/terminal/node/ptyHostService'; @@ -73,6 +72,7 @@ import { ExtensionsScannerService } from 'vs/server/node/extensionsScannerServic import { ExtensionsProfileScannerService, IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { NullPolicyService } from 'vs/platform/policy/common/policy'; +import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender'; const eventPrefix = 'monacoworkbench'; @@ -128,16 +128,16 @@ export async function setupServerServices(connectionToken: ServerConnectionToken // Request services.set(IRequestService, new SyncDescriptor(RequestService)); - let appInsightsAppender: ITelemetryAppender = NullAppender; + let oneDsAppender: ITelemetryAppender = NullAppender; const machineId = await getMachineId(); if (supportsTelemetry(productService, environmentService)) { - if (productService.aiConfig && productService.aiConfig.asimovKey) { - appInsightsAppender = new AppInsightsAppender(eventPrefix, null, productService.aiConfig.asimovKey); - disposables.add(toDisposable(() => appInsightsAppender!.flush())); // Ensure the AI appender is disposed so that it flushes remaining data + if (productService.aiConfig && productService.aiConfig.ariaKey) { + oneDsAppender = new OneDataSystemAppender(configurationService, eventPrefix, null, productService.aiConfig.ariaKey); + disposables.add(toDisposable(() => oneDsAppender?.flush())); // Ensure the AI appender is disposed so that it flushes remaining data } const config: ITelemetryServiceConfig = { - appenders: [appInsightsAppender], + appenders: [oneDsAppender], commonProperties: resolveCommonProperties(fileService, release(), hostname(), process.arch, productService.commit, productService.version + '-remote', machineId, productService.msftInternalDomains, environmentService.installSourcePath, 'remoteAgent'), piiPaths: getPiiPathsFromEnvironment(environmentService) }; @@ -193,7 +193,7 @@ export async function setupServerServices(connectionToken: ServerConnectionToken const remoteExtensionEnvironmentChannel = new RemoteAgentEnvironmentChannel(connectionToken, environmentService, userDataProfilesService, extensionManagementCLIService, logService, extensionHostStatusService, extensionsScannerService); socketServer.registerChannel('remoteextensionsenvironment', remoteExtensionEnvironmentChannel); - const telemetryChannel = new ServerTelemetryChannel(accessor.get(IServerTelemetryService), appInsightsAppender); + const telemetryChannel = new ServerTelemetryChannel(accessor.get(IServerTelemetryService), oneDsAppender); socketServer.registerChannel('telemetry', telemetryChannel); socketServer.registerChannel(REMOTE_TERMINAL_CHANNEL_NAME, new RemoteTerminalChannel(environmentService, logService, ptyService, productService, extensionManagementService)); diff --git a/src/vs/workbench/contrib/debug/node/telemetryApp.ts b/src/vs/workbench/contrib/debug/node/telemetryApp.ts index ab6d37993ca..601ff4f9b1e 100644 --- a/src/vs/workbench/contrib/debug/node/telemetryApp.ts +++ b/src/vs/workbench/contrib/debug/node/telemetryApp.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import { Server } from 'vs/base/parts/ipc/node/ipc.cp'; -import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender'; import { TelemetryAppenderChannel } from 'vs/platform/telemetry/common/telemetryIpc'; +import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender'; -const appender = new AppInsightsAppender(process.argv[2], JSON.parse(process.argv[3]), process.argv[4]); +const appender = new OneDataSystemAppender(undefined, process.argv[2], JSON.parse(process.argv[3]), process.argv[4]); process.once('exit', () => appender.flush()); const channel = new TelemetryAppenderChannel([appender]); diff --git a/src/vs/workbench/services/telemetry/browser/telemetryService.ts b/src/vs/workbench/services/telemetry/browser/telemetryService.ts index 75701e1a088..3ad179570b6 100644 --- a/src/vs/workbench/services/telemetry/browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/browser/telemetryService.ts @@ -11,7 +11,6 @@ import { ILoggerService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { OneDataSystemWebAppender } from 'vs/platform/telemetry/browser/1dsAppender'; -import { WebAppInsightsAppender } from 'vs/platform/telemetry/browser/appInsightsAppender'; import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; import { ITelemetryData, ITelemetryInfo, ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogAppender'; @@ -38,17 +37,11 @@ export class TelemetryService extends Disposable implements ITelemetryService { ) { super(); - if (supportsTelemetry(productService, environmentService) && productService.aiConfig?.asimovKey && productService.aiConfig?.ariaKey) { + if (supportsTelemetry(productService, environmentService) && productService.aiConfig?.ariaKey) { // If remote server is present send telemetry through that, else use the client side appender - const internalTesting = configurationService.getValue('telemetry.internalTesting'); const appenders = []; - if (internalTesting || productService.aiConfig?.preferAria) { - const telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new OneDataSystemWebAppender(configurationService, 'monacoworkbench', null, productService.aiConfig?.ariaKey); - appenders.push(telemetryProvider); - } else { - const telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new WebAppInsightsAppender('monacoworkbench', productService.aiConfig?.asimovKey); - appenders.push(telemetryProvider); - } + const telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new OneDataSystemWebAppender(configurationService, 'monacoworkbench', null, productService.aiConfig?.ariaKey); + appenders.push(telemetryProvider); appenders.push(new TelemetryLogAppender(loggerService, environmentService)); const config: ITelemetryServiceConfig = { appenders, -- cgit v1.2.3 From e337c0289b320ad9e2e6d5b9b63958f75fdaaa7d Mon Sep 17 00:00:00 2001 From: Robert Jin <20613660+jzyrobert@users.noreply.github.com> Date: Thu, 7 Jul 2022 07:55:48 +0100 Subject: Edit showFoldingControls to have a never setting (#153764) --- src/vs/editor/common/config/editorOptions.ts | 10 ++++++---- src/vs/editor/contrib/folding/browser/folding.ts | 4 ++-- src/vs/editor/contrib/folding/browser/foldingDecorations.ts | 6 +++--- src/vs/monaco.d.ts | 4 ++-- .../contrib/comments/browser/commentsEditorContribution.ts | 2 +- .../contrib/notebook/browser/notebook.contribution.ts | 3 ++- src/vs/workbench/contrib/notebook/common/notebookOptions.ts | 4 ++-- 7 files changed, 18 insertions(+), 15 deletions(-) (limited to 'src/vs') diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index bafc557e3e4..2158431d8b1 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -563,7 +563,7 @@ export interface IEditorOptions { * Controls whether the fold actions in the gutter stay always visible or hide unless the mouse is over the gutter. * Defaults to 'mouseover'. */ - showFoldingControls?: 'always' | 'mouseover'; + showFoldingControls?: 'always' | 'never' | 'mouseover'; /** * Controls whether clicking on the empty content after a folded line will unfold the line. * Defaults to false. @@ -2331,6 +2331,7 @@ export class EditorLayoutInfoComputer extends ComputedEditorOption; selectionHighlight: IEditorOption; selectOnLineNumbers: IEditorOption; - showFoldingControls: IEditorOption; + showFoldingControls: IEditorOption; showUnused: IEditorOption; showDeprecated: IEditorOption; inlayHints: IEditorOption>>; diff --git a/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts b/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts index a0e155d0bdd..335976fbac8 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts @@ -859,7 +859,7 @@ export class CommentController implements IEditorContribution { } const options = this.editor.getOptions(); - if (options.get(EditorOption.folding)) { + if (options.get(EditorOption.folding) && options.get(EditorOption.showFoldingControls) !== 'never') { lineDecorationsWidth -= 16; } lineDecorationsWidth += 9; diff --git a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts index 466fd1bf565..6111d9f1caa 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -846,9 +846,10 @@ configurationRegistry.registerConfiguration({ [NotebookSetting.showFoldingControls]: { description: nls.localize('notebook.showFoldingControls.description', "Controls when the Markdown header folding arrow is shown."), type: 'string', - enum: ['always', 'mouseover'], + enum: ['always', 'never', 'mouseover'], enumDescriptions: [ nls.localize('showFoldingControls.always', "The folding controls are always visible."), + nls.localize('showFoldingControls.never', "Never show the folding controls and reduce the gutter size."), nls.localize('showFoldingControls.mouseover', "The folding controls are visible only on mouseover."), ], default: 'mouseover', diff --git a/src/vs/workbench/contrib/notebook/common/notebookOptions.ts b/src/vs/workbench/contrib/notebook/common/notebookOptions.ts index 426871f84fa..2aa4ca14cf8 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookOptions.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookOptions.ts @@ -59,7 +59,7 @@ export interface NotebookLayoutConfiguration { globalToolbar: boolean; consolidatedOutputButton: boolean; consolidatedRunButton: boolean; - showFoldingControls: 'always' | 'mouseover'; + showFoldingControls: 'always' | 'never' | 'mouseover'; dragAndDropEnabled: boolean; fontSize: number; outputFontSize: number; @@ -385,7 +385,7 @@ export class NotebookOptions extends Disposable { } private _computeShowFoldingControlsOption() { - return this.configurationService.getValue<'always' | 'mouseover'>(NotebookSetting.showFoldingControls) ?? 'mouseover'; + return this.configurationService.getValue<'always' | 'never' | 'mouseover'>(NotebookSetting.showFoldingControls) ?? 'mouseover'; } private _computeFocusIndicatorOption() { -- cgit v1.2.3 From 7efebe8df8edfd69fc7da5a8315be6703b9cf647 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 7 Jul 2022 10:42:21 +0200 Subject: focus last (not first) symbol enclosing position, refines https://github.com/microsoft/vscode/issues/154246 (#154340) --- src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts b/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts index b1ba09a6133..0702c58a85c 100644 --- a/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts +++ b/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts @@ -20,6 +20,7 @@ import { localize } from 'vs/nls'; import { IQuickPick, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { Position } from 'vs/editor/common/core/position'; +import { findLast } from 'vs/base/common/arrays'; export interface IGotoSymbolQuickPickItem extends IQuickPickItem { kind: SymbolKind; @@ -177,7 +178,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit if (items.length > 0) { picker.items = items; if (positionToEnclose && query.original.length === 0) { - const candidate = items.find(item => item.type !== 'separator' && item.range && Range.containsPosition(item.range.decoration, positionToEnclose)); + const candidate = findLast(items, item => Boolean(item.type !== 'separator' && item.range && Range.containsPosition(item.range.decoration, positionToEnclose))); if (candidate) { picker.activeItems = [candidate]; } -- cgit v1.2.3 From 89f06306f37eb7fa9c5de99757f2b070983dd1a8 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 7 Jul 2022 11:01:49 +0200 Subject: read extensions resource from userDataProfileService --- .../userDataProfile/browser/userDataProfile.ts | 22 ++++++++++++++++++++++ .../electron-sandbox/userDataProfile.ts | 2 -- src/vs/workbench/browser/web.main.ts | 5 +++-- .../browser/webExtensionsScannerService.ts | 14 +++++++------- 4 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 src/vs/platform/userDataProfile/browser/userDataProfile.ts (limited to 'src/vs') diff --git a/src/vs/platform/userDataProfile/browser/userDataProfile.ts b/src/vs/platform/userDataProfile/browser/userDataProfile.ts new file mode 100644 index 00000000000..c0cc477ed01 --- /dev/null +++ b/src/vs/platform/userDataProfile/browser/userDataProfile.ts @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IFileService } from 'vs/platform/files/common/files'; +import { ILogService } from 'vs/platform/log/common/log'; +import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; + +export class BrowserUserDataProfilesService extends UserDataProfilesService implements IUserDataProfilesService { + + constructor( + @IEnvironmentService environmentService: IEnvironmentService, + @IFileService fileService: IFileService, + @ILogService logService: ILogService, + ) { + super(environmentService, fileService, logService); + this._profiles = [this.createDefaultUserDataProfile(true)]; + } + +} diff --git a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts index 1666539da3e..57e02b114e1 100644 --- a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts @@ -16,8 +16,6 @@ export class UserDataProfilesNativeService extends UserDataProfilesService imple private readonly channel: IChannel; - override get profiles(): IUserDataProfile[] { return this._profiles; } - constructor( profiles: UriDto[], @IMainProcessService mainProcessService: IMainProcessService, diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index e9b7f4fc8b0..6dd97deb256 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -73,13 +73,14 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IProgressService } from 'vs/platform/progress/common/progress'; import { DelayedLogChannel } from 'vs/workbench/services/output/common/delayedLogChannel'; import { dirname, joinPath } from 'vs/base/common/resources'; -import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { NullPolicyService } from 'vs/platform/policy/common/policy'; import { IRemoteExplorerService, TunnelSource } from 'vs/workbench/services/remote/common/remoteExplorerService'; import { DisposableTunnel } from 'vs/platform/tunnel/common/tunnel'; import { ILabelService } from 'vs/platform/label/common/label'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { BrowserUserDataProfilesService } from 'vs/platform/userDataProfile/browser/userDataProfile'; export class BrowserMain extends Disposable { @@ -260,7 +261,7 @@ export class BrowserMain extends Disposable { await this.registerFileSystemProviders(environmentService, fileService, remoteAgentService, logService, logsPath); // User Data Profiles - const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); + const userDataProfilesService = new BrowserUserDataProfilesService(environmentService, fileService, logService); serviceCollection.set(IUserDataProfilesService, userDataProfilesService); const userDataProfileService = new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService); diff --git a/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts b/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts index fb5c4babf4a..efd825b6107 100644 --- a/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts +++ b/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts @@ -40,6 +40,7 @@ import { IProductService } from 'vs/platform/product/common/productService'; import { validateExtensionManifest } from 'vs/platform/extensions/common/extensionValidator'; import Severity from 'vs/base/common/severity'; import { IStringDictionary } from 'vs/base/common/collections'; +import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; type GalleryExtensionInfo = { readonly id: string; preRelease?: boolean; migrateStorageFrom?: string }; type ExtensionInfo = { readonly id: string; preRelease: boolean }; @@ -83,7 +84,6 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten private readonly systemExtensionsCacheResource: URI | undefined = undefined; private readonly customBuiltinExtensionsCacheResource: URI | undefined = undefined; - private readonly installedExtensionsResource: URI | undefined = undefined; private readonly resourcesAccessQueueMap = new ResourceMap>(); constructor( @@ -97,11 +97,11 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten @IExtensionStorageService private readonly extensionStorageService: IExtensionStorageService, @IStorageService private readonly storageService: IStorageService, @IProductService private readonly productService: IProductService, + @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, @ILifecycleService lifecycleService: ILifecycleService, ) { super(); if (isWeb) { - this.installedExtensionsResource = joinPath(environmentService.userRoamingDataHome, 'extensions.json'); this.systemExtensionsCacheResource = joinPath(environmentService.userRoamingDataHome, 'systemExtensionsCache.json'); this.customBuiltinExtensionsCacheResource = joinPath(environmentService.userRoamingDataHome, 'customBuiltinExtensionsCache.json'); this.registerActions(); @@ -672,7 +672,7 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten private async readInstalledExtensions(): Promise { await this.migratePackageNLSUris(); - return this.withWebExtensions(this.installedExtensionsResource); + return this.withWebExtensions(this.userDataProfileService.currentProfile.extensionsResource); } // TODO: @TylerLeonhardt/@Sandy081: Delete after 6 months @@ -680,7 +680,7 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten private migratePackageNLSUris(): Promise { if (!this._migratePackageNLSUrisPromise) { this._migratePackageNLSUrisPromise = (async () => { - const webExtensions = await this.withWebExtensions(this.installedExtensionsResource); + const webExtensions = await this.withWebExtensions(this.userDataProfileService.currentProfile.extensionsResource); if (webExtensions.some(e => !e.packageNLSUris && e.packageNLSUri)) { const migratedExtensions = await Promise.all(webExtensions.map(async e => { if (!e.packageNLSUris && e.packageNLSUri) { @@ -691,7 +691,7 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten } return e; })); - await this.withWebExtensions(this.installedExtensionsResource, () => migratedExtensions); + await this.withWebExtensions(this.userDataProfileService.currentProfile.extensionsResource, () => migratedExtensions); } })(); } @@ -699,7 +699,7 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten } private writeInstalledExtensions(updateFn: (extensions: IWebExtension[]) => IWebExtension[]): Promise { - return this.withWebExtensions(this.installedExtensionsResource, updateFn); + return this.withWebExtensions(this.userDataProfileService.currentProfile.extensionsResource, updateFn); } private readCustomBuiltinExtensionsCache(): Promise { @@ -809,7 +809,7 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten }); } run(serviceAccessor: ServicesAccessor): void { - serviceAccessor.get(IEditorService).openEditor({ resource: that.installedExtensionsResource }); + serviceAccessor.get(IEditorService).openEditor({ resource: that.userDataProfileService.currentProfile.extensionsResource }); } })); } -- cgit v1.2.3 From a5ed786a96d431daa9d85fb832f6ac1b799938da Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 7 Jul 2022 05:15:51 -0700 Subject: Revert "more specific setting names" This reverts commit 2d9947ba4e53c0889c07e3a415572ec8bad1529e. --- src/vs/platform/terminal/common/terminal.ts | 4 ++-- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 2 +- .../contrib/terminal/browser/terminalProfileResolverService.ts | 4 ++-- src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 0619e9e87fa..4ef5e51de3e 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -40,8 +40,8 @@ export const enum TerminalSettingId { DefaultProfileMacOs = 'terminal.integrated.defaultProfile.osx', DefaultProfileWindows = 'terminal.integrated.defaultProfile.windows', UseWslProfiles = 'terminal.integrated.useWslProfiles', - TabsDefaultIconColor = 'terminal.integrated.tabs.defaultIconColor', - TabsDefaultIconId = 'terminal.integrated.tabs.defaultIconId', + TabsDefaultColor = 'terminal.integrated.tabs.defaultColor', + TabsDefaultIcon = 'terminal.integrated.tabs.defaultIcon', TabsEnabled = 'terminal.integrated.tabs.enabled', TabsEnableAnimation = 'terminal.integrated.tabs.enableAnimation', TabsHideCondition = 'terminal.integrated.tabs.hideCondition', diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index dbba638fbd9..527493739e4 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -550,7 +550,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { private _getIcon(): TerminalIcon | undefined { if (!this._icon) { this._icon = this._processManager.processState >= ProcessState.Launching - ? getIconRegistry().getIcon(this._configurationService.getValue(TerminalSettingId.TabsDefaultIconId)) + ? getIconRegistry().getIcon(this._configurationService.getValue(TerminalSettingId.TabsDefaultIcon)) : undefined; } return this._icon; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts index b133c8e5d8d..f920f87442f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts @@ -117,7 +117,7 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro } getDefaultIcon(): TerminalIcon & ThemeIcon { - return this._iconRegistry.getIcon(this._configurationService.getValue(TerminalSettingId.TabsDefaultIconId)) || Codicon.terminal; + return this._iconRegistry.getIcon(this._configurationService.getValue(TerminalSettingId.TabsDefaultIcon)) || Codicon.terminal; } async resolveShellLaunchConfig(shellLaunchConfig: IShellLaunchConfig, options: IShellLaunchConfigResolveOptions): Promise { @@ -157,7 +157,7 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro // Apply the color shellLaunchConfig.color = shellLaunchConfig.color || resolvedProfile.color - || this._configurationService.getValue(TerminalSettingId.TabsDefaultIconColor); + || this._configurationService.getValue(TerminalSettingId.TabsDefaultColor); // Resolve useShellEnvironment based on the setting if it's not set if (shellLaunchConfig.useShellEnvironment === undefined) { diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index 2675a545b60..9a63b3777a8 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -40,12 +40,12 @@ const terminalConfiguration: IConfigurationNode = { type: 'boolean', default: false }, - [TerminalSettingId.TabsDefaultIconColor]: { - description: localize('terminal.integrated.tabs.defaultIconColor', "A theme color ID to associate with terminals by default."), + [TerminalSettingId.TabsDefaultColor]: { + description: localize('terminal.integrated.tabs.defaultColor', "A theme color ID to associate with terminals by default."), ...terminalColorSchema }, - [TerminalSettingId.TabsDefaultIconId]: { - description: localize('terminal.integrated.tabs.defaultIconId', "A codicon ID to associate with terminals by default."), + [TerminalSettingId.TabsDefaultIcon]: { + description: localize('terminal.integrated.tabs.defaultIcon', "A codicon ID to associate with terminals by default."), ...terminalIconSchema, default: Codicon.terminal.id, }, -- cgit v1.2.3 From 836231fd60de995826aec5a0076cff54f9802f91 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 7 Jul 2022 14:16:39 +0200 Subject: adopt profiles in web extensions scanning --- .../browser/webExtensionsScannerService.ts | 54 ++++++++++++++-------- .../common/extensionManagement.ts | 8 ++-- .../common/webExtensionManagementService.ts | 2 +- .../test/browser/workbenchTestServices.ts | 2 +- 4 files changed, 41 insertions(+), 25 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts b/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts index efd825b6107..10d163b4571 100644 --- a/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts +++ b/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts @@ -41,6 +41,7 @@ import { validateExtensionManifest } from 'vs/platform/extensions/common/extensi import Severity from 'vs/base/common/severity'; import { IStringDictionary } from 'vs/base/common/collections'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; type GalleryExtensionInfo = { readonly id: string; preRelease?: boolean; migrateStorageFrom?: string }; type ExtensionInfo = { readonly id: string; preRelease: boolean }; @@ -98,6 +99,7 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten @IStorageService private readonly storageService: IStorageService, @IProductService private readonly productService: IProductService, @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, + @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, @ILifecycleService lifecycleService: ILifecycleService, ) { super(); @@ -435,24 +437,26 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten return null; } - async addExtensionFromGallery(galleryExtension: IGalleryExtension, metadata?: Metadata): Promise { + async addExtensionFromGallery(galleryExtension: IGalleryExtension, metadata?: Metadata): Promise { const webExtension = await this.toWebExtensionFromGallery(galleryExtension, metadata); return this.addWebExtension(webExtension); } - async addExtension(location: URI, metadata?: Metadata): Promise { + async addExtension(location: URI, metadata?: Metadata): Promise { const webExtension = await this.toWebExtension(location, undefined, undefined, undefined, undefined, undefined, metadata); return this.addWebExtension(webExtension); } - async removeExtension(identifier: IExtensionIdentifier, version?: string): Promise { - await this.writeInstalledExtensions(installedExtensions => installedExtensions.filter(extension => !(areSameExtensions(extension.identifier, identifier) && (version ? extension.version === version : true)))); + async removeExtension(extension: IScannedExtension): Promise { + const profile = extension.metadata?.isApplicationScoped ? this.userDataProfilesService.defaultProfile : this.userDataProfileService.currentProfile; + await this.writeInstalledExtensions(profile, installedExtensions => installedExtensions.filter(installedExtension => !areSameExtensions(installedExtension.identifier, extension.identifier))); } private async addWebExtension(webExtension: IWebExtension): Promise { const isSystem = !!(await this.scanSystemExtensions()).find(e => areSameExtensions(e.identifier, webExtension.identifier)); const isBuiltin = !!webExtension.metadata?.isBuiltin; const extension = await this.toScannedExtension(webExtension, isBuiltin); + const profile = webExtension.metadata?.isApplicationScoped ? this.userDataProfilesService.defaultProfile : this.userDataProfileService.currentProfile; if (isSystem) { await this.writeSystemExtensionsCache(systemExtensions => { @@ -473,21 +477,21 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten return customBuiltinExtensions; }); - const installedExtensions = await this.readInstalledExtensions(); + const installedExtensions = await this.readInstalledExtensions(profile); // Also add to installed extensions if it is installed to update its version if (installedExtensions.some(e => areSameExtensions(e.identifier, webExtension.identifier))) { - await this.addToInstalledExtensions(webExtension); + await this.addToInstalledExtensions(webExtension, profile); } return extension; } // Add to installed extensions - await this.addToInstalledExtensions(webExtension); + await this.addToInstalledExtensions(webExtension, profile); return extension; } - private async addToInstalledExtensions(webExtension: IWebExtension): Promise { - await this.writeInstalledExtensions(installedExtensions => { + private async addToInstalledExtensions(webExtension: IWebExtension, profile: IUserDataProfile): Promise { + await this.writeInstalledExtensions(profile, installedExtensions => { // Remove the existing extension to avoid duplicates installedExtensions = installedExtensions.filter(e => !areSameExtensions(e.identifier, webExtension.identifier)); installedExtensions.push(webExtension); @@ -496,7 +500,17 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten } private async scanInstalledExtensions(scanOptions?: ScanOptions): Promise { - const installedExtensions = await this.readInstalledExtensions(); + let installedExtensions = await this.readInstalledExtensions(this.userDataProfileService.currentProfile); + + // If current profile is not a default profile, then add the application extensions to the list + if (!this.userDataProfileService.currentProfile.isDefault) { + // Remove application extensions from the non default profile + installedExtensions = installedExtensions.filter(i => !i.metadata?.isApplicationScoped); + // Add application extensions from the default profile to the list + const defaultProfileExtensions = await this.readInstalledExtensions(this.userDataProfilesService.defaultProfile); + installedExtensions.push(...defaultProfileExtensions.filter(i => i.metadata?.isApplicationScoped)); + } + installedExtensions.sort((a, b) => a.identifier.id < b.identifier.id ? -1 : a.identifier.id > b.identifier.id ? 1 : semver.rcompare(a.version, b.version)); const result = new Map(); for (const webExtension of installedExtensions) { @@ -670,17 +684,12 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten return manifest; } - private async readInstalledExtensions(): Promise { - await this.migratePackageNLSUris(); - return this.withWebExtensions(this.userDataProfileService.currentProfile.extensionsResource); - } - // TODO: @TylerLeonhardt/@Sandy081: Delete after 6 months private _migratePackageNLSUrisPromise: Promise | undefined; private migratePackageNLSUris(): Promise { if (!this._migratePackageNLSUrisPromise) { this._migratePackageNLSUrisPromise = (async () => { - const webExtensions = await this.withWebExtensions(this.userDataProfileService.currentProfile.extensionsResource); + const webExtensions = await this.withWebExtensions(this.userDataProfilesService.defaultProfile.extensionsResource); if (webExtensions.some(e => !e.packageNLSUris && e.packageNLSUri)) { const migratedExtensions = await Promise.all(webExtensions.map(async e => { if (!e.packageNLSUris && e.packageNLSUri) { @@ -691,15 +700,22 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten } return e; })); - await this.withWebExtensions(this.userDataProfileService.currentProfile.extensionsResource, () => migratedExtensions); + await this.withWebExtensions(this.userDataProfilesService.defaultProfile.extensionsResource, () => migratedExtensions); } })(); } return this._migratePackageNLSUrisPromise; } - private writeInstalledExtensions(updateFn: (extensions: IWebExtension[]) => IWebExtension[]): Promise { - return this.withWebExtensions(this.userDataProfileService.currentProfile.extensionsResource, updateFn); + private async readInstalledExtensions(profile: IUserDataProfile): Promise { + if (profile.isDefault) { + await this.migratePackageNLSUris(); + } + return this.withWebExtensions(profile.extensionsResource); + } + + private writeInstalledExtensions(profile: IUserDataProfile, updateFn: (extensions: IWebExtension[]) => IWebExtension[]): Promise { + return this.withWebExtensions(profile.extensionsResource, updateFn); } private readCustomBuiltinExtensionsCache(): Promise { diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts index 9c9683c1c3b..1d9dd9e5183 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts @@ -6,7 +6,7 @@ import { Event } from 'vs/base/common/event'; import { createDecorator, refineServiceDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IExtension, ExtensionType, IExtensionManifest } from 'vs/platform/extensions/common/extensions'; -import { IExtensionManagementService, IGalleryExtension, IExtensionIdentifier, ILocalExtension, InstallOptions, InstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionResult, Metadata, InstallVSIXOptions, UninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionManagementService, IGalleryExtension, ILocalExtension, InstallOptions, InstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionResult, Metadata, InstallVSIXOptions, UninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; import { URI } from 'vs/base/common/uri'; import { FileAccess } from 'vs/base/common/network'; @@ -162,9 +162,9 @@ export interface IWebExtensionsScannerService { scanExtensionsUnderDevelopment(): Promise; scanExistingExtension(extensionLocation: URI, extensionType: ExtensionType): Promise; - addExtension(location: URI, metadata?: Metadata): Promise; - addExtensionFromGallery(galleryExtension: IGalleryExtension, metadata?: Metadata): Promise; - removeExtension(identifier: IExtensionIdentifier, version?: string): Promise; + addExtension(location: URI, metadata?: Metadata): Promise; + addExtensionFromGallery(galleryExtension: IGalleryExtension, metadata?: Metadata): Promise; + removeExtension(extension: IScannedExtension, version?: string): Promise; scanMetadata(extensionLocation: URI): Promise; scanExtensionManifest(extensionLocation: URI): Promise; diff --git a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts index 2c371645082..3b7e5f36a19 100644 --- a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts @@ -196,6 +196,6 @@ class UninstallExtensionTask extends AbstractExtensionTask implements IUni } protected doRun(token: CancellationToken): Promise { - return this.webExtensionsScannerService.removeExtension(this.extension.identifier); + return this.webExtensionsScannerService.removeExtension(this.extension); } } diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index caa62c81497..ac262dac6ce 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -2014,7 +2014,7 @@ export class TestWebExtensionsScannerService implements IWebExtensionsScannerSer addExtensionFromGallery(galleryExtension: IGalleryExtension, metadata?: Partial | undefined): Promise { throw new Error('Method not implemented.'); } - removeExtension(identifier: IExtensionIdentifier, version?: string | undefined): Promise { + removeExtension(): Promise { throw new Error('Method not implemented.'); } scanMetadata(extensionLocation: URI): Promise | undefined> { -- cgit v1.2.3 From 6037448e13801c02e9949c46d62a5c378e222b27 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 7 Jul 2022 14:18:48 +0200 Subject: filter application extensions from non default profile --- .../common/extensionsScannerService.ts | 45 ++++++++++++---------- .../electron-sandbox/extensionsScannerService.ts | 4 +- .../node/extensionsScannerService.ts | 4 +- .../test/node/extensionsScannerService.test.ts | 4 +- src/vs/server/node/extensionsScannerService.ts | 4 +- 5 files changed, 36 insertions(+), 25 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/extensionManagement/common/extensionsScannerService.ts b/src/vs/platform/extensionManagement/common/extensionsScannerService.ts index 823a0be2541..194ff9965ae 100644 --- a/src/vs/platform/extensionManagement/common/extensionsScannerService.ts +++ b/src/vs/platform/extensionManagement/common/extensionsScannerService.ts @@ -27,13 +27,14 @@ import { areSameExtensions, computeTargetPlatform, ExtensionKey, getExtensionId, import { ExtensionType, ExtensionIdentifier, IExtensionManifest, TargetPlatform, IExtensionIdentifier, IRelaxedExtensionManifest, UNDEFINED_PUBLISHER, IExtensionDescription, BUILTIN_MANIFEST_CACHE_FILE, USER_MANIFEST_CACHE_FILE, MANIFEST_CACHE_FOLDER } from 'vs/platform/extensions/common/extensions'; import { validateExtensionManifest } from 'vs/platform/extensions/common/extensionValidator'; import { FileOperationResult, IFileService, toFileOperationResult } from 'vs/platform/files/common/files'; -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { Emitter, Event } from 'vs/base/common/event'; import { revive } from 'vs/base/common/marshalling'; import { IExtensionsProfileScannerService, IScannedProfileExtension } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; export type IScannedExtensionManifest = IRelaxedExtensionManifest & { __metadata?: Metadata }; @@ -139,9 +140,9 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem readonly onDidChangeCache = this._onDidChangeCache.event; private readonly obsoleteFile = joinPath(this.userExtensionsLocation, '.obsolete'); - private readonly systemExtensionsCachedScanner = this._register(new CachedExtensionsScanner(joinPath(this.cacheLocation, BUILTIN_MANIFEST_CACHE_FILE), this.obsoleteFile, this.extensionsProfileScannerService, this.fileService, this.logService)); - private readonly userExtensionsCachedScanner = this._register(new CachedExtensionsScanner(joinPath(this.cacheLocation, USER_MANIFEST_CACHE_FILE), this.obsoleteFile, this.extensionsProfileScannerService, this.fileService, this.logService)); - private readonly extensionsScanner = this._register(new ExtensionsScanner(this.obsoleteFile, this.extensionsProfileScannerService, this.fileService, this.logService)); + private readonly systemExtensionsCachedScanner = this._register(this.instantiationService.createInstance(CachedExtensionsScanner, joinPath(this.cacheLocation, BUILTIN_MANIFEST_CACHE_FILE), this.obsoleteFile)); + private readonly userExtensionsCachedScanner = this._register(this.instantiationService.createInstance(CachedExtensionsScanner, joinPath(this.cacheLocation, USER_MANIFEST_CACHE_FILE), this.obsoleteFile)); + private readonly extensionsScanner = this._register(this.instantiationService.createInstance(ExtensionsScanner, this.obsoleteFile)); constructor( readonly systemExtensionsLocation: URI, @@ -154,6 +155,7 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem @ILogService protected readonly logService: ILogService, @IEnvironmentService private readonly environmentService: IEnvironmentService, @IProductService private readonly productService: IProductService, + @IInstantiationService private readonly instantiationService: IInstantiationService, ) { super(); @@ -476,9 +478,10 @@ class ExtensionsScanner extends Disposable { constructor( private readonly obsoleteFile: URI, - protected readonly extensionsProfileScannerService: IExtensionsProfileScannerService, - protected readonly fileService: IFileService, - protected readonly logService: ILogService + @IExtensionsProfileScannerService protected readonly extensionsProfileScannerService: IExtensionsProfileScannerService, + @IUriIdentityService protected readonly uriIdentityService: IUriIdentityService, + @IFileService protected readonly fileService: IFileService, + @ILogService protected readonly logService: ILogService ) { super(); } @@ -518,15 +521,13 @@ class ExtensionsScanner extends Disposable { } private async scanExtensionsFromProfile(input: ExtensionScannerInput): Promise { - const profileExtensions = await this.scanExtensionsFromProfileResource(input.location, () => true, input); - const applicationExtensions = await this.scanApplicationExtensions(input); - return [...profileExtensions, ...applicationExtensions]; - } - - private async scanApplicationExtensions(input: ExtensionScannerInput): Promise { - return input.applicationExtensionslocation - ? this.scanExtensionsFromProfileResource(input.applicationExtensionslocation, (e) => !!e.metadata?.isApplicationScoped, input) - : []; + let profileExtensions = await this.scanExtensionsFromProfileResource(input.location, () => true, input); + if (input.applicationExtensionslocation && !this.uriIdentityService.extUri.isEqual(input.location, input.applicationExtensionslocation)) { + profileExtensions = profileExtensions.filter(e => !e.metadata?.isApplicationScoped); + const applicationExtensions = await this.scanExtensionsFromProfileResource(input.applicationExtensionslocation, (e) => !!e.metadata?.isApplicationScoped, input); + profileExtensions.push(...applicationExtensions); + } + return profileExtensions; } private async scanExtensionsFromProfileResource(profileResource: URI, filter: (extensionInfo: IScannedProfileExtension) => boolean, input: ExtensionScannerInput): Promise { @@ -845,11 +846,12 @@ class CachedExtensionsScanner extends ExtensionsScanner { constructor( private readonly cacheFile: URI, obsoleteFile: URI, - extensionsProfileScannerService: IExtensionsProfileScannerService, - fileService: IFileService, - logService: ILogService + @IExtensionsProfileScannerService extensionsProfileScannerService: IExtensionsProfileScannerService, + @IUriIdentityService uriIdentityService: IUriIdentityService, + @IFileService fileService: IFileService, + @ILogService logService: ILogService ) { - super(obsoleteFile, extensionsProfileScannerService, fileService, logService); + super(obsoleteFile, extensionsProfileScannerService, uriIdentityService, fileService, logService); } override async scanExtensions(input: ExtensionScannerInput): Promise { @@ -947,13 +949,14 @@ export class NativeExtensionsScannerService extends AbstractExtensionsScannerSer logService: ILogService, environmentService: IEnvironmentService, productService: IProductService, + instantiationService: IInstantiationService, ) { super( systemExtensionsLocation, userExtensionsLocation, joinPath(userHome, '.vscode-oss-dev', 'extensions', 'control.json'), joinPath(userDataPath, MANIFEST_CACHE_FOLDER), - userDataProfilesService, extensionsProfileScannerService, fileService, logService, environmentService, productService); + userDataProfilesService, extensionsProfileScannerService, fileService, logService, environmentService, productService, instantiationService); this.translationsPromise = (async () => { if (platform.translationsConfigFile) { try { diff --git a/src/vs/platform/extensionManagement/electron-sandbox/extensionsScannerService.ts b/src/vs/platform/extensionManagement/electron-sandbox/extensionsScannerService.ts index cfc0d5dacf3..9503799fef8 100644 --- a/src/vs/platform/extensionManagement/electron-sandbox/extensionsScannerService.ts +++ b/src/vs/platform/extensionManagement/electron-sandbox/extensionsScannerService.ts @@ -9,6 +9,7 @@ import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagemen import { IExtensionsScannerService, NativeExtensionsScannerService, } from 'vs/platform/extensionManagement/common/extensionsScannerService'; import { IFileService } from 'vs/platform/files/common/files'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; @@ -22,13 +23,14 @@ export class ExtensionsScannerService extends NativeExtensionsScannerService imp @ILogService logService: ILogService, @INativeEnvironmentService environmentService: INativeEnvironmentService, @IProductService productService: IProductService, + @IInstantiationService instantiationService: IInstantiationService, ) { super( URI.file(environmentService.builtinExtensionsPath), URI.file(environmentService.extensionsPath), environmentService.userHome, URI.file(environmentService.userDataPath), - userDataProfilesService, extensionsProfileScannerService, fileService, logService, environmentService, productService); + userDataProfilesService, extensionsProfileScannerService, fileService, logService, environmentService, productService, instantiationService); } } diff --git a/src/vs/platform/extensionManagement/node/extensionsScannerService.ts b/src/vs/platform/extensionManagement/node/extensionsScannerService.ts index 9d90bf687d6..20a1fd0a61d 100644 --- a/src/vs/platform/extensionManagement/node/extensionsScannerService.ts +++ b/src/vs/platform/extensionManagement/node/extensionsScannerService.ts @@ -8,6 +8,7 @@ import { INativeEnvironmentService } from 'vs/platform/environment/common/enviro import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; import { IExtensionsScannerService, NativeExtensionsScannerService, } from 'vs/platform/extensionManagement/common/extensionsScannerService'; import { IFileService } from 'vs/platform/files/common/files'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; @@ -21,13 +22,14 @@ export class ExtensionsScannerService extends NativeExtensionsScannerService imp @ILogService logService: ILogService, @INativeEnvironmentService environmentService: INativeEnvironmentService, @IProductService productService: IProductService, + @IInstantiationService instantiationService: IInstantiationService, ) { super( URI.file(environmentService.builtinExtensionsPath), URI.file(environmentService.extensionsPath), environmentService.userHome, URI.file(environmentService.userDataPath), - userDataProfilesService, extensionsProfileScannerService, fileService, logService, environmentService, productService); + userDataProfilesService, extensionsProfileScannerService, fileService, logService, environmentService, productService, instantiationService); } } diff --git a/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts b/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts index cdfaa38b842..8409d699f37 100644 --- a/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts +++ b/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts @@ -14,6 +14,7 @@ import { ExtensionType, IExtensionManifest, MANIFEST_CACHE_FOLDER, TargetPlatfor import { IFileService } from 'vs/platform/files/common/files'; import { FileService } from 'vs/platform/files/common/fileService'; import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { ILogService, NullLogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; @@ -31,13 +32,14 @@ class ExtensionsScannerService extends AbstractExtensionsScannerService implemen @ILogService logService: ILogService, @INativeEnvironmentService nativeEnvironmentService: INativeEnvironmentService, @IProductService productService: IProductService, + @IInstantiationService instantiationService: IInstantiationService, ) { super( URI.file(nativeEnvironmentService.builtinExtensionsPath), URI.file(nativeEnvironmentService.extensionsPath), joinPath(nativeEnvironmentService.userHome, '.vscode-oss-dev', 'extensions', 'control.json'), joinPath(ROOT, MANIFEST_CACHE_FOLDER), - userDataProfilesService, extensionsProfileScannerService, fileService, logService, nativeEnvironmentService, productService); + userDataProfilesService, extensionsProfileScannerService, fileService, logService, nativeEnvironmentService, productService, instantiationService); } protected async getTranslations(language: string): Promise { diff --git a/src/vs/server/node/extensionsScannerService.ts b/src/vs/server/node/extensionsScannerService.ts index 5f2be934b4b..b780ab7d6e8 100644 --- a/src/vs/server/node/extensionsScannerService.ts +++ b/src/vs/server/node/extensionsScannerService.ts @@ -10,6 +10,7 @@ import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagemen import { AbstractExtensionsScannerService, IExtensionsScannerService, Translations } from 'vs/platform/extensionManagement/common/extensionsScannerService'; import { MANIFEST_CACHE_FOLDER } from 'vs/platform/extensions/common/extensions'; import { IFileService } from 'vs/platform/files/common/files'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; @@ -24,13 +25,14 @@ export class ExtensionsScannerService extends AbstractExtensionsScannerService i @ILogService logService: ILogService, @INativeEnvironmentService private readonly nativeEnvironmentService: INativeEnvironmentService, @IProductService productService: IProductService, + @IInstantiationService instantiationService: IInstantiationService, ) { super( URI.file(nativeEnvironmentService.builtinExtensionsPath), URI.file(nativeEnvironmentService.extensionsPath), joinPath(nativeEnvironmentService.userHome, '.vscode-oss-dev', 'extensions', 'control.json'), joinPath(URI.file(nativeEnvironmentService.userDataPath), MANIFEST_CACHE_FOLDER), - userDataProfilesService, extensionsProfileScannerService, fileService, logService, nativeEnvironmentService, productService); + userDataProfilesService, extensionsProfileScannerService, fileService, logService, nativeEnvironmentService, productService, instantiationService); } protected async getTranslations(language: string): Promise { -- cgit v1.2.3 From f7f3f48049934cf5d3a060aa911dafed5046500c Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 7 Jul 2022 05:17:24 -0700 Subject: Mention icon in terminal icon/color settings Fixes #154354 --- src/vs/platform/terminal/common/terminalPlatformConfiguration.ts | 4 ++-- src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminalPlatformConfiguration.ts b/src/vs/platform/terminal/common/terminalPlatformConfiguration.ts index 79db8443a33..45bad3159a1 100644 --- a/src/vs/platform/terminal/common/terminalPlatformConfiguration.ts +++ b/src/vs/platform/terminal/common/terminalPlatformConfiguration.ts @@ -46,11 +46,11 @@ const terminalProfileBaseProperties: IJSONSchemaMap = { type: 'boolean' }, icon: { - description: localize('terminalProfile.icon', 'A codicon ID to associate with this terminal.'), + description: localize('terminalProfile.icon', 'A codicon ID to associate with the terminal icon.'), ...terminalIconSchema }, color: { - description: localize('terminalProfile.color', 'A theme color ID to associate with this terminal.'), + description: localize('terminalProfile.color', 'A theme color ID to associate with the terminal icon.'), ...terminalColorSchema }, env: { diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index 9a63b3777a8..3c5513e7c90 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -41,11 +41,11 @@ const terminalConfiguration: IConfigurationNode = { default: false }, [TerminalSettingId.TabsDefaultColor]: { - description: localize('terminal.integrated.tabs.defaultColor', "A theme color ID to associate with terminals by default."), + description: localize('terminal.integrated.tabs.defaultColor', "A theme color ID to associate with terminal icons by default."), ...terminalColorSchema }, [TerminalSettingId.TabsDefaultIcon]: { - description: localize('terminal.integrated.tabs.defaultIcon', "A codicon ID to associate with terminals by default."), + description: localize('terminal.integrated.tabs.defaultIcon', "A codicon ID to associate with terminal icons by default."), ...terminalIconSchema, default: Codicon.terminal.id, }, -- cgit v1.2.3 From d68ae55c9a9135461e948382900c88ef38e442b6 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Thu, 7 Jul 2022 08:38:13 -0400 Subject: show fit to content width in command palette (#154325) * fix #152748 * better solution Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com> * Update src/vs/workbench/contrib/terminal/browser/terminalActions.ts * add comma Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com> --- src/vs/workbench/contrib/terminal/browser/terminalActions.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index ee79622f1c2..c46f4d33c30 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -2127,10 +2127,11 @@ export function registerTerminalActions() { title: { value: localize('workbench.action.terminal.sizeToContentWidth', "Toggle Size to Content Width"), original: 'Toggle Size to Content Width' }, f1: true, category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen, TerminalContextKeys.focus), + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), keybinding: { primary: KeyMod.Alt | KeyCode.KeyZ, - weight: KeybindingWeight.WorkbenchContrib + weight: KeybindingWeight.WorkbenchContrib, + when: TerminalContextKeys.focus } }); } @@ -2138,12 +2139,13 @@ export function registerTerminalActions() { await accessor.get(ITerminalService).doWithActiveInstance(t => t.toggleSizeToContentWidth()); } }); + registerAction2(class extends Action2 { constructor() { super({ id: TerminalCommandId.SizeToContentWidthInstance, title: terminalStrings.toggleSizeToContentWidth, - f1: true, + f1: false, category, precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus) }); -- cgit v1.2.3 From 6cf558d7a0bf13ef6726bb5fe91219633a042094 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Thu, 7 Jul 2022 08:38:30 -0400 Subject: make task setting keys into an enum (#154322) --- .../contrib/tasks/browser/abstractTaskService.ts | 28 ++++++++++++---------- .../contrib/tasks/browser/task.contribution.ts | 20 ++++++++-------- .../contrib/tasks/browser/terminalTaskSystem.ts | 6 ++--- src/vs/workbench/contrib/tasks/common/tasks.ts | 23 ++++++++++++++++++ .../test/browser/configurationService.test.ts | 11 +++++---- 5 files changed, 57 insertions(+), 31 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index da7e0dccf58..644103faf6a 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -53,7 +53,9 @@ import { ITaskSet, TaskGroup, ExecutionEngine, JsonSchemaVersion, TaskSourceKind, TaskSorter, ITaskIdentifier, TASK_RUNNING_STATE, TaskRunSource, KeyedTaskIdentifier as KeyedTaskIdentifier, TaskDefinition, RuntimeType, - USER_TASKS_GROUP_KEY + USER_TASKS_GROUP_KEY, + TaskSettingId, + TasksSchemaProperties } from 'vs/workbench/contrib/tasks/common/tasks'; import { ITaskService, ITaskProvider, IProblemMatcherRunOptions, ICustomizationProperties, ITaskFilter, IWorkspaceFolderTaskResult, CustomExecutionSupportedContext, ShellExecutionSupportedContext, ProcessExecutionSupportedContext } from 'vs/workbench/contrib/tasks/common/taskService'; import { getTemplates as getTaskTemplates } from 'vs/workbench/contrib/tasks/common/taskTemplates'; @@ -1093,7 +1095,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } private _isProvideTasksEnabled(): boolean { - const settingValue = this._configurationService.getValue('task.autoDetect'); + const settingValue = this._configurationService.getValue(TaskSettingId.AutoDetect); return settingValue === 'on'; } @@ -1688,7 +1690,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer Prompt = 'prompt' } - const saveBeforeRunTaskConfig: SaveBeforeRunConfigOptions = this._configurationService.getValue('task.saveBeforeRun'); + const saveBeforeRunTaskConfig: SaveBeforeRunConfigOptions = this._configurationService.getValue(TaskSettingId.SaveBeforeRun); if (saveBeforeRunTaskConfig === SaveBeforeRunConfigOptions.Never) { return false; @@ -3523,11 +3525,11 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } const configTasks: (TaskConfig.ICustomTask | TaskConfig.IConfiguringTask)[] = []; - const suppressTaskName = !!this._configurationService.getValue('tasks.suppressTaskName', { resource: folder.uri }); + const suppressTaskName = !!this._configurationService.getValue(TasksSchemaProperties.SuppressTaskName, { resource: folder.uri }); const globalConfig = { - windows: this._configurationService.getValue('tasks.windows', { resource: folder.uri }), - osx: this._configurationService.getValue('tasks.osx', { resource: folder.uri }), - linux: this._configurationService.getValue('tasks.linux', { resource: folder.uri }) + windows: this._configurationService.getValue(TasksSchemaProperties.Windows, { resource: folder.uri }), + osx: this._configurationService.getValue(TasksSchemaProperties.Osx, { resource: folder.uri }), + linux: this._configurationService.getValue(TasksSchemaProperties.Linux, { resource: folder.uri }) }; tasks.get(folder).forEach(task => { const configTask = this._upgradeTask(task, suppressTaskName, globalConfig); @@ -3539,14 +3541,14 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer this._workspaceTasksPromise = undefined; await this._writeConfiguration(folder, 'tasks.tasks', configTasks); await this._writeConfiguration(folder, 'tasks.version', '2.0.0'); - if (this._configurationService.getValue('tasks.showOutput', { resource: folder.uri })) { - await this._configurationService.updateValue('tasks.showOutput', undefined, { resource: folder.uri }); + if (this._configurationService.getValue(TasksSchemaProperties.ShowOutput, { resource: folder.uri })) { + await this._configurationService.updateValue(TasksSchemaProperties.ShowOutput, undefined, { resource: folder.uri }); } - if (this._configurationService.getValue('tasks.isShellCommand', { resource: folder.uri })) { - await this._configurationService.updateValue('tasks.isShellCommand', undefined, { resource: folder.uri }); + if (this._configurationService.getValue(TasksSchemaProperties.IsShellCommand, { resource: folder.uri })) { + await this._configurationService.updateValue(TasksSchemaProperties.IsShellCommand, undefined, { resource: folder.uri }); } - if (this._configurationService.getValue('tasks.suppressTaskName', { resource: folder.uri })) { - await this._configurationService.updateValue('tasks.suppressTaskName', undefined, { resource: folder.uri }); + if (this._configurationService.getValue(TasksSchemaProperties.SuppressTaskName, { resource: folder.uri })) { + await this._configurationService.updateValue(TasksSchemaProperties.SuppressTaskName, undefined, { resource: folder.uri }); } } this._updateSetup(); diff --git a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts index eff66ddba5f..911ee6ec393 100644 --- a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts +++ b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts @@ -20,7 +20,7 @@ import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor, IStatus import { IOutputChannelRegistry, Extensions as OutputExt } from 'vs/workbench/services/output/common/output'; -import { ITaskEvent, TaskEventKind, TaskGroup, TASKS_CATEGORY, TASK_RUNNING_STATE } from 'vs/workbench/contrib/tasks/common/tasks'; +import { ITaskEvent, TaskEventKind, TaskGroup, TaskSettingId, TASKS_CATEGORY, TASK_RUNNING_STATE } from 'vs/workbench/contrib/tasks/common/tasks'; import { ITaskService, ProcessExecutionSupportedContext, ShellExecutionSupportedContext } from 'vs/workbench/contrib/tasks/common/taskService'; import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry, IWorkbenchContribution } from 'vs/workbench/common/contributions'; @@ -431,7 +431,7 @@ configurationRegistry.registerConfiguration({ title: nls.localize('tasksConfigurationTitle', "Tasks"), type: 'object', properties: { - 'task.problemMatchers.neverPrompt': { + [TaskSettingId.ProblemMatchersNeverPrompt]: { markdownDescription: nls.localize('task.problemMatchers.neverPrompt', "Configures whether to show the problem matcher prompt when running a task. Set to `true` to never prompt, or use a dictionary of task types to turn off prompting only for specific task types."), 'oneOf': [ { @@ -453,13 +453,13 @@ configurationRegistry.registerConfiguration({ ], default: false }, - 'task.autoDetect': { + [TaskSettingId.AutoDetect]: { markdownDescription: nls.localize('task.autoDetect', "Controls enablement of `provideTasks` for all task provider extension. If the Tasks: Run Task command is slow, disabling auto detect for task providers may help. Individual extensions may also provide settings that disable auto detection."), type: 'string', enum: ['on', 'off'], default: 'on' }, - 'task.slowProviderWarning': { + [TaskSettingId.SlowProviderWarning]: { markdownDescription: nls.localize('task.slowProviderWarning', "Configures whether a warning is shown when a provider is slow"), 'oneOf': [ { @@ -476,32 +476,32 @@ configurationRegistry.registerConfiguration({ ], default: true }, - 'task.quickOpen.history': { + [TaskSettingId.QuickOpenHistory]: { markdownDescription: nls.localize('task.quickOpen.history', "Controls the number of recent items tracked in task quick open dialog."), type: 'number', default: 30, minimum: 0, maximum: 30 }, - 'task.quickOpen.detail': { + [TaskSettingId.QuickOpenDetail]: { markdownDescription: nls.localize('task.quickOpen.detail', "Controls whether to show the task detail for tasks that have a detail in task quick picks, such as Run Task."), type: 'boolean', default: true }, - 'task.quickOpen.skip': { + [TaskSettingId.QuickOpenSkip]: { type: 'boolean', description: nls.localize('task.quickOpen.skip', "Controls whether the task quick pick is skipped when there is only one task to pick from."), default: false }, - 'task.quickOpen.showAll': { + [TaskSettingId.QuickOpenShowAll]: { type: 'boolean', description: nls.localize('task.quickOpen.showAll', "Causes the Tasks: Run Task command to use the slower \"show all\" behavior instead of the faster two level picker where tasks are grouped by provider."), default: false }, - 'task.showDecorations': { + [TaskSettingId.ShowDecorations]: { type: 'boolean', description: nls.localize('task.showDecorations', "Shows decorations at points of interest in the terminal buffer such as the first problem found via a watch task. Note that this will only take effect for future tasks."), default: true }, - 'task.saveBeforeRun': { + [TaskSettingId.SaveBeforeRun]: { markdownDescription: nls.localize( 'task.saveBeforeRun', 'Save all dirty editors before running a task.' diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index 0beaded25b4..754a84163c1 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -31,7 +31,7 @@ import { IOutputService } from 'vs/workbench/services/output/common/output'; import { StartStopProblemCollector, WatchingProblemCollector, ProblemCollectorEventKind, ProblemHandlingStrategy } from 'vs/workbench/contrib/tasks/common/problemCollectors'; import { Task, CustomTask, ContributedTask, RevealKind, CommandOptions, IShellConfiguration, RuntimeType, PanelKind, - TaskEvent, TaskEventKind, IShellQuotingOptions, ShellQuoting, CommandString, ICommandConfiguration, IExtensionTaskSource, TaskScope, RevealProblemKind, DependsOrder, TaskSourceKind, InMemoryTask, ITaskEvent + TaskEvent, TaskEventKind, IShellQuotingOptions, ShellQuoting, CommandString, ICommandConfiguration, IExtensionTaskSource, TaskScope, RevealProblemKind, DependsOrder, TaskSourceKind, InMemoryTask, ITaskEvent, TaskSettingId } from 'vs/workbench/contrib/tasks/common/tasks'; import { ITaskSystem, ITaskSummary, ITaskExecuteResult, TaskExecuteKind, TaskError, TaskErrors, ITaskResolver, @@ -209,10 +209,10 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { private readonly _onDidStateChange: Emitter; get taskShellIntegrationStartSequence(): string { - return this._configurationService.getValue('task.showDecorations') ? VSCodeSequence(VSCodeOscPt.PromptStart) + VSCodeSequence(VSCodeOscPt.Property, `${VSCodeOscProperty.Task}=True`) + VSCodeSequence(VSCodeOscPt.CommandStart) : ''; + return this._configurationService.getValue(TaskSettingId.ShowDecorations) ? VSCodeSequence(VSCodeOscPt.PromptStart) + VSCodeSequence(VSCodeOscPt.Property, `${VSCodeOscProperty.Task}=True`) + VSCodeSequence(VSCodeOscPt.CommandStart) : ''; } get taskShellIntegrationOutputSequence(): string { - return this._configurationService.getValue('task.showDecorations') ? VSCodeSequence(VSCodeOscPt.CommandExecuted) : ''; + return this._configurationService.getValue(TaskSettingId.ShowDecorations) ? VSCodeSequence(VSCodeOscPt.CommandExecuted) : ''; } constructor( diff --git a/src/vs/workbench/contrib/tasks/common/tasks.ts b/src/vs/workbench/contrib/tasks/common/tasks.ts index f4956cc9aef..2300c659cb0 100644 --- a/src/vs/workbench/contrib/tasks/common/tasks.ts +++ b/src/vs/workbench/contrib/tasks/common/tasks.ts @@ -1190,6 +1190,29 @@ export namespace KeyedTaskIdentifier { } } +export const enum TaskSettingId { + AutoDetect = 'task.autoDetect', + SaveBeforeRun = 'task.saveBeforeRun', + ShowDecorations = 'task.showDecorations', + ProblemMatchersNeverPrompt = 'task.problemMatchers.neverPrompt', + SlowProviderWarning = 'task.slowProviderWarning', + QuickOpenHistory = 'task.quickOpen.history', + QuickOpenDetail = 'task.quickOpen.detail', + QuickOpenSkip = 'task.quickOpen.skip', + QuickOpenShowAll = 'task.quickOpen.showAll' +} + +export const enum TasksSchemaProperties { + Tasks = 'tasks', + SuppressTaskName = 'tasks.suppressTaskName', + Windows = 'tasks.windows', + Osx = 'tasks.osx', + Linux = 'tasks.linux', + ShowOutput = 'tasks.showOutput', + IsShellCommand = 'tasks.isShellCommand', + ServiceTestSetting = 'tasks.service.testSetting', +} + export namespace TaskDefinition { export function createTaskIdentifier(external: ITaskIdentifier, reporter: { error(message: string): void }): KeyedTaskIdentifier | undefined { const definition = TaskDefinitionRegistry.get(external.type); diff --git a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts index 1254e1a9b0b..41573109ed5 100644 --- a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts @@ -50,6 +50,7 @@ import { FilePolicyService } from 'vs/platform/policy/common/filePolicyService'; import { runWithFakedTimers } from 'vs/base/test/common/timeTravelScheduler'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { TasksSchemaProperties } from 'vs/workbench/contrib/tasks/common/tasks'; function convertToWorkspacePayload(folder: URI): ISingleFolderWorkspaceIdentifier { return { @@ -1096,7 +1097,7 @@ suite('WorkspaceConfigurationService - Folder', () => { test('update workspace configuration', () => { return testObject.updateValue('tasks.service.testSetting', 'value', ConfigurationTarget.WORKSPACE) - .then(() => assert.strictEqual(testObject.getValue('tasks.service.testSetting'), 'value')); + .then(() => assert.strictEqual(testObject.getValue(TasksSchemaProperties.ServiceTestSetting), 'value')); }); test('update resource configuration', () => { @@ -1150,7 +1151,7 @@ suite('WorkspaceConfigurationService - Folder', () => { test('update tasks configuration', () => { return testObject.updateValue('tasks', { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] }, ConfigurationTarget.WORKSPACE) - .then(() => assert.deepStrictEqual(testObject.getValue('tasks'), { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] })); + .then(() => assert.deepStrictEqual(testObject.getValue(TasksSchemaProperties.Tasks), { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] })); }); test('update user configuration should trigger change event before promise is resolve', () => { @@ -1994,7 +1995,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => { }; await jsonEditingServce.write((workspaceContextService.getWorkspace().configuration!), [{ path: ['tasks'], value: expectedTasksConfiguration }], true); await testObject.reloadConfiguration(); - const actual = testObject.getValue('tasks'); + const actual = testObject.getValue(TasksSchemaProperties.Tasks); assert.deepStrictEqual(actual, expectedTasksConfiguration); }); @@ -2119,7 +2120,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => { test('update tasks configuration in a folder', async () => { const workspace = workspaceContextService.getWorkspace(); await testObject.updateValue('tasks', { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] }, { resource: workspace.folders[0].uri }, ConfigurationTarget.WORKSPACE_FOLDER); - assert.deepStrictEqual(testObject.getValue('tasks', { resource: workspace.folders[0].uri }), { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] }); + assert.deepStrictEqual(testObject.getValue(TasksSchemaProperties.Tasks, { resource: workspace.folders[0].uri }), { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] }); }); test('update launch configuration in a workspace', async () => { @@ -2132,7 +2133,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => { const workspace = workspaceContextService.getWorkspace(); const tasks = { 'version': '2.0.0', tasks: [{ 'label': 'myTask' }] }; await testObject.updateValue('tasks', tasks, { resource: workspace.folders[0].uri }, ConfigurationTarget.WORKSPACE, true); - assert.deepStrictEqual(testObject.getValue('tasks'), tasks); + assert.deepStrictEqual(testObject.getValue(TasksSchemaProperties.Tasks), tasks); }); test('configuration of newly added folder is available on configuration change event', async () => { -- cgit v1.2.3 From e5f5a16b745e27bd87ffc774c26e502e8b1a2d61 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 7 Jul 2022 14:55:51 +0200 Subject: joh/issue145374 (#154360) * enroll more places into `snippetWorkspaceEdit` proposal, https://github.com/microsoft/vscode/issues/145374 * tweak API proposal for snippet edits, make this `WorkspaceEdit` only, remove old proposal bit https://github.com/microsoft/vscode/issues/145374 --- .../api/common/extHostFileSystemEventService.ts | 11 ++++++----- .../api/common/extHostLanguageFeatures.ts | 8 ++++---- .../workbench/api/common/extHostTypeConverters.ts | 23 ++++++++++++++++------ src/vs/workbench/api/common/extHostTypes.ts | 20 +++++++++++++++---- 4 files changed, 43 insertions(+), 19 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/api/common/extHostFileSystemEventService.ts b/src/vs/workbench/api/common/extHostFileSystemEventService.ts index d4f86a58255..79aa5cd22f4 100644 --- a/src/vs/workbench/api/common/extHostFileSystemEventService.ts +++ b/src/vs/workbench/api/common/extHostFileSystemEventService.ts @@ -16,6 +16,7 @@ import { FileOperation } from 'vs/platform/files/common/files'; import { CancellationToken } from 'vs/base/common/cancellation'; import { ILogService } from 'vs/platform/log/common/log'; import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; +import { isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; class FileSystemWatcher implements vscode.FileSystemWatcher { @@ -223,14 +224,14 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ private async _fireWillEvent(emitter: AsyncEmitter, data: IWaitUntilData, timeout: number, token: CancellationToken): Promise { const extensionNames = new Set(); - const edits: WorkspaceEdit[] = []; + const edits: [IExtensionDescription, WorkspaceEdit][] = []; - await emitter.fireAsync(data, token, async (thenable, listener) => { + await emitter.fireAsync(data, token, async (thenable: Promise, listener) => { // ignore all results except for WorkspaceEdits. Those are stored in an array. const now = Date.now(); const result = await Promise.resolve(thenable); if (result instanceof WorkspaceEdit) { - edits.push(result); + edits.push([(>listener).extension, result]); extensionNames.add((>listener).extension.displayName ?? (>listener).extension.identifier.value); } @@ -249,11 +250,11 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ // concat all WorkspaceEdits collected via waitUntil-call and send them over to the renderer const dto: IWorkspaceEditDto = { edits: [] }; - for (const edit of edits) { + for (const [extension, edit] of edits) { const { edits } = typeConverter.WorkspaceEdit.from(edit, { getTextDocumentVersion: uri => this._extHostDocumentsAndEditors.getDocument(uri)?.version, getNotebookDocumentVersion: () => undefined, - }); + }, isProposedApiEnabled(extension, 'snippetWorkspaceEdit')); dto.edits = dto.edits.concat(edits); } return { edit: dto, extensionNames: Array.from(extensionNames) }; diff --git a/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/src/vs/workbench/api/common/extHostLanguageFeatures.ts index afdb6fbb015..4c70e92c5e6 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatures.ts @@ -446,7 +446,7 @@ class CodeActionAdapter { title: candidate.title, command: candidate.command && this._commands.toInternal(candidate.command, disposables), diagnostics: candidate.diagnostics && candidate.diagnostics.map(typeConvert.Diagnostic.from), - edit: candidate.edit && typeConvert.WorkspaceEdit.from(candidate.edit), + edit: candidate.edit && typeConvert.WorkspaceEdit.from(candidate.edit, undefined, isProposedApiEnabled(this._extension, 'snippetWorkspaceEdit')), kind: candidate.kind && candidate.kind.value, isPreferred: candidate.isPreferred, disabled: candidate.disabled?.reason @@ -467,7 +467,7 @@ class CodeActionAdapter { } const resolvedItem = (await this._provider.resolveCodeAction(item, token)) ?? item; return resolvedItem?.edit - ? typeConvert.WorkspaceEdit.from(resolvedItem.edit) + ? typeConvert.WorkspaceEdit.from(resolvedItem.edit, undefined, isProposedApiEnabled(this._extension, 'snippetWorkspaceEdit')) : undefined; } @@ -522,7 +522,7 @@ class DocumentPasteEditProvider { return { insertText: typeof edit.insertText === 'string' ? edit.insertText : { snippet: edit.insertText.value }, - additionalEdit: edit.additionalEdit ? typeConvert.WorkspaceEdit.from(edit.additionalEdit) : undefined, + additionalEdit: edit.additionalEdit ? typeConvert.WorkspaceEdit.from(edit.additionalEdit, undefined, true) : undefined, }; } } @@ -1808,7 +1808,7 @@ class DocumentOnDropEditAdapter { } return { insertText: typeof edit.insertText === 'string' ? edit.insertText : { snippet: edit.insertText.value }, - additionalEdit: edit.additionalEdit ? typeConvert.WorkspaceEdit.from(edit.additionalEdit) : undefined, + additionalEdit: edit.additionalEdit ? typeConvert.WorkspaceEdit.from(edit.additionalEdit, undefined, true) : undefined, }; } } diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index f7917e317d2..52b5d2c712e 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -598,17 +598,28 @@ export namespace WorkspaceEdit { } else if (entry._type === types.FileEditType.Text) { // text edits - const edit = { + result.edits.push({ resource: entry.uri, textEdit: TextEdit.from(entry.edit), versionId: !toCreate.has(entry.uri) ? versionInfo?.getTextDocumentVersion(entry.uri) : undefined, metadata: entry.metadata - }; - if (allowSnippetTextEdit && entry.edit.newText2 instanceof types.SnippetString) { - edit.textEdit.insertAsSnippet = true; - edit.textEdit.text = entry.edit.newText2.value; + }); + } else if (entry._type === types.FileEditType.Snippet) { + // snippet text edits + if (!allowSnippetTextEdit) { + console.warn(`DROPPING snippet text edit because proposal IS NOT ENABLED`, entry); + continue; } - result.edits.push(edit); + result.edits.push({ + resource: entry.uri, + textEdit: { + range: Range.from(entry.range), + text: entry.edit.value, + insertAsSnippet: true + }, + versionId: !toCreate.has(entry.uri) ? versionInfo?.getTextDocumentVersion(entry.uri) : undefined, + metadata: entry.metadata + }); } else if (entry._type === types.FileEditType.Cell) { // cell edit diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index ce30f68d26e..4eac2a31120 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -549,7 +549,6 @@ export class TextEdit { protected _range: Range; protected _newText: string | null; - newText2?: string | SnippetString; protected _newEol?: EndOfLine; get range(): Range { @@ -660,6 +659,7 @@ export const enum FileEditType { Text = 2, Cell = 3, CellReplace = 5, + Snippet = 6, } export interface IFileOperation { @@ -677,6 +677,14 @@ export interface IFileTextEdit { metadata?: vscode.WorkspaceEditEntryMetadata; } +export interface IFileSnippetTextEdit { + _type: FileEditType.Snippet; + uri: URI; + range: vscode.Range; + edit: vscode.SnippetString; + metadata?: vscode.WorkspaceEditEntryMetadata; +} + export interface IFileCellEdit { _type: FileEditType.Cell; uri: URI; @@ -695,7 +703,7 @@ export interface ICellEdit { } -type WorkspaceEditEntry = IFileOperation | IFileTextEdit | IFileCellEdit | ICellEdit; +type WorkspaceEditEntry = IFileOperation | IFileTextEdit | IFileSnippetTextEdit | IFileCellEdit | ICellEdit; @es5ClassCompat export class WorkspaceEdit implements vscode.WorkspaceEdit { @@ -762,8 +770,12 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit { // --- text - replace(uri: URI, range: Range, newText: string, metadata?: vscode.WorkspaceEditEntryMetadata): void { - this._edits.push({ _type: FileEditType.Text, uri, edit: new TextEdit(range, newText), metadata }); + replace(uri: URI, range: Range, newText: string | vscode.SnippetString, metadata?: vscode.WorkspaceEditEntryMetadata): void { + if (typeof newText === 'string') { + this._edits.push({ _type: FileEditType.Text, uri, edit: new TextEdit(range, newText), metadata }); + } else { + this._edits.push({ _type: FileEditType.Snippet, uri, range, edit: newText, metadata }); + } } insert(resource: URI, position: Position, newText: string, metadata?: vscode.WorkspaceEditEntryMetadata): void { -- cgit v1.2.3 From dd17e8276e1628c5c12b69754c56ff536ac7e580 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 7 Jul 2022 15:20:33 +0200 Subject: standalone theme service: improve detection, toggle (#154357) * standalone theme service: clean up os theme detection * toggle to matching high contrast --- .../standalone/browser/standaloneThemeService.ts | 70 +++++++++++----------- .../toggleHighContrast/toggleHighContrast.ts | 12 ++-- 2 files changed, 43 insertions(+), 39 deletions(-) (limited to 'src/vs') diff --git a/src/vs/editor/standalone/browser/standaloneThemeService.ts b/src/vs/editor/standalone/browser/standaloneThemeService.ts index 4690b299892..1366682b48f 100644 --- a/src/vs/editor/standalone/browser/standaloneThemeService.ts +++ b/src/vs/editor/standalone/browser/standaloneThemeService.ts @@ -17,13 +17,13 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { asCssVariableName, ColorIdentifier, Extensions, IColorRegistry } from 'vs/platform/theme/common/colorRegistry'; import { Extensions as ThemingExtensions, ICssStyleCollector, IFileIconTheme, IProductIconTheme, IThemingRegistry, ITokenStyle } from 'vs/platform/theme/common/themeService'; import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; -import { ColorScheme, isDark } from 'vs/platform/theme/common/theme'; +import { ColorScheme, isDark, isHighContrast } from 'vs/platform/theme/common/theme'; import { getIconsStyleSheet, UnthemedProductIconTheme } from 'vs/platform/theme/browser/iconsStyleSheet'; -const VS_THEME_NAME = 'vs'; -const VS_DARK_THEME_NAME = 'vs-dark'; -const HC_BLACK_THEME_NAME = 'hc-black'; -const HC_LIGHT_THEME_NAME = 'hc-light'; +export const VS_LIGHT_THEME_NAME = 'vs'; +export const VS_DARK_THEME_NAME = 'vs-dark'; +export const HC_BLACK_THEME_NAME = 'hc-black'; +export const HC_LIGHT_THEME_NAME = 'hc-light'; const colorRegistry = Registry.as(Extensions.ColorContribution); const themingRegistry = Registry.as(ThemingExtensions.ThemingContribution); @@ -118,7 +118,7 @@ class StandaloneTheme implements IStandaloneTheme { public get type(): ColorScheme { switch (this.base) { - case VS_THEME_NAME: return ColorScheme.LIGHT; + case VS_LIGHT_THEME_NAME: return ColorScheme.LIGHT; case HC_BLACK_THEME_NAME: return ColorScheme.HIGH_CONTRAST_DARK; case HC_LIGHT_THEME_NAME: return ColorScheme.HIGH_CONTRAST_LIGHT; default: return ColorScheme.DARK; @@ -182,7 +182,7 @@ class StandaloneTheme implements IStandaloneTheme { function isBuiltinTheme(themeName: string): themeName is BuiltinTheme { return ( - themeName === VS_THEME_NAME + themeName === VS_LIGHT_THEME_NAME || themeName === VS_DARK_THEME_NAME || themeName === HC_BLACK_THEME_NAME || themeName === HC_LIGHT_THEME_NAME @@ -191,7 +191,7 @@ function isBuiltinTheme(themeName: string): themeName is BuiltinTheme { function getBuiltinRules(builtinTheme: BuiltinTheme): IStandaloneThemeData { switch (builtinTheme) { - case VS_THEME_NAME: + case VS_LIGHT_THEME_NAME: return vs; case VS_DARK_THEME_NAME: return vs_dark; @@ -229,7 +229,6 @@ export class StandaloneThemeService extends Disposable implements IStandaloneThe private _globalStyleElement: HTMLStyleElement | null; private _styleElements: HTMLStyleElement[]; private _colorMapOverride: Color[] | null; - private _desiredTheme!: IStandaloneTheme; private _theme!: IStandaloneTheme; private _builtInProductIconTheme = new UnthemedProductIconTheme(); @@ -240,7 +239,7 @@ export class StandaloneThemeService extends Disposable implements IStandaloneThe this._autoDetectHighContrast = true; this._knownThemes = new Map(); - this._knownThemes.set(VS_THEME_NAME, newBuiltInTheme(VS_THEME_NAME)); + this._knownThemes.set(VS_LIGHT_THEME_NAME, newBuiltInTheme(VS_LIGHT_THEME_NAME)); this._knownThemes.set(VS_DARK_THEME_NAME, newBuiltInTheme(VS_DARK_THEME_NAME)); this._knownThemes.set(HC_BLACK_THEME_NAME, newBuiltInTheme(HC_BLACK_THEME_NAME)); this._knownThemes.set(HC_LIGHT_THEME_NAME, newBuiltInTheme(HC_LIGHT_THEME_NAME)); @@ -253,7 +252,8 @@ export class StandaloneThemeService extends Disposable implements IStandaloneThe this._globalStyleElement = null; this._styleElements = []; this._colorMapOverride = null; - this.setTheme(VS_THEME_NAME); + this.setTheme(VS_LIGHT_THEME_NAME); + this._onOSSchemeChanged(); iconsStyleSheet.onDidChange(() => { this._codiconCSS = iconsStyleSheet.getCSS(); @@ -261,7 +261,7 @@ export class StandaloneThemeService extends Disposable implements IStandaloneThe }); addMatchMediaChangeListener('(forced-colors: active)', () => { - this._updateActualTheme(); + this._onOSSchemeChanged(); }); } @@ -331,41 +331,43 @@ export class StandaloneThemeService extends Disposable implements IStandaloneThe } public setTheme(themeName: string): void { - let theme: StandaloneTheme; + let theme: StandaloneTheme | undefined; if (this._knownThemes.has(themeName)) { - theme = this._knownThemes.get(themeName)!; + theme = this._knownThemes.get(themeName); } else { - theme = this._knownThemes.get(VS_THEME_NAME)!; + theme = this._knownThemes.get(VS_LIGHT_THEME_NAME); } - this._desiredTheme = theme; - this._updateActualTheme(); + this._updateActualTheme(theme); } - private getHighContrastTheme() { - if (isDark(this._desiredTheme.type)) { - return HC_BLACK_THEME_NAME; - } else { - return HC_LIGHT_THEME_NAME; - } - } - - private _updateActualTheme(): void { - const theme = ( - this._autoDetectHighContrast && window.matchMedia(`(forced-colors: active)`).matches - ? this._knownThemes.get(this.getHighContrastTheme())! - : this._desiredTheme - ); - if (this._theme === theme) { + private _updateActualTheme(desiredTheme: IStandaloneTheme | undefined): void { + if (!desiredTheme || this._theme === desiredTheme) { // Nothing to do return; } - this._theme = theme; + this._theme = desiredTheme; this._updateThemeOrColorMap(); } + private _onOSSchemeChanged() { + if (this._autoDetectHighContrast) { + const wantsHighContrast = window.matchMedia(`(forced-colors: active)`).matches; + if (wantsHighContrast !== isHighContrast(this._theme.type)) { + // switch to high contrast or non-high contrast but stick to dark or light + let newThemeName; + if (isDark(this._theme.type)) { + newThemeName = wantsHighContrast ? HC_BLACK_THEME_NAME : VS_DARK_THEME_NAME; + } else { + newThemeName = wantsHighContrast ? HC_LIGHT_THEME_NAME : VS_LIGHT_THEME_NAME; + } + this._updateActualTheme(this._knownThemes.get(newThemeName)); + } + } + } + public setAutoDetectHighContrast(autoDetectHighContrast: boolean): void { this._autoDetectHighContrast = autoDetectHighContrast; - this._updateActualTheme(); + this._onOSSchemeChanged(); } private _updateThemeOrColorMap(): void { diff --git a/src/vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast.ts b/src/vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast.ts index d10e1ccafb9..4fe1552ebd5 100644 --- a/src/vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast.ts +++ b/src/vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast.ts @@ -7,7 +7,8 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, ServicesAccessor, registerEditorAction } from 'vs/editor/browser/editorExtensions'; import { IStandaloneThemeService } from 'vs/editor/standalone/common/standaloneTheme'; import { ToggleHighContrastNLS } from 'vs/editor/common/standaloneStrings'; -import { isHighContrast } from 'vs/platform/theme/common/theme'; +import { isDark, isHighContrast } from 'vs/platform/theme/common/theme'; +import { HC_BLACK_THEME_NAME, HC_LIGHT_THEME_NAME, VS_DARK_THEME_NAME, VS_LIGHT_THEME_NAME } from 'vs/editor/standalone/browser/standaloneThemeService'; class ToggleHighContrast extends EditorAction { @@ -25,13 +26,14 @@ class ToggleHighContrast extends EditorAction { public run(accessor: ServicesAccessor, editor: ICodeEditor): void { const standaloneThemeService = accessor.get(IStandaloneThemeService); - if (isHighContrast(standaloneThemeService.getColorTheme().type)) { + const currentTheme = standaloneThemeService.getColorTheme(); + if (isHighContrast(currentTheme.type)) { // We must toggle back to the integrator's theme - standaloneThemeService.setTheme(this._originalThemeName || 'vs'); + standaloneThemeService.setTheme(this._originalThemeName || (isDark(currentTheme.type) ? VS_DARK_THEME_NAME : VS_LIGHT_THEME_NAME)); this._originalThemeName = null; } else { - this._originalThemeName = standaloneThemeService.getColorTheme().themeName; - standaloneThemeService.setTheme('hc-black'); + standaloneThemeService.setTheme(isDark(currentTheme.type) ? HC_BLACK_THEME_NAME : HC_LIGHT_THEME_NAME); + this._originalThemeName = currentTheme.themeName; } } } -- cgit v1.2.3 From 0b9de0b7405b0f02a36389f3c23201ab79e02abd Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 7 Jul 2022 15:26:25 +0200 Subject: fix compile issue --- src/vs/editor/test/browser/editorTestServices.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/editor/test/browser/editorTestServices.ts b/src/vs/editor/test/browser/editorTestServices.ts index 6eb1863c26e..3aad1a86547 100644 --- a/src/vs/editor/test/browser/editorTestServices.ts +++ b/src/vs/editor/test/browser/editorTestServices.ts @@ -22,7 +22,7 @@ export class TestCodeEditorService extends AbstractCodeEditorService { return null; } public lastInput?: IResourceEditorInput; - openCodeEditor(input: IResourceEditorInput, source: ICodeEditor | null, sideBySide?: boolean): Promise { + override openCodeEditor(input: IResourceEditorInput, source: ICodeEditor | null, sideBySide?: boolean): Promise { this.lastInput = input; return Promise.resolve(null); } -- cgit v1.2.3 From 30c88106734239138e6b875552ce4a90fef79386 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 7 Jul 2022 06:32:54 -0700 Subject: Use BASH_COMMAND instead of history for empty command detection Part of #143766 --- .../terminal/browser/media/shellIntegration-bash.sh | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh index b0c525a298d..c57e7eb13db 100755 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh @@ -39,13 +39,6 @@ if [[ "$PROMPT_COMMAND" =~ .*(' '.*\;)|(\;.*' ').* ]]; then builtin return fi -# Disable shell integration if HISTCONTROL is set to erase duplicate entries as the exit code -# reporting relies on the duplicates existing -if [[ "$HISTCONTROL" =~ .*erasedups.* ]]; then - builtin unset VSCODE_SHELL_INTEGRATION - builtin return -fi - if [ -z "$VSCODE_SHELL_INTEGRATION" ]; then builtin return fi @@ -56,7 +49,7 @@ __vsc_original_PS2="$PS2" __vsc_custom_PS1="" __vsc_custom_PS2="" __vsc_in_command_execution="1" -__vsc_last_history_id=$(history 1 | awk '{print $1;}') +__vsc_current_command="" __vsc_prompt_start() { builtin printf "\033]633;A\007" @@ -72,6 +65,13 @@ __vsc_update_cwd() { __vsc_command_output_start() { builtin printf "\033]633;C\007" + if [[ ! "$BASH_COMMAND" =~ ^__vsc_prompt* ]]; then + __vsc_current_command=$BASH_COMMAND + builtin printf "\033]633;E;$BASH_COMMAND\007" + else + __vsc_current_command="" + builtin printf "\033]633;E\007" + fi } __vsc_continuation_start() { @@ -83,12 +83,10 @@ __vsc_continuation_end() { } __vsc_command_complete() { - local __vsc_history_id=$(builtin history 1 | awk '{print $1;}') - if [[ "$__vsc_history_id" == "$__vsc_last_history_id" ]]; then + if [ "$__vsc_current_command" = "" ]; then builtin printf "\033]633;D\007" else builtin printf "\033]633;D;%s\007" "$__vsc_status" - __vsc_last_history_id=$__vsc_history_id fi __vsc_update_cwd } -- cgit v1.2.3 From f52f2ed7b5f50dac9aa71e899d12078c31020ca0 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 7 Jul 2022 06:55:01 -0700 Subject: Use preexec $1 not history and send command Fixes #143766 --- .../terminal/browser/media/shellIntegration-bash.sh | 14 +++++++------- .../terminal/browser/media/shellIntegration-rc.zsh | 20 +++++++------------- 2 files changed, 14 insertions(+), 20 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh index c57e7eb13db..88498fbfb9a 100755 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh @@ -65,13 +65,7 @@ __vsc_update_cwd() { __vsc_command_output_start() { builtin printf "\033]633;C\007" - if [[ ! "$BASH_COMMAND" =~ ^__vsc_prompt* ]]; then - __vsc_current_command=$BASH_COMMAND - builtin printf "\033]633;E;$BASH_COMMAND\007" - else - __vsc_current_command="" - builtin printf "\033]633;E\007" - fi + builtin printf "\033]633;E;$__vsc_current_command\007" } __vsc_continuation_start() { @@ -111,6 +105,7 @@ __vsc_update_prompt() { __vsc_precmd() { __vsc_command_complete "$__vsc_status" + __vsc_current_command="" __vsc_update_prompt } @@ -118,6 +113,11 @@ __vsc_preexec() { if [ "$__vsc_in_command_execution" = "0" ]; then __vsc_initialized=1 __vsc_in_command_execution="1" + if [[ ! "$BASH_COMMAND" =~ ^__vsc_prompt* ]]; then + __vsc_current_command=$BASH_COMMAND + else + __vsc_current_command="" + fi __vsc_command_output_start fi } diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh index 595c1261e18..7db2583a817 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh @@ -33,9 +33,8 @@ if [ -z "$VSCODE_SHELL_INTEGRATION" ]; then builtin return fi -__vsc_initialized="0" __vsc_in_command_execution="1" -__vsc_last_history_id=0 +__vsc_current_command="" __vsc_prompt_start() { builtin printf "\033]633;A\007" @@ -51,6 +50,7 @@ __vsc_update_cwd() { __vsc_command_output_start() { builtin printf "\033]633;C\007" + builtin printf "\033]633;E;$__vsc_current_command\007" } __vsc_continuation_start() { @@ -70,17 +70,10 @@ __vsc_right_prompt_end() { } __vsc_command_complete() { - builtin local __vsc_history_id=$(builtin history | tail -n1 | awk '{print $1;}') - # Don't write the command complete sequence for the first prompt without an associated command - if [[ "$__vsc_initialized" == "1" ]]; then - if [[ "$__vsc_history_id" == "$__vsc_last_history_id" ]]; then - builtin printf "\033]633;D\007" - else - builtin printf "\033]633;D;%s\007" "$__vsc_status" - __vsc_last_history_id=$__vsc_history_id - fi - else + if [[ "$__vsc_current_command" == "" ]]; then builtin printf "\033]633;D\007" + else + builtin printf "\033]633;D;%s\007" "$__vsc_status" fi __vsc_update_cwd } @@ -112,6 +105,7 @@ __vsc_precmd() { fi __vsc_command_complete "$__vsc_status" + __vsc_current_command="" # in command execution if [ -n "$__vsc_in_command_execution" ]; then @@ -125,8 +119,8 @@ __vsc_preexec() { if [ -n "$RPROMPT" ]; then RPROMPT="$__vsc_prior_rprompt" fi - __vsc_initialized="1" __vsc_in_command_execution="1" + __vsc_current_command=$1 __vsc_command_output_start } add-zsh-hook precmd __vsc_precmd -- cgit v1.2.3 From 4dc272701b0a6e5cf59cfc38d1e08f8862604b05 Mon Sep 17 00:00:00 2001 From: Jean Pierre Date: Thu, 7 Jul 2022 10:15:07 -0500 Subject: Only update storage `IS_NEW_KEY` once (#154313) * Fixes #153913 * spelling error Co-authored-by: Benjamin Pasero --- .../workbench/services/storage/browser/storageService.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/services/storage/browser/storageService.ts b/src/vs/workbench/services/storage/browser/storageService.ts index a939ea7e567..e267855723c 100644 --- a/src/vs/workbench/services/storage/browser/storageService.ts +++ b/src/vs/workbench/services/storage/browser/storageService.ts @@ -23,7 +23,7 @@ export class BrowserStorageService extends AbstractStorageService { private applicationStorage: IStorage | undefined; private applicationStorageDatabase: IIndexedDBStorageDatabase | undefined; - private readonly applicationStoragePromise = new DeferredPromise<{ indededDb: IIndexedDBStorageDatabase; storage: IStorage }>(); + private readonly applicationStoragePromise = new DeferredPromise<{ indexedDb: IIndexedDBStorageDatabase; storage: IStorage }>(); private profileStorage: IStorage | undefined; private profileStorageDatabase: IIndexedDBStorageDatabase | undefined; @@ -92,7 +92,7 @@ export class BrowserStorageService extends AbstractStorageService { this.updateIsNew(this.applicationStorage); - this.applicationStoragePromise.complete({ indededDb: applicationStorageIndexedDB, storage: this.applicationStorage }); + this.applicationStoragePromise.complete({ indexedDb: applicationStorageIndexedDB, storage: this.applicationStorage }); } private async createProfileStorage(profile: IUserDataProfile): Promise { @@ -110,22 +110,24 @@ export class BrowserStorageService extends AbstractStorageService { // avoid creating the storage library a second time on // the same DB. - const { indededDb: applicationStorageIndexedDB, storage: applicationStorage } = await this.applicationStoragePromise.p; + const { indexedDb: applicationStorageIndexedDB, storage: applicationStorage } = await this.applicationStoragePromise.p; this.profileStorageDatabase = applicationStorageIndexedDB; this.profileStorage = applicationStorage; + + this.profileStorageDisposables.add(this.profileStorage.onDidChangeStorage(key => this.emitDidChangeValue(StorageScope.PROFILE, key))); } else { const profileStorageIndexedDB = await IndexedDBStorageDatabase.create({ id: this.getId(StorageScope.PROFILE), broadcastChanges: true }, this.logService); this.profileStorageDatabase = this.profileStorageDisposables.add(profileStorageIndexedDB); this.profileStorage = this.profileStorageDisposables.add(new Storage(this.profileStorageDatabase)); - } - this.profileStorageDisposables.add(this.profileStorage.onDidChangeStorage(key => this.emitDidChangeValue(StorageScope.PROFILE, key))); + this.profileStorageDisposables.add(this.profileStorage.onDidChangeStorage(key => this.emitDidChangeValue(StorageScope.PROFILE, key))); - await this.profileStorage.init(); + await this.profileStorage.init(); - this.updateIsNew(this.profileStorage); + this.updateIsNew(this.profileStorage); + } } private async createWorkspaceStorage(): Promise { -- cgit v1.2.3 From 1b8ac1d09d6eea72e9305ba977d6449106251349 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 7 Jul 2022 17:40:22 +0200 Subject: Fix 2 clicks to show collapsed comments (#154365) Fixes #153924 --- src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts | 1 + src/vs/workbench/contrib/comments/browser/commentsView.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts b/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts index 335976fbac8..41ed64d6d55 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts @@ -382,6 +382,7 @@ export class CommentController implements IEditorContribution { this._commentingRangeDecorator.update(this.editor, []); this._commentThreadRangeDecorator.update(this.editor, []); dispose(this._commentWidgets); + this._commentWidgets = []; } })); diff --git a/src/vs/workbench/contrib/comments/browser/commentsView.ts b/src/vs/workbench/contrib/comments/browser/commentsView.ts index d6883919fa6..4c38db0a895 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsView.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsView.ts @@ -234,7 +234,7 @@ export class CommentsPanel extends ViewPane { const commentToReveal = element instanceof ResourceWithCommentThreads ? element.commentThreads[0].comment.uniqueIdInThread : element.comment.uniqueIdInThread; if (threadToReveal && isCodeEditor(editor)) { const controller = CommentController.get(editor); - controller?.revealCommentThread(threadToReveal, commentToReveal, false); + controller?.revealCommentThread(threadToReveal, commentToReveal, true); } return true; -- cgit v1.2.3 From 7f8fdb3b32eaa3cd769b80b0937900636b45e448 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 7 Jul 2022 18:49:41 +0200 Subject: adopt extension installation in profiles in web --- .../common/abstractExtensionManagementService.ts | 109 +++------------------ .../node/extensionManagementService.ts | 92 +++++++++++++++-- .../common/webExtensionManagementService.ts | 12 +-- 3 files changed, 102 insertions(+), 111 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts index 66e250a2df1..0a06843fb5d 100644 --- a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts +++ b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts @@ -18,13 +18,10 @@ import { ServerInstallOptions, ServerInstallVSIXOptions, ServerUninstallOptions, Metadata, ServerInstallExtensionEvent, ServerInstallExtensionResult, ServerUninstallExtensionEvent, ServerDidUninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions, ExtensionKey, getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, getMaliciousExtensionsSet } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; import { ExtensionType, IExtensionManifest, TargetPlatform } from 'vs/platform/extensions/common/extensions'; import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; export interface IInstallExtensionTask { readonly identifier: IExtensionIdentifier; @@ -66,10 +63,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl private readonly participants: IExtensionManagementParticipant[] = []; constructor( - @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, - @IUriIdentityService private readonly uriIdenityService: IUriIdentityService, @IExtensionGalleryService protected readonly galleryService: IExtensionGalleryService, - @IExtensionsProfileScannerService protected readonly extensionsProfileScannerService: IExtensionsProfileScannerService, @ITelemetryService protected readonly telemetryService: ITelemetryService, @ILogService protected readonly logService: ILogService, @IProductService protected readonly productService: IProductService @@ -120,7 +114,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl throw new Error(nls.localize('Not a Marketplace extension', "Only Marketplace Extensions can be reinstalled")); } - await this.createDefaultUninstallExtensionTask(extension, { remove: true, versionOnly: true }).run(); + await this.createUninstallExtensionTask(extension, { remove: true, versionOnly: true }).run(); await this.installFromGallery(galleryExtension); } @@ -140,13 +134,15 @@ export abstract class AbstractExtensionManagementService extends Disposable impl } protected async installExtension(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): Promise { + + const getInstallExtensionTaskKey = (extension: IGalleryExtension) => `${ExtensionKey.create(extension).toString()}${options.profileLocation ? `-${options.profileLocation.toString()}` : ''}`; + // only cache gallery extensions tasks if (!URI.isUri(extension)) { - const installExtensionTask = this.installingExtensions.get(ExtensionKey.create(extension).toString()); + const installExtensionTask = this.installingExtensions.get(getInstallExtensionTaskKey(extension)); if (installExtensionTask) { this.logService.info('Extensions is already requested to install', extension.identifier.id); - const waitUntilTaskIsFinishedTask = this.createWaitUntilInstallExtensionTaskIsFinishedTask(installExtensionTask, options); - const { local } = await waitUntilTaskIsFinishedTask.waitUntilTaskIsFinished(); + const { local } = await installExtensionTask.waitUntilTaskIsFinished(); return local; } options = { ...options, installOnlyNewlyAddedFromExtensionPack: true /* always true for gallery extensions */ }; @@ -156,7 +152,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl const installResults: (ServerInstallExtensionResult & { local: ILocalExtension })[] = []; const installExtensionTask = this.createInstallExtensionTask(manifest, extension, options); if (!URI.isUri(extension)) { - this.installingExtensions.set(ExtensionKey.create(extension).toString(), installExtensionTask); + this.installingExtensions.set(getInstallExtensionTaskKey(extension), installExtensionTask); } this._onInstallExtension.fire({ identifier: installExtensionTask.identifier, source: extension, profileLocation: options.profileLocation }); this.logService.info('Installing extension:', installExtensionTask.identifier.id); @@ -171,7 +167,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl const allDepsAndPackExtensionsToInstall = await this.getAllDepsAndPackExtensionsToInstall(installExtensionTask.identifier, manifest, !!options.installOnlyNewlyAddedFromExtensionPack, !!options.installPreReleaseVersion, options.profileLocation); for (const { gallery, manifest } of allDepsAndPackExtensionsToInstall) { installExtensionHasDependents = installExtensionHasDependents || !!manifest.extensionDependencies?.some(id => areSameExtensions({ id }, installExtensionTask.identifier)); - const key = ExtensionKey.create(gallery).toString(); + const key = getInstallExtensionTaskKey(gallery); if (this.installingExtensions.has(key)) { this.logService.info('Extension is already requested to install', gallery.identifier.id); } else { @@ -260,7 +256,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl // rollback installed extensions if (installResults.length) { try { - const result = await Promise.allSettled(installResults.map(({ local }) => this.createUninstallExtensionTask(local, { versionOnly: true }, options.profileLocation).run())); + const result = await Promise.allSettled(installResults.map(({ local }) => this.createUninstallExtensionTask(local, { versionOnly: true, profileLocation: options.profileLocation }).run())); for (let index = 0; index < result.length; index++) { const r = result[index]; const { identifier } = installResults[index]; @@ -282,7 +278,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl /* Remove the gallery tasks from the cache */ for (const { task } of allInstallExtensionTasks) { if (!URI.isUri(task.source)) { - const key = ExtensionKey.create(task.source).toString(); + const key = getInstallExtensionTaskKey(task.source); if (!this.installingExtensions.delete(key)) { this.logService.warn('Installation task is not found in the cache', key); } @@ -434,7 +430,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl } const createUninstallExtensionTask = (extension: ILocalExtension, uninstallOptions: ServerUninstallOptions): IUninstallExtensionTask => { - const uninstallExtensionTask = this.createUninstallExtensionTask(extension, uninstallOptions, options.profileLocation); + const uninstallExtensionTask = this.createUninstallExtensionTask(extension, uninstallOptions); this.uninstallingExtensions.set(getUninstallExtensionTaskKey(uninstallExtensionTask.extension.identifier), uninstallExtensionTask); if (options.profileLocation) { this.logService.info('Uninstalling extension from the profile:', `${extension.identifier.id}@${extension.manifest.version}`, options.profileLocation.toString()); @@ -603,25 +599,6 @@ export abstract class AbstractExtensionManagementService extends Disposable impl } } - private createInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask { - const installTask = this.createDefaultInstallExtensionTask(manifest, extension, options); - return options.profileLocation && this.userDataProfilesService.defaultProfile.extensionsResource ? new InstallExtensionInProfileTask(installTask, options.profileLocation, this.userDataProfilesService.defaultProfile.extensionsResource, this.extensionsProfileScannerService) : installTask; - } - - private createWaitUntilInstallExtensionTaskIsFinishedTask(installTask: IInstallExtensionTask, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask { - if (!options.profileLocation || !this.userDataProfilesService.defaultProfile.extensionsResource) { - return installTask; - } - if (installTask instanceof InstallExtensionInProfileTask && this.uriIdenityService.extUri.isEqual(installTask.profileLocation, options.profileLocation)) { - return installTask; - } - return new InstallExtensionInProfileTask(installTask, options.profileLocation, this.userDataProfilesService.defaultProfile.extensionsResource, this.extensionsProfileScannerService); - } - - private createUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions, profile?: URI): IUninstallExtensionTask { - return profile && this.userDataProfilesService.defaultProfile.extensionsResource ? new UninstallExtensionFromProfileTask(extension, profile, this.userDataProfilesService, this.extensionsProfileScannerService) : this.createDefaultUninstallExtensionTask(extension, options); - } - abstract getTargetPlatform(): Promise; abstract zip(extension: ILocalExtension): Promise; abstract unzip(zipLocation: URI): Promise; @@ -633,8 +610,8 @@ export abstract class AbstractExtensionManagementService extends Disposable impl abstract updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): Promise; abstract updateExtensionScope(local: ILocalExtension, isMachineScoped: boolean): Promise; - protected abstract createDefaultInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask; - protected abstract createDefaultUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions): IUninstallExtensionTask; + protected abstract createInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask; + protected abstract createUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions): IUninstallExtensionTask; } export function joinErrors(errorOrErrors: (Error | string) | (Array)): Error { @@ -731,63 +708,3 @@ export abstract class AbstractExtensionTask { protected abstract doRun(token: CancellationToken): Promise; } - -class InstallExtensionInProfileTask implements IInstallExtensionTask { - - readonly identifier = this.task.identifier; - readonly source = this.task.source; - readonly operation = this.task.operation; - - private readonly promise: Promise<{ local: ILocalExtension; metadata: Metadata }>; - - constructor( - private readonly task: IInstallExtensionTask, - readonly profileLocation: URI, - private readonly defaultProfileLocation: URI, - private readonly extensionsProfileScannerService: IExtensionsProfileScannerService, - ) { - this.promise = this.waitAndAddExtensionToProfile(); - } - - private async waitAndAddExtensionToProfile(): Promise<{ local: ILocalExtension; metadata: Metadata }> { - const result = await this.task.waitUntilTaskIsFinished(); - const profileLocation = result.local.isApplicationScoped ? this.defaultProfileLocation : this.profileLocation; - await this.extensionsProfileScannerService.addExtensionsToProfile([[result.local, result.metadata]], profileLocation); - return result; - } - - async run(): Promise<{ local: ILocalExtension; metadata: Metadata }> { - await this.task.run(); - return this.promise; - } - - waitUntilTaskIsFinished(): Promise<{ local: ILocalExtension; metadata: Metadata }> { - return this.promise; - } - - cancel(): void { - return this.task.cancel(); - } -} - -class UninstallExtensionFromProfileTask extends AbstractExtensionTask implements IUninstallExtensionTask { - - constructor( - readonly extension: ILocalExtension, - private readonly profileLocation: URI, - private readonly userDataProfilesService: IUserDataProfilesService, - private readonly extensionsProfileScannerService: IExtensionsProfileScannerService, - ) { - super(); - } - - protected async doRun(token: CancellationToken): Promise { - const promises: Promise[] = []; - promises.push(this.extensionsProfileScannerService.removeExtensionFromProfile(this.extension.identifier, this.profileLocation)); - if (this.extension.isApplicationScoped && this.userDataProfilesService.defaultProfile.extensionsResource) { - promises.push(this.extensionsProfileScannerService.removeExtensionFromProfile(this.extension.identifier, this.userDataProfilesService.defaultProfile.extensionsResource)); - } - await Promise.all(promises); - } - -} diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 56ea181d99e..5171a2fa2e4 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -65,21 +65,23 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi private readonly manifestCache: ExtensionsManifestCache; private readonly extensionsDownloader: ExtensionsDownloader; + private readonly installGalleryExtensionsTasks = new Map(); + constructor( @IExtensionGalleryService galleryService: IExtensionGalleryService, @ITelemetryService telemetryService: ITelemetryService, @ILogService logService: ILogService, @INativeEnvironmentService private readonly environmentService: INativeEnvironmentService, @IExtensionsScannerService private readonly extensionsScannerService: IExtensionsScannerService, - @IExtensionsProfileScannerService extensionsProfileScannerService: IExtensionsProfileScannerService, + @IExtensionsProfileScannerService private readonly extensionsProfileScannerService: IExtensionsProfileScannerService, @IDownloadService private downloadService: IDownloadService, @IInstantiationService instantiationService: IInstantiationService, @IFileService private readonly fileService: IFileService, @IProductService productService: IProductService, @IUriIdentityService uriIdentityService: IUriIdentityService, - @IUserDataProfilesService userDataProfilesService: IUserDataProfilesService, + @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, ) { - super(userDataProfilesService, uriIdentityService, galleryService, extensionsProfileScannerService, telemetryService, logService, productService); + super(galleryService, telemetryService, logService, productService); const extensionLifecycle = this._register(instantiationService.createInstance(ExtensionsLifecycle)); this.extensionsScanner = this._register(instantiationService.createInstance(ExtensionsScanner, extension => extensionLifecycle.postUninstall(extension))); this.manifestCache = this._register(new ExtensionsManifestCache(environmentService, this)); @@ -176,11 +178,28 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi return downloadedLocation; } - protected createDefaultInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask { - return URI.isUri(extension) ? new InstallVSIXTask(manifest, extension, options, this.galleryService, this.extensionsScanner, this.logService) : new InstallGalleryExtensionTask(manifest, extension, options, this.extensionsDownloader, this.extensionsScanner, this.logService); + protected createInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask { + let installExtensionTask: IInstallExtensionTask | undefined; + if (URI.isUri(extension)) { + installExtensionTask = new InstallVSIXTask(manifest, extension, options, this.galleryService, this.extensionsScanner, this.logService); + } else { + const key = ExtensionKey.create(extension).toString(); + installExtensionTask = this.installGalleryExtensionsTasks.get(key); + if (!installExtensionTask) { + this.installGalleryExtensionsTasks.set(key, installExtensionTask = new InstallGalleryExtensionTask(manifest, extension, options, this.extensionsDownloader, this.extensionsScanner, this.logService)); + installExtensionTask.waitUntilTaskIsFinished().then(() => this.installGalleryExtensionsTasks.delete(key)); + } + } + if (options.profileLocation && this.userDataProfilesService.defaultProfile.extensionsResource) { + return new InstallExtensionInProfileTask(installExtensionTask, options.profileLocation, this.userDataProfilesService.defaultProfile.extensionsResource, this.extensionsProfileScannerService); + } + return installExtensionTask; } - protected createDefaultUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions): IUninstallExtensionTask { + protected createUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions): IUninstallExtensionTask { + if (options.profileLocation && this.userDataProfilesService.defaultProfile.extensionsResource) { + return new UninstallExtensionFromProfileTask(extension, options.profileLocation, this.userDataProfilesService, this.extensionsProfileScannerService); + } return new UninstallExtensionTask(extension, options, this.extensionsScanner); } @@ -706,6 +725,44 @@ class InstallVSIXTask extends InstallExtensionTask { } } +class InstallExtensionInProfileTask implements IInstallExtensionTask { + + readonly identifier = this.task.identifier; + readonly source = this.task.source; + readonly operation = this.task.operation; + + private readonly promise: Promise<{ local: ILocalExtension; metadata: Metadata }>; + + constructor( + private readonly task: IInstallExtensionTask, + readonly profileLocation: URI, + private readonly defaultProfileLocation: URI, + private readonly extensionsProfileScannerService: IExtensionsProfileScannerService, + ) { + this.promise = this.waitAndAddExtensionToProfile(); + } + + private async waitAndAddExtensionToProfile(): Promise<{ local: ILocalExtension; metadata: Metadata }> { + const result = await this.task.waitUntilTaskIsFinished(); + const profileLocation = result.local.isApplicationScoped ? this.defaultProfileLocation : this.profileLocation; + await this.extensionsProfileScannerService.addExtensionsToProfile([[result.local, result.metadata]], profileLocation); + return result; + } + + async run(): Promise<{ local: ILocalExtension; metadata: Metadata }> { + await this.task.run(); + return this.promise; + } + + waitUntilTaskIsFinished(): Promise<{ local: ILocalExtension; metadata: Metadata }> { + return this.promise; + } + + cancel(): void { + return this.task.cancel(); + } +} + class UninstallExtensionTask extends AbstractExtensionTask implements IUninstallExtensionTask { constructor( @@ -745,3 +802,26 @@ class UninstallExtensionTask extends AbstractExtensionTask implements IUni } } + +class UninstallExtensionFromProfileTask extends AbstractExtensionTask implements IUninstallExtensionTask { + + constructor( + readonly extension: ILocalExtension, + private readonly profileLocation: URI, + private readonly userDataProfilesService: IUserDataProfilesService, + private readonly extensionsProfileScannerService: IExtensionsProfileScannerService, + ) { + super(); + } + + protected async doRun(token: CancellationToken): Promise { + const promises: Promise[] = []; + promises.push(this.extensionsProfileScannerService.removeExtensionFromProfile(this.extension.identifier, this.profileLocation)); + if (this.extension.isApplicationScoped && this.userDataProfilesService.defaultProfile.extensionsResource) { + promises.push(this.extensionsProfileScannerService.removeExtensionFromProfile(this.extension.identifier, this.userDataProfilesService.defaultProfile.extensionsResource)); + } + await Promise.all(promises); + } + +} + diff --git a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts index 3b7e5f36a19..ae7bdcbc28c 100644 --- a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts @@ -16,9 +16,6 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService'; import { IProductService } from 'vs/platform/product/common/productService'; import { isBoolean, isUndefined } from 'vs/base/common/types'; -import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; -import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; -import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; export class WebExtensionManagementService extends AbstractExtensionManagementService implements IProfileAwareExtensionManagementService { @@ -32,12 +29,9 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe @ILogService logService: ILogService, @IWebExtensionsScannerService private readonly webExtensionsScannerService: IWebExtensionsScannerService, @IExtensionManifestPropertiesService private readonly extensionManifestPropertiesService: IExtensionManifestPropertiesService, - @IExtensionsProfileScannerService extensionsProfileScannerService: IExtensionsProfileScannerService, @IProductService productService: IProductService, - @IUserDataProfilesService userDataProfilesService: IUserDataProfilesService, - @IUriIdentityService uriIdentityService: IUriIdentityService, ) { - super(userDataProfilesService, uriIdentityService, extensionGalleryService, extensionsProfileScannerService, telemetryService, logService, productService); + super(extensionGalleryService, telemetryService, logService, productService); } async getTargetPlatform(): Promise { @@ -100,11 +94,11 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe return local; } - protected createDefaultInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: InstallOptions): IInstallExtensionTask { + protected createInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: InstallOptions): IInstallExtensionTask { return new InstallExtensionTask(manifest, extension, options, this.webExtensionsScannerService); } - protected createDefaultUninstallExtensionTask(extension: ILocalExtension, options: UninstallOptions): IUninstallExtensionTask { + protected createUninstallExtensionTask(extension: ILocalExtension, options: UninstallOptions): IUninstallExtensionTask { return new UninstallExtensionTask(extension, options, this.webExtensionsScannerService); } -- cgit v1.2.3 From 61a9d7236ea9952b3ec5e3386ec92ca66ed2ab3b Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 7 Jul 2022 19:16:16 +0200 Subject: trigger extensions change when profile changed --- .../browser/webExtensionsScannerService.ts | 43 ++++++++++++++++------ .../common/extensionManagement.ts | 2 + .../common/webExtensionManagementService.ts | 3 +- 3 files changed, 35 insertions(+), 13 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts b/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts index 10d163b4571..588ca24cc10 100644 --- a/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts +++ b/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IBuiltinExtensionsScannerService, ExtensionType, IExtensionIdentifier, IExtension, IExtensionManifest, TargetPlatform } from 'vs/platform/extensions/common/extensions'; +import { IBuiltinExtensionsScannerService, ExtensionType, IExtensionIdentifier, IExtension, IExtensionManifest, TargetPlatform, ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'; import { IScannedExtension, IWebExtensionsScannerService, ScanOptions } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { isWeb, Language } from 'vs/base/common/platform'; @@ -33,15 +33,17 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { basename } from 'vs/base/common/path'; import { IExtensionStorageService } from 'vs/platform/extensionManagement/common/extensionStorage'; -import { isNonEmptyArray } from 'vs/base/common/arrays'; +import { delta, isNonEmptyArray } from 'vs/base/common/arrays'; import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { IProductService } from 'vs/platform/product/common/productService'; import { validateExtensionManifest } from 'vs/platform/extensions/common/extensionValidator'; import Severity from 'vs/base/common/severity'; import { IStringDictionary } from 'vs/base/common/collections'; -import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { DidChangeUserDataProfileEvent, IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { Emitter } from 'vs/base/common/event'; +import { compare } from 'vs/base/common/strings'; type GalleryExtensionInfo = { readonly id: string; preRelease?: boolean; migrateStorageFrom?: string }; type ExtensionInfo = { readonly id: string; preRelease: boolean }; @@ -87,6 +89,9 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten private readonly customBuiltinExtensionsCacheResource: URI | undefined = undefined; private readonly resourcesAccessQueueMap = new ResourceMap>(); + private readonly _onDidChangeProfileExtensions = this._register(new Emitter<{ readonly added: IScannedExtension[]; readonly removed: IScannedExtension[] }>()); + readonly onDidChangeProfileExtensions = this._onDidChangeProfileExtensions.event; + constructor( @IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService, @IBuiltinExtensionsScannerService private readonly builtinExtensionsScannerService: IBuiltinExtensionsScannerService, @@ -110,6 +115,7 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten // Eventually update caches lifecycleService.when(LifecyclePhase.Eventually).then(() => this.updateCaches()); + this._register(userDataProfileService.onDidChangeCurrentProfile(e => e.join(this.whenProfileChanged(e)))); } } @@ -381,7 +387,7 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten } // User Installed extensions - const installedExtensions = await this.scanInstalledExtensions(scanOptions); + const installedExtensions = await this.scanInstalledExtensions(this.userDataProfileService.currentProfile, scanOptions); for (const extension of installedExtensions) { extensions.set(extension.identifier.id.toLowerCase(), extension); } @@ -480,30 +486,30 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten const installedExtensions = await this.readInstalledExtensions(profile); // Also add to installed extensions if it is installed to update its version if (installedExtensions.some(e => areSameExtensions(e.identifier, webExtension.identifier))) { - await this.addToInstalledExtensions(webExtension, profile); + await this.addToInstalledExtensions([webExtension], profile); } return extension; } // Add to installed extensions - await this.addToInstalledExtensions(webExtension, profile); + await this.addToInstalledExtensions([webExtension], profile); return extension; } - private async addToInstalledExtensions(webExtension: IWebExtension, profile: IUserDataProfile): Promise { + private async addToInstalledExtensions(webExtensions: IWebExtension[], profile: IUserDataProfile): Promise { await this.writeInstalledExtensions(profile, installedExtensions => { // Remove the existing extension to avoid duplicates - installedExtensions = installedExtensions.filter(e => !areSameExtensions(e.identifier, webExtension.identifier)); - installedExtensions.push(webExtension); + installedExtensions = installedExtensions.filter(installedExtension => webExtensions.some(extension => !areSameExtensions(installedExtension.identifier, extension.identifier))); + installedExtensions.push(...webExtensions); return installedExtensions; }); } - private async scanInstalledExtensions(scanOptions?: ScanOptions): Promise { - let installedExtensions = await this.readInstalledExtensions(this.userDataProfileService.currentProfile); + private async scanInstalledExtensions(profile: IUserDataProfile, scanOptions?: ScanOptions): Promise { + let installedExtensions = await this.readInstalledExtensions(profile); // If current profile is not a default profile, then add the application extensions to the list - if (!this.userDataProfileService.currentProfile.isDefault) { + if (!profile.isDefault) { // Remove application extensions from the non default profile installedExtensions = installedExtensions.filter(i => !i.metadata?.isApplicationScoped); // Add application extensions from the default profile to the list @@ -830,6 +836,19 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten })); } + private async whenProfileChanged(e: DidChangeUserDataProfileEvent): Promise { + if (e.preserveData) { + const extensions = (await this.readInstalledExtensions(e.previous)).filter(e => !e.metadata?.isApplicationScoped); /* remove application scoped extensions */ + await this.addToInstalledExtensions(extensions, e.profile); + } else { + const oldExtensions = await this.scanInstalledExtensions(e.previous); + const newExtensions = await this.scanInstalledExtensions(e.profile); + const { added, removed } = delta(oldExtensions, newExtensions, (a, b) => compare(`${ExtensionIdentifier.toKey(a.identifier.id)}@${a.manifest.version}`, `${ExtensionIdentifier.toKey(b.identifier.id)}@${b.manifest.version}`)); + if (added.length || removed.length) { + this._onDidChangeProfileExtensions.fire({ added, removed }); + } + } + } } registerSingleton(IWebExtensionsScannerService, WebExtensionsScannerService); diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts index 1d9dd9e5183..668f143421e 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts @@ -157,6 +157,8 @@ export const IWebExtensionsScannerService = createDecorator; + scanSystemExtensions(): Promise; scanUserExtensions(options?: ScanOptions): Promise; scanExtensionsUnderDevelopment(): Promise; diff --git a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts index ae7bdcbc28c..720b7ebed1d 100644 --- a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts @@ -21,7 +21,7 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe declare readonly _serviceBrand: undefined; - readonly onDidChangeProfileExtensions = Event.None; + readonly onDidChangeProfileExtensions: Event<{ readonly added: ILocalExtension[]; readonly removed: ILocalExtension[] }>; constructor( @IExtensionGalleryService extensionGalleryService: IExtensionGalleryService, @@ -32,6 +32,7 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe @IProductService productService: IProductService, ) { super(extensionGalleryService, telemetryService, logService, productService); + this.onDidChangeProfileExtensions = Event.map(this.webExtensionsScannerService.onDidChangeProfileExtensions, e => ({ added: e.added.map(a => toLocalExtension(a)), removed: e.removed.map(a => toLocalExtension(a)) })); } async getTargetPlatform(): Promise { -- cgit v1.2.3 From 755d39f1e079d103fc7f6dce43e9bc00071f24fe Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Thu, 7 Jul 2022 13:58:38 -0400 Subject: add allow automatic tasks setting (#154171) --- .../contrib/tasks/browser/abstractTaskService.ts | 2 +- .../contrib/tasks/browser/runAutomaticTasks.ts | 48 ++++++++++++---------- .../contrib/tasks/browser/task.contribution.ts | 12 ++++++ src/vs/workbench/contrib/tasks/common/tasks.ts | 3 +- 4 files changed, 41 insertions(+), 24 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 644103faf6a..1a3261a3335 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -1084,7 +1084,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }).then((value) => { if (runSource === TaskRunSource.User) { this.getWorkspaceTasks().then(workspaceTasks => { - RunAutomaticTasks.promptForPermission(this, this._storageService, this._notificationService, this._workspaceTrustManagementService, this._openerService, workspaceTasks); + RunAutomaticTasks.promptForPermission(this, this._storageService, this._notificationService, this._workspaceTrustManagementService, this._openerService, this._configurationService, workspaceTasks); }); } return value; diff --git a/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts b/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts index 55d63c00125..aa0d0441b79 100644 --- a/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts +++ b/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts @@ -15,18 +15,19 @@ import { IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/commo import { Action2 } from 'vs/platform/actions/common/actions'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust'; -import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; +import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { URI } from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; import { ILogService } from 'vs/platform/log/common/log'; -const ARE_AUTOMATIC_TASKS_ALLOWED_IN_WORKSPACE = 'tasks.run.allowAutomatic'; +const HAS_PROMPTED_FOR_AUTOMATIC_TASKS = 'task.hasPromptedForAutomaticTasks'; +const ALLOW_AUTOMATIC_TASKS = 'task.allowAutomaticTasks'; export class RunAutomaticTasks extends Disposable implements IWorkbenchContribution { constructor( @ITaskService private readonly _taskService: ITaskService, - @IStorageService private readonly _storageService: IStorageService, + @IConfigurationService private readonly _configurationService: IConfigurationService, @IWorkspaceTrustManagementService private readonly _workspaceTrustManagementService: IWorkspaceTrustManagementService, @ILogService private readonly _logService: ILogService) { super(); @@ -42,7 +43,7 @@ export class RunAutomaticTasks extends Disposable implements IWorkbenchContribut } this._logService.trace('RunAutomaticTasks: Checking if automatic tasks should run.'); - const isFolderAutomaticAllowed = this._storageService.getBoolean(ARE_AUTOMATIC_TASKS_ALLOWED_IN_WORKSPACE, StorageScope.WORKSPACE, undefined); + const isFolderAutomaticAllowed = this._configurationService.getValue(ALLOW_AUTOMATIC_TASKS) !== 'off'; await this._workspaceTrustManagementService.workspaceTrustInitialized; const isWorkspaceTrusted = this._workspaceTrustManagementService.isWorkspaceTrusted(); // Only run if allowed. Prompting for permission occurs when a user first tries to run a task. @@ -128,30 +129,33 @@ export class RunAutomaticTasks extends Disposable implements IWorkbenchContribut } public static async promptForPermission(taskService: ITaskService, storageService: IStorageService, notificationService: INotificationService, workspaceTrustManagementService: IWorkspaceTrustManagementService, - openerService: IOpenerService, workspaceTaskResult: Map) { + openerService: IOpenerService, configurationService: IConfigurationService, workspaceTaskResult: Map) { const isWorkspaceTrusted = workspaceTrustManagementService.isWorkspaceTrusted; if (!isWorkspaceTrusted) { return; } - - const isFolderAutomaticAllowed = storageService.getBoolean(ARE_AUTOMATIC_TASKS_ALLOWED_IN_WORKSPACE, StorageScope.WORKSPACE, undefined); - if (isFolderAutomaticAllowed !== undefined) { + if (configurationService.getValue(ALLOW_AUTOMATIC_TASKS) === 'off') { return; } + const hasShownPromptForAutomaticTasks = storageService.getBoolean(HAS_PROMPTED_FOR_AUTOMATIC_TASKS, StorageScope.WORKSPACE, undefined); const { tasks, taskNames, locations } = RunAutomaticTasks._findAutoTasks(taskService, workspaceTaskResult); if (taskNames.length > 0) { - // We have automatic tasks, prompt to allow. - this._showPrompt(notificationService, storageService, taskService, openerService, taskNames, locations).then(allow => { - if (allow) { - RunAutomaticTasks._runTasks(taskService, tasks); - } - }); + if (configurationService.getValue(ALLOW_AUTOMATIC_TASKS) === 'on') { + RunAutomaticTasks._runTasks(taskService, tasks); + } else if (!hasShownPromptForAutomaticTasks) { + // We have automatic tasks, prompt to allow. + this._showPrompt(notificationService, storageService, openerService, configurationService, taskNames, locations).then(allow => { + if (allow) { + RunAutomaticTasks._runTasks(taskService, tasks); + } + }); + } } } - private static _showPrompt(notificationService: INotificationService, storageService: IStorageService, taskService: ITaskService, - openerService: IOpenerService, taskNames: Array, locations: Map): Promise { + private static _showPrompt(notificationService: INotificationService, storageService: IStorageService, + openerService: IOpenerService, configurationService: IConfigurationService, taskNames: Array, locations: Map): Promise { return new Promise(resolve => { notificationService.prompt(Severity.Info, nls.localize('tasks.run.allowAutomatic', "This workspace has tasks ({0}) defined ({1}) that run automatically when you open this workspace. Do you allow automatic tasks to run when you open this workspace?", @@ -162,14 +166,15 @@ export class RunAutomaticTasks extends Disposable implements IWorkbenchContribut label: nls.localize('allow', "Allow and run"), run: () => { resolve(true); - storageService.store(ARE_AUTOMATIC_TASKS_ALLOWED_IN_WORKSPACE, true, StorageScope.WORKSPACE, StorageTarget.MACHINE); + configurationService.updateValue(ALLOW_AUTOMATIC_TASKS, true, ConfigurationTarget.WORKSPACE); } }, { label: nls.localize('disallow', "Disallow"), run: () => { resolve(false); - storageService.store(ARE_AUTOMATIC_TASKS_ALLOWED_IN_WORKSPACE, false, StorageScope.WORKSPACE, StorageTarget.MACHINE); + configurationService.updateValue(ALLOW_AUTOMATIC_TASKS, false, ConfigurationTarget.WORKSPACE); + } }, { @@ -182,9 +187,9 @@ export class RunAutomaticTasks extends Disposable implements IWorkbenchContribut } }] ); + storageService.store(HAS_PROMPTED_FOR_AUTOMATIC_TASKS, true, StorageScope.WORKSPACE, StorageTarget.MACHINE); }); } - } export class ManageAutomaticTaskRunning extends Action2 { @@ -202,14 +207,13 @@ export class ManageAutomaticTaskRunning extends Action2 { public async run(accessor: ServicesAccessor): Promise { const quickInputService = accessor.get(IQuickInputService); - const storageService = accessor.get(IStorageService); + const configurationService = accessor.get(IConfigurationService); const allowItem: IQuickPickItem = { label: nls.localize('workbench.action.tasks.allowAutomaticTasks', "Allow Automatic Tasks in Folder") }; const disallowItem: IQuickPickItem = { label: nls.localize('workbench.action.tasks.disallowAutomaticTasks', "Disallow Automatic Tasks in Folder") }; const value = await quickInputService.pick([allowItem, disallowItem], { canPickMany: false }); if (!value) { return; } - - storageService.store(ARE_AUTOMATIC_TASKS_ALLOWED_IN_WORKSPACE, value === allowItem, StorageScope.WORKSPACE, StorageTarget.MACHINE); + configurationService.updateValue(ALLOW_AUTOMATIC_TASKS, value === allowItem, ConfigurationTarget.WORKSPACE); } } diff --git a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts index 911ee6ec393..00c85294b7b 100644 --- a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts +++ b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts @@ -496,6 +496,18 @@ configurationRegistry.registerConfiguration({ description: nls.localize('task.quickOpen.showAll', "Causes the Tasks: Run Task command to use the slower \"show all\" behavior instead of the faster two level picker where tasks are grouped by provider."), default: false }, + [TaskSettingId.AllowAutomaticTasks]: { + type: 'string', + enum: ['on', 'auto', 'off'], + enumDescriptions: [ + nls.localize('ttask.allowAutomaticTasks.on', "Always"), + nls.localize('task.allowAutomaticTasks.auto', "Prompt for permission for each folder"), + nls.localize('task.allowAutomaticTasks.off', "Never"), + ], + description: nls.localize('task.allowAutomaticTasks', "Enable automatic tasks in the folder."), + default: 'auto', + restricted: true + }, [TaskSettingId.ShowDecorations]: { type: 'boolean', description: nls.localize('task.showDecorations', "Shows decorations at points of interest in the terminal buffer such as the first problem found via a watch task. Note that this will only take effect for future tasks."), diff --git a/src/vs/workbench/contrib/tasks/common/tasks.ts b/src/vs/workbench/contrib/tasks/common/tasks.ts index 2300c659cb0..5877beb6437 100644 --- a/src/vs/workbench/contrib/tasks/common/tasks.ts +++ b/src/vs/workbench/contrib/tasks/common/tasks.ts @@ -1199,7 +1199,8 @@ export const enum TaskSettingId { QuickOpenHistory = 'task.quickOpen.history', QuickOpenDetail = 'task.quickOpen.detail', QuickOpenSkip = 'task.quickOpen.skip', - QuickOpenShowAll = 'task.quickOpen.showAll' + QuickOpenShowAll = 'task.quickOpen.showAll', + AllowAutomaticTasks = 'task.allowAutomaticTasks' } export const enum TasksSchemaProperties { -- cgit v1.2.3 From 1cc52ae41064ad363a214e7e0c67921b64e9c8df Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Thu, 7 Jul 2022 11:01:16 -0700 Subject: Fix broken Not Synced indicator (#154381) Fixes #154379 --- .../preferences/browser/settingsEditorSettingIndicators.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts index a10179c4ac7..bbb035a2c99 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts @@ -51,12 +51,6 @@ export class SettingsTreeIndicatorsLabel implements IDisposable { this.indicatorsContainerElement = DOM.append(container, $('.misc-label')); this.indicatorsContainerElement.style.display = 'inline'; - const scopeOverridesIndicator = this.createScopeOverridesIndicator(); - this.scopeOverridesElement = scopeOverridesIndicator.element; - this.scopeOverridesLabel = scopeOverridesIndicator.label; - this.syncIgnoredElement = this.createSyncIgnoredElement(); - this.defaultOverrideIndicatorElement = this.createDefaultOverrideIndicator(); - this.hoverDelegate = { showHover: (options: IHoverDelegateOptions, focus?: boolean) => { return hoverService.showHover(options, focus); @@ -65,6 +59,12 @@ export class SettingsTreeIndicatorsLabel implements IDisposable { delay: configurationService.getValue('workbench.hover.delay'), placement: 'element' }; + + const scopeOverridesIndicator = this.createScopeOverridesIndicator(); + this.scopeOverridesElement = scopeOverridesIndicator.element; + this.scopeOverridesLabel = scopeOverridesIndicator.label; + this.syncIgnoredElement = this.createSyncIgnoredElement(); + this.defaultOverrideIndicatorElement = this.createDefaultOverrideIndicator(); } private createScopeOverridesIndicator(): { element: HTMLElement; label: SimpleIconLabel } { -- cgit v1.2.3 From 368400c1907a62a920b7a94ee10ff74a083f34c5 Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Thu, 7 Jul 2022 11:01:33 -0700 Subject: Check save settings before debug restart (#154206) * Fix bug: Files automatically saved when restarting debugger, even though it is set not to Fixes #149885 --- src/vs/workbench/api/browser/mainThreadDebugService.ts | 7 ++++--- src/vs/workbench/contrib/debug/browser/debugCommands.ts | 2 +- src/vs/workbench/contrib/debug/browser/debugService.ts | 10 ++++++++-- src/vs/workbench/contrib/debug/browser/debugSession.ts | 4 ++++ src/vs/workbench/contrib/debug/common/debug.ts | 4 +++- src/vs/workbench/contrib/debug/test/browser/mockDebug.ts | 4 ++++ 6 files changed, 24 insertions(+), 7 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/api/browser/mainThreadDebugService.ts b/src/vs/workbench/api/browser/mainThreadDebugService.ts index c0ec9d1b550..1b0e0389246 100644 --- a/src/vs/workbench/api/browser/mainThreadDebugService.ts +++ b/src/vs/workbench/api/browser/mainThreadDebugService.ts @@ -223,6 +223,7 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb const folderUri = folder ? uri.revive(folder) : undefined; const launch = this.debugService.getConfigurationManager().getLaunch(folderUri); const parentSession = this.getSession(options.parentSessionID); + const saveBeforeStart = typeof options.suppressSaveBeforeStart === 'boolean' ? !options.suppressSaveBeforeStart : undefined; const debugOptions: IDebugSessionOptions = { noDebug: options.noDebug, parentSession, @@ -230,11 +231,11 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb repl: options.repl, compact: options.compact, debugUI: options.debugUI, - compoundRoot: parentSession?.compoundRoot + compoundRoot: parentSession?.compoundRoot, + saveBeforeStart: saveBeforeStart }; try { - const saveBeforeStart = typeof options.suppressSaveBeforeStart === 'boolean' ? !options.suppressSaveBeforeStart : undefined; - return this.debugService.startDebugging(launch, nameOrConfig, debugOptions, saveBeforeStart); + return this.debugService.startDebugging(launch, nameOrConfig, debugOptions); } catch (err) { throw new ErrorNoTelemetry(err && err.message ? err.message : 'cannot start debugging'); } diff --git a/src/vs/workbench/contrib/debug/browser/debugCommands.ts b/src/vs/workbench/contrib/debug/browser/debugCommands.ts index 25da3464ac6..596bbd9c32d 100644 --- a/src/vs/workbench/contrib/debug/browser/debugCommands.ts +++ b/src/vs/workbench/contrib/debug/browser/debugCommands.ts @@ -723,7 +723,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ const { launch, name, getConfig } = debugService.getConfigurationManager().selectedConfiguration; const config = await getConfig(); const configOrName = config ? Object.assign(deepClone(config), debugStartOptions?.config) : name; - await debugService.startDebugging(launch, configOrName, { noDebug: debugStartOptions?.noDebug, startedByUser: true }, false); + await debugService.startDebugging(launch, configOrName, { noDebug: debugStartOptions?.noDebug, startedByUser: true, saveBeforeStart: false }); } }); diff --git a/src/vs/workbench/contrib/debug/browser/debugService.ts b/src/vs/workbench/contrib/debug/browser/debugService.ts index b308716a8bb..2474922a5ad 100644 --- a/src/vs/workbench/contrib/debug/browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugService.ts @@ -312,7 +312,10 @@ export class DebugService implements IDebugService { * main entry point * properly manages compounds, checks for errors and handles the initializing state. */ - async startDebugging(launch: ILaunch | undefined, configOrName?: IConfig | string, options?: IDebugSessionOptions, saveBeforeStart = !options?.parentSession): Promise { + async startDebugging(launch: ILaunch | undefined, configOrName?: IConfig | string, options?: IDebugSessionOptions): Promise { + + const saveBeforeStart = options?.saveBeforeStart ?? !options?.parentSession; + const message = options && options.noDebug ? nls.localize('runTrust', "Running executes build tasks and program code from your workspace.") : nls.localize('debugTrust', "Debugging executes build tasks and program code from your workspace."); const trust = await this.workspaceTrustRequestService.requestWorkspaceTrust({ message }); if (!trust) { @@ -701,7 +704,10 @@ export class DebugService implements IDebugService { } async restartSession(session: IDebugSession, restartData?: any): Promise { - await this.editorService.saveAll(); + if (session.saveBeforeStart) { + await saveAllBeforeDebugStart(this.configurationService, this.editorService); + } + const isAutoRestart = !!restartData; const runTasks: () => Promise = async () => { diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index de26f713ef0..29a568d478b 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -164,6 +164,10 @@ export class DebugSession implements IDebugSession { return !!this._options.compact; } + get saveBeforeStart(): boolean { + return this._options.saveBeforeStart ?? !this._options?.parentSession; + } + get compoundRoot(): DebugCompoundRoot | undefined { return this._options.compoundRoot; } diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index a8397f69aef..21dc92d475c 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -206,6 +206,7 @@ export interface IDebugSessionOptions { simple?: boolean; }; startedByUser?: boolean; + saveBeforeStart?: boolean; } export interface IDataBreakpointInfoResponse { @@ -296,6 +297,7 @@ export interface IDebugSession extends ITreeElement { readonly subId: string | undefined; readonly compact: boolean; readonly compoundRoot: DebugCompoundRoot | undefined; + readonly saveBeforeStart: boolean; readonly name: string; readonly isSimpleUI: boolean; readonly autoExpandLazyVariables: boolean; @@ -1088,7 +1090,7 @@ export interface IDebugService { * Returns true if the start debugging was successful. For compound launches, all configurations have to start successfully for it to return success. * On errors the startDebugging will throw an error, however some error and cancelations are handled and in that case will simply return false. */ - startDebugging(launch: ILaunch | undefined, configOrName?: IConfig | string, options?: IDebugSessionOptions, saveBeforeStart?: boolean): Promise; + startDebugging(launch: ILaunch | undefined, configOrName?: IConfig | string, options?: IDebugSessionOptions): Promise; /** * Restarts a session or creates a new one if there is no active session. diff --git a/src/vs/workbench/contrib/debug/test/browser/mockDebug.ts b/src/vs/workbench/contrib/debug/test/browser/mockDebug.ts index 1bebaa31adb..1596e346e31 100644 --- a/src/vs/workbench/contrib/debug/test/browser/mockDebug.ts +++ b/src/vs/workbench/contrib/debug/test/browser/mockDebug.ts @@ -190,6 +190,10 @@ export class MockSession implements IDebugSession { return undefined; } + get saveBeforeStart(): boolean { + return true; + } + get isSimpleUI(): boolean { return false; } -- cgit v1.2.3 From d5379b5e34e4bb0f5ddb33688da91f787ebc159f Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Thu, 7 Jul 2022 11:14:03 -0700 Subject: Fix more settings description setting links (#154383) Ref #154317 --- src/vs/editor/common/config/editorOptions.ts | 12 ++++++------ src/vs/workbench/browser/workbench.contribution.ts | 10 +++++----- src/vs/workbench/contrib/files/browser/files.contribution.ts | 6 +++--- .../contrib/notebook/browser/notebook.contribution.ts | 6 +++--- .../workbench/contrib/remote/common/remote.contribution.ts | 4 ++-- .../workbench/contrib/search/browser/search.contribution.ts | 2 +- 6 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src/vs') diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 2158431d8b1..7292a7e132b 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -2562,12 +2562,12 @@ class EditorInlayHints extends BaseEditorOption(ConfigurationExtensions.Con }, 'workbench.editor.restoreViewState': { 'type': 'boolean', - 'markdownDescription': localize('restoreViewState', "Restores the last editor view state (e.g. scroll position) when re-opening editors after they have been closed. Editor view state is stored per editor group and discarded when a group closes. Use the `#workbench.editor.sharedViewState#` setting to use the last known view state across all editor groups in case no previous view state was found for a editor group."), + 'markdownDescription': localize('restoreViewState', "Restores the last editor view state (e.g. scroll position) when re-opening editors after they have been closed. Editor view state is stored per editor group and discarded when a group closes. Use the {0} setting to use the last known view state across all editor groups in case no previous view state was found for a editor group.", '`#workbench.editor.sharedViewState#`'), 'default': true, 'scope': ConfigurationScope.LANGUAGE_OVERRIDABLE }, @@ -278,7 +278,7 @@ const registry = Registry.as(ConfigurationExtensions.Con 'type': 'number', 'default': 10, 'exclusiveMinimum': 0, - 'markdownDescription': localize('limitEditorsMaximum', "Controls the maximum number of opened editors. Use the `#workbench.editor.limit.perEditorGroup#` setting to control this limit per editor group or across all groups.") + 'markdownDescription': localize('limitEditorsMaximum', "Controls the maximum number of opened editors. Use the {0} setting to control this limit per editor group or across all groups.", '`#workbench.editor.limit.perEditorGroup#`') }, 'workbench.editor.limit.excludeDirty': { 'type': 'boolean', @@ -540,12 +540,12 @@ const registry = Registry.as(ConfigurationExtensions.Con 'window.titleSeparator': { 'type': 'string', 'default': isMacintosh ? ' \u2014 ' : ' - ', - 'markdownDescription': localize("window.titleSeparator", "Separator used by `window.title`.") + 'markdownDescription': localize("window.titleSeparator", "Separator used by {0}.", '`#window.title#`') }, 'window.commandCenter': { type: 'boolean', default: false, - markdownDescription: localize('window.commandCenter', "Show command launcher together with the window title. This setting only has an effect when `#window.titleBarStyle#` is set to `custom`.") + markdownDescription: localize('window.commandCenter', "Show command launcher together with the window title. This setting only has an effect when {0} is set to {1}.", '`#window.titleBarStyle#`', '`custom`') }, 'window.menuBarVisibility': { 'type': 'string', @@ -557,7 +557,7 @@ const registry = Registry.as(ConfigurationExtensions.Con localize('window.menuBarVisibility.toggle.mac', "Menu is hidden but can be displayed at the top of the window by executing the `Focus Application Menu` command.") : localize('window.menuBarVisibility.toggle', "Menu is hidden but can be displayed at the top of the window via the Alt key."), localize('window.menuBarVisibility.hidden', "Menu is always hidden."), - localize('window.menuBarVisibility.compact', "Menu is displayed as a compact button in the side bar. This value is ignored when `#window.titleBarStyle#` is `native`.") + localize('window.menuBarVisibility.compact', "Menu is displayed as a compact button in the side bar. This value is ignored when {0} is {1}.", '`#window.titleBarStyle#`', '`native`') ], 'default': isWeb ? 'compact' : 'classic', 'scope': ConfigurationScope.APPLICATION, diff --git a/src/vs/workbench/contrib/files/browser/files.contribution.ts b/src/vs/workbench/contrib/files/browser/files.contribution.ts index 592d559451a..0db2db173e1 100644 --- a/src/vs/workbench/contrib/files/browser/files.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/files.contribution.ts @@ -185,7 +185,7 @@ configurationRegistry.registerConfiguration({ 'files.autoGuessEncoding': { 'type': 'boolean', 'default': false, - 'markdownDescription': nls.localize('autoGuessEncoding', "When enabled, the editor will attempt to guess the character set encoding when opening files. This setting can also be configured per language. Note, this setting is not respected by text search. Only `#files.encoding#` is respected."), + 'markdownDescription': nls.localize('autoGuessEncoding', "When enabled, the editor will attempt to guess the character set encoding when opening files. This setting can also be configured per language. Note, this setting is not respected by text search. Only {0} is respected.", '`#files.encoding#`'), 'scope': ConfigurationScope.LANGUAGE_OVERRIDABLE }, 'files.eol': { @@ -475,7 +475,7 @@ configurationRegistry.registerConfiguration({ }, 'explorer.excludeGitIgnore': { type: 'boolean', - markdownDescription: nls.localize('excludeGitignore', "Controls whether entries in .gitignore should be parsed and excluded from the explorer. Similar to `#files.exclude#`."), + markdownDescription: nls.localize('excludeGitignore', "Controls whether entries in .gitignore should be parsed and excluded from the explorer. Similar to {0}.", '`#files.exclude#`'), default: false, scope: ConfigurationScope.RESOURCE }, @@ -487,7 +487,7 @@ configurationRegistry.registerConfiguration({ }, 'explorer.fileNesting.expand': { 'type': 'boolean', - 'markdownDescription': nls.localize('fileNestingExpand', "Controls whether file nests are automatically expanded. `#explorer.fileNesting.enabled#` must be set for this to take effect."), + 'markdownDescription': nls.localize('fileNestingExpand', "Controls whether file nests are automatically expanded. {0} must be set for this to take effect.", '`#explorer.fileNesting.enabled#`'), 'default': true, }, 'explorer.fileNesting.patterns': { diff --git a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts index 6111d9f1caa..33bf079467f 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -881,7 +881,7 @@ configurationRegistry.registerConfiguration({ tags: ['notebookLayout'] }, [NotebookSetting.markupFontSize]: { - markdownDescription: nls.localize('notebook.markup.fontSize', "Controls the font size in pixels of rendered markup in notebooks. When set to `0`, 120% of `#editor.fontSize#` is used."), + markdownDescription: nls.localize('notebook.markup.fontSize', "Controls the font size in pixels of rendered markup in notebooks. When set to {0}, 120% of {1} is used.", '`0`', '`#editor.fontSize#`'), type: 'number', default: 0, tags: ['notebookLayout'] @@ -900,13 +900,13 @@ configurationRegistry.registerConfiguration({ tags: ['notebookLayout'] }, [NotebookSetting.outputFontSize]: { - markdownDescription: nls.localize('notebook.outputFontSize', "Font size for the output text for notebook cells. When set to 0 `#editor.fontSize#` is used."), + markdownDescription: nls.localize('notebook.outputFontSize', "Font size for the output text for notebook cells. When set to {0}, {1} is used.", '`0`', '`#editor.fontSize#`'), type: 'number', default: 0, tags: ['notebookLayout'] }, [NotebookSetting.outputFontFamily]: { - markdownDescription: nls.localize('notebook.outputFontFamily', "The font family for the output text for notebook cells. When set to empty, the `#editor.fontFamily#` is used."), + markdownDescription: nls.localize('notebook.outputFontFamily', "The font family for the output text for notebook cells. When set to empty, the {0} is used.", '`#editor.fontFamily#`'), type: 'string', tags: ['notebookLayout'] }, diff --git a/src/vs/workbench/contrib/remote/common/remote.contribution.ts b/src/vs/workbench/contrib/remote/common/remote.contribution.ts index b6488780711..0b2e94b01bc 100644 --- a/src/vs/workbench/contrib/remote/common/remote.contribution.ts +++ b/src/vs/workbench/contrib/remote/common/remote.contribution.ts @@ -353,7 +353,7 @@ Registry.as(ConfigurationExtensions.Configuration) }, 'remote.autoForwardPortsSource': { type: 'string', - markdownDescription: localize('remote.autoForwardPortsSource', "Sets the source from which ports are automatically forwarded when `remote.autoForwardPorts` is true. On Windows and Mac remotes, the `process` option has no effect and `output` will be used. Requires a reload to take effect."), + markdownDescription: localize('remote.autoForwardPortsSource', "Sets the source from which ports are automatically forwarded when {0} is true. On Windows and Mac remotes, the `process` option has no effect and `output` will be used. Requires a reload to take effect.", '`#remote.autoForwardPorts#`'), enum: ['process', 'output'], enumDescriptions: [ localize('remote.autoForwardPortsSource.process', "Ports will be automatically forwarded when discovered by watching for processes that are started and include a port."), @@ -463,7 +463,7 @@ Registry.as(ConfigurationExtensions.Configuration) } }, defaultSnippets: [{ body: { onAutoForward: 'ignore' } }], - markdownDescription: localize('remote.portsAttributes.defaults', "Set default properties that are applied to all ports that don't get properties from the setting `remote.portsAttributes`. For example:\n\n```\n{\n \"onAutoForward\": \"ignore\"\n}\n```"), + markdownDescription: localize('remote.portsAttributes.defaults', "Set default properties that are applied to all ports that don't get properties from the setting {0}. For example:\n\n```\n{\n \"onAutoForward\": \"ignore\"\n}\n```", '`#remote.portsAttributes#`'), additionalProperties: false }, 'remote.localPortHost': { diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index 08f7dc2cf25..54450eb71c4 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -996,7 +996,7 @@ configurationRegistry.registerConfiguration({ 'search.searchOnTypeDebouncePeriod': { type: 'number', default: 300, - markdownDescription: nls.localize('search.searchOnTypeDebouncePeriod', "When `#search.searchOnType#` is enabled, controls the timeout in milliseconds between a character being typed and the search starting. Has no effect when `search.searchOnType` is disabled.") + markdownDescription: nls.localize('search.searchOnTypeDebouncePeriod', "When {0} is enabled, controls the timeout in milliseconds between a character being typed and the search starting. Has no effect when {0} is disabled.", '`#search.searchOnType#`') }, 'search.searchEditor.doubleClickBehaviour': { type: 'string', -- cgit v1.2.3 From bc0bdc5d0969030f114d5931b18e134059da00c1 Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Thu, 7 Jul 2022 11:55:35 -0700 Subject: Fix hover underline issue on "Modified in" label (#154386) Fixes #154385 --- src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css | 2 +- .../contrib/preferences/browser/settingsEditorSettingIndicators.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css index d44eec7e5d5..11f242b2646 100644 --- a/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css @@ -351,7 +351,7 @@ font-style: italic; } -.settings-editor > .settings-body .settings-tree-container .setting-item-contents .setting-item-title > .misc-label .setting-item-overrides:hover, +.settings-editor > .settings-body .settings-tree-container .setting-item-contents .setting-item-title > .misc-label .setting-item-overrides.with-custom-hover:hover, .settings-editor > .settings-body .settings-tree-container .setting-item-contents .setting-item-title > .misc-label .setting-item-ignored:hover, .settings-editor > .settings-body .settings-tree-container .setting-item-contents .setting-item-title > .misc-label .setting-item-default-overridden:hover { text-decoration: underline; diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts index bbb035a2c99..ae71ad571f6 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts @@ -139,6 +139,7 @@ export class SettingsTreeIndicatorsLabel implements IDisposable { // Render inline if we have the flag and there are scope overrides to render, // or if there is only one scope override to render and no language overrides. this.scopeOverridesElement.style.display = 'inline'; + this.scopeOverridesElement.classList.remove('with-custom-hover'); this.hover?.dispose(); // Just show all the text in the label. @@ -170,6 +171,7 @@ export class SettingsTreeIndicatorsLabel implements IDisposable { // show the text in a custom hover only if // the feature flag isn't on. this.scopeOverridesElement.style.display = 'inline'; + this.scopeOverridesElement.classList.add('with-custom-hover'); const scopeOverridesLabelText = element.isConfigured ? localize('alsoConfiguredElsewhere', "Also modified elsewhere") : localize('configuredElsewhere', "Modified elsewhere"); -- cgit v1.2.3 From 00eb9c4356c520299e7e2c95eb2089698b30b7fd Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Thu, 7 Jul 2022 13:38:32 -0700 Subject: Polish up restart dialogs and switch to using Language instead of language (#154382) --- .../contrib/localization/browser/localeService.ts | 51 ++++++++++++++++----- .../localization/browser/localizationsActions.ts | 39 +--------------- .../contrib/localization/common/locale.ts | 4 +- .../localization/electron-sandbox/localeService.ts | 52 ++++++++++++++++------ 4 files changed, 83 insertions(+), 63 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/localization/browser/localeService.ts b/src/vs/workbench/contrib/localization/browser/localeService.ts index c59d84821b2..4768a1752b4 100644 --- a/src/vs/workbench/contrib/localization/browser/localeService.ts +++ b/src/vs/workbench/contrib/localization/browser/localeService.ts @@ -3,31 +3,62 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { language } from 'vs/base/common/platform'; +import { localize } from 'vs/nls'; +import { Language } from 'vs/base/common/platform'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { ILanguagePackItem } from 'vs/platform/languagePacks/common/languagePacks'; import { ILocaleService } from 'vs/workbench/contrib/localization/common/locale'; +import { IHostService } from 'vs/workbench/services/host/browser/host'; +import { IProductService } from 'vs/platform/product/common/productService'; export class WebLocaleService implements ILocaleService { declare readonly _serviceBrand: undefined; - async setLocale(languagePackItem: ILanguagePackItem): Promise { + constructor( + @IDialogService private readonly dialogService: IDialogService, + @IHostService private readonly hostService: IHostService, + @IProductService private readonly productService: IProductService + ) { } + + async setLocale(languagePackItem: ILanguagePackItem): Promise { const locale = languagePackItem.id; - if (locale === language || (!locale && language === navigator.language)) { - return false; + if (locale === Language.value() || (!locale && Language.value() === navigator.language)) { + return; } if (locale) { window.localStorage.setItem('vscode.nls.locale', locale); } else { window.localStorage.removeItem('vscode.nls.locale'); } - return true; - } - async clearLocalePreference(): Promise { - if (language === navigator.language) { - return false; + const restartDialog = await this.dialogService.confirm({ + type: 'info', + message: localize('relaunchDisplayLanguageMessage', "{0} needs to reload to change the display language", this.productService.nameLong), + detail: localize('relaunchDisplayLanguageDetail', "Press the reload button to refresh the page and set the display language to {0}.", languagePackItem.label), + primaryButton: localize({ key: 'reload', comment: ['&& denotes a mnemonic character'] }, "&&Reload"), + }); + + if (restartDialog.confirmed) { + this.hostService.restart(); } + } + + async clearLocalePreference(): Promise { window.localStorage.removeItem('vscode.nls.locale'); - return true; + + if (Language.value() === navigator.language) { + return; + } + + const restartDialog = await this.dialogService.confirm({ + type: 'info', + message: localize('clearDisplayLanguageMessage', "{0} needs to reload to change the display language", this.productService.nameLong), + detail: localize('clearDisplayLanguageDetail', "Press the reload button to refresh the page and use your browser's language."), + primaryButton: localize({ key: 'reload', comment: ['&& denotes a mnemonic character'] }, "&&Reload"), + }); + + if (restartDialog.confirmed) { + this.hostService.restart(); + } } } diff --git a/src/vs/workbench/contrib/localization/browser/localizationsActions.ts b/src/vs/workbench/contrib/localization/browser/localizationsActions.ts index 5bdb7500724..2be6435942d 100644 --- a/src/vs/workbench/contrib/localization/browser/localizationsActions.ts +++ b/src/vs/workbench/contrib/localization/browser/localizationsActions.ts @@ -5,9 +5,6 @@ import { localize } from 'vs/nls'; import { IQuickInputService, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; -import { IHostService } from 'vs/workbench/services/host/browser/host'; -import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; -import { IProductService } from 'vs/platform/product/common/productService'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { Action2, MenuId } from 'vs/platform/actions/common/actions'; @@ -15,8 +12,6 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation import { ILanguagePackItem, ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks'; import { ILocaleService } from 'vs/workbench/contrib/localization/common/locale'; -const restart = localize('restart', "&&Restart"); - export class ConfigureDisplayLanguageAction extends Action2 { public static readonly ID = 'workbench.action.configureLocale'; public static readonly LABEL = localize('configureLocale', "Configure Display Language"); @@ -34,9 +29,6 @@ export class ConfigureDisplayLanguageAction extends Action2 { public async run(accessor: ServicesAccessor): Promise { const languagePackService: ILanguagePackService = accessor.get(ILanguagePackService); const quickInputService: IQuickInputService = accessor.get(IQuickInputService); - const hostService: IHostService = accessor.get(IHostService); - const dialogService: IDialogService = accessor.get(IDialogService); - const productService: IProductService = accessor.get(IProductService); const localeService: ILocaleService = accessor.get(ILocaleService); const installedLanguages = await languagePackService.getInstalledLanguages(); @@ -72,19 +64,7 @@ export class ConfigureDisplayLanguageAction extends Action2 { disposables.add(qp.onDidAccept(async () => { const selectedLanguage = qp.activeItems[0]; qp.hide(); - - if (await localeService.setLocale(selectedLanguage)) { - const restartDialog = await dialogService.confirm({ - type: 'info', - message: localize('relaunchDisplayLanguageMessage', "A restart is required for the change in display language to take effect."), - detail: localize('relaunchDisplayLanguageDetail', "Press the restart button to restart {0} and change the display language.", productService.nameLong), - primaryButton: restart - }); - - if (restartDialog.confirmed) { - hostService.restart(); - } - } + await localeService.setLocale(selectedLanguage); })); qp.show(); @@ -108,21 +88,6 @@ export class ClearDisplayLanguageAction extends Action2 { public async run(accessor: ServicesAccessor): Promise { const localeService: ILocaleService = accessor.get(ILocaleService); - const dialogService: IDialogService = accessor.get(IDialogService); - const productService: IProductService = accessor.get(IProductService); - const hostService: IHostService = accessor.get(IHostService); - - if (await localeService.clearLocalePreference()) { - const restartDialog = await dialogService.confirm({ - type: 'info', - message: localize('relaunchAfterClearDisplayLanguageMessage', "A restart is required for the change in display language to take effect."), - detail: localize('relaunchAfterClearDisplayLanguageDetail', "Press the restart button to restart {0} and change the display language.", productService.nameLong), - primaryButton: restart - }); - - if (restartDialog.confirmed) { - hostService.restart(); - } - } + await localeService.clearLocalePreference(); } } diff --git a/src/vs/workbench/contrib/localization/common/locale.ts b/src/vs/workbench/contrib/localization/common/locale.ts index f447d40bc41..f2e8417c443 100644 --- a/src/vs/workbench/contrib/localization/common/locale.ts +++ b/src/vs/workbench/contrib/localization/common/locale.ts @@ -10,6 +10,6 @@ export const ILocaleService = createDecorator('localizationServi export interface ILocaleService { readonly _serviceBrand: undefined; - setLocale(languagePackItem: ILanguagePackItem): Promise; - clearLocalePreference(): Promise; + setLocale(languagePackItem: ILanguagePackItem): Promise; + clearLocalePreference(): Promise; } diff --git a/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts b/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts index 00a6ec7036f..59b10dc5fcf 100644 --- a/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts +++ b/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { language } from 'vs/base/common/platform'; +import { Language } from 'vs/base/common/platform'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; @@ -19,6 +19,9 @@ import { toAction } from 'vs/base/common/actions'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { stripComments } from 'vs/base/common/stripComments'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IHostService } from 'vs/workbench/services/host/browser/host'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { IProductService } from 'vs/platform/product/common/productService'; export class NativeLocaleService implements ILocaleService { _serviceBrand: undefined; @@ -32,7 +35,10 @@ export class NativeLocaleService implements ILocaleService { @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, @IProgressService private readonly progressService: IProgressService, @ITextFileService private readonly textFileService: ITextFileService, - @IEditorService private readonly editorService: IEditorService + @IEditorService private readonly editorService: IEditorService, + @IDialogService private readonly dialogService: IDialogService, + @IHostService private readonly hostService: IHostService, + @IProductService private readonly productService: IProductService ) { } private async validateLocaleFile(): Promise { @@ -69,10 +75,10 @@ export class NativeLocaleService implements ILocaleService { return true; } - async setLocale(languagePackItem: ILanguagePackItem): Promise { + async setLocale(languagePackItem: ILanguagePackItem): Promise { const locale = languagePackItem.id; - if (locale === language || (!locale && language === 'en')) { - return false; + if (locale === Language.value() || (!locale && Language.isDefaultVariant())) { + return; } const installedLanguages = await this.languagePackService.getInstalledLanguages(); try { @@ -87,7 +93,7 @@ export class NativeLocaleService implements ILocaleService { // as of now, there are no 3rd party language packs available on the Marketplace. const viewlet = await this.paneCompositePartService.openPaneComposite(EXTENSIONS_VIEWLET_ID, ViewContainerLocation.Sidebar); (viewlet?.getViewPaneContainer() as IExtensionsViewPaneContainer).search(`@id:${languagePackItem.extensionId}`); - return false; + return; } await this.progressService.withProgress( @@ -102,22 +108,40 @@ export class NativeLocaleService implements ILocaleService { ); } - return await this.writeLocaleValue(locale); + if (await this.writeLocaleValue(locale)) { + await this.showRestartDialog(languagePackItem.label); + } } catch (err) { this.notificationService.error(err); - return false; } } - async clearLocalePreference(): Promise { - if (language === 'en') { - return false; - } + async clearLocalePreference(): Promise { try { - return await this.writeLocaleValue(undefined); + await this.writeLocaleValue(undefined); + if (!Language.isDefaultVariant()) { + await this.showRestartDialog('English'); + } } catch (err) { this.notificationService.error(err); - return false; + } + } + + private async showRestartDialog(languageName: string) { + const restartDialog = await this.dialogService.confirm({ + type: 'info', + message: localize('restartDisplayLanguageMessage', "{0} needs to restart to change the display language", this.productService.nameLong), + detail: localize( + 'restartDisplayLanguageDetail', + "Press the restart button to restart {0} and set the display language to {1}.", + this.productService.nameLong, + languageName + ), + primaryButton: localize({ key: 'restart', comment: ['&& denotes a mnemonic character'] }, "&&Restart"), + }); + + if (restartDialog.confirmed) { + this.hostService.restart(); } } } -- cgit v1.2.3 From 986d2e5df30f7fdce9c97baf404a349ea8f1059e Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 7 Jul 2022 17:31:14 -0700 Subject: Make contiguous search case insensitive --- src/vs/base/parts/quickinput/browser/quickInputList.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/base/parts/quickinput/browser/quickInputList.ts b/src/vs/base/parts/quickinput/browser/quickInputList.ts index 610176917d2..d2c58f8c6f7 100644 --- a/src/vs/base/parts/quickinput/browser/quickInputList.ts +++ b/src/vs/base/parts/quickinput/browser/quickInputList.ts @@ -763,7 +763,7 @@ export function matchesContiguousIconAware(query: string, target: IParsedLabelWi } function matchesContiguous(word: string, wordToMatchAgainst: string, enableSeparateSubstringMatching = false): IMatch[] | null { - const matchIndex = wordToMatchAgainst.indexOf(word); + const matchIndex = wordToMatchAgainst.toLowerCase().indexOf(word.toLowerCase()); if (matchIndex !== -1) { return [{ start: matchIndex, end: matchIndex + word.length }]; } -- cgit v1.2.3 From 8fdc7542e99265a07f3bc6e512d074c4c0fa8721 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 7 Jul 2022 17:39:03 -0700 Subject: Hide split/kill when tabs never hide Fixes #154411 --- src/vs/workbench/contrib/terminal/browser/terminalMenus.ts | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts b/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts index 5183542cb14..c6e6700e280 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts @@ -417,6 +417,7 @@ export function setupTerminalMenus(): void { order: 2, when: ContextKeyExpr.and( ContextKeyExpr.equals('view', TERMINAL_VIEW_ID), + ContextKeyExpr.notEquals(`config.${TerminalSettingId.TabsHideCondition}`, 'never'), ContextKeyExpr.or( ContextKeyExpr.not(`config.${TerminalSettingId.TabsEnabled}`), ContextKeyExpr.and( @@ -451,6 +452,7 @@ export function setupTerminalMenus(): void { order: 3, when: ContextKeyExpr.and( ContextKeyExpr.equals('view', TERMINAL_VIEW_ID), + ContextKeyExpr.notEquals(`config.${TerminalSettingId.TabsHideCondition}`, 'never'), ContextKeyExpr.or( ContextKeyExpr.not(`config.${TerminalSettingId.TabsEnabled}`), ContextKeyExpr.and( -- cgit v1.2.3 From 3104db414c8fedcf6e4493f14da7df0b7413853a Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Thu, 7 Jul 2022 21:19:59 -0700 Subject: slight copy change for display language dialog (#154402) slight copy change --- src/vs/workbench/contrib/localization/browser/localeService.ts | 4 ++-- .../workbench/contrib/localization/electron-sandbox/localeService.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/localization/browser/localeService.ts b/src/vs/workbench/contrib/localization/browser/localeService.ts index 4768a1752b4..dc8138589bf 100644 --- a/src/vs/workbench/contrib/localization/browser/localeService.ts +++ b/src/vs/workbench/contrib/localization/browser/localeService.ts @@ -33,7 +33,7 @@ export class WebLocaleService implements ILocaleService { const restartDialog = await this.dialogService.confirm({ type: 'info', - message: localize('relaunchDisplayLanguageMessage', "{0} needs to reload to change the display language", this.productService.nameLong), + message: localize('relaunchDisplayLanguageMessage', "To change the display language, {0} needs to reload", this.productService.nameLong), detail: localize('relaunchDisplayLanguageDetail', "Press the reload button to refresh the page and set the display language to {0}.", languagePackItem.label), primaryButton: localize({ key: 'reload', comment: ['&& denotes a mnemonic character'] }, "&&Reload"), }); @@ -52,7 +52,7 @@ export class WebLocaleService implements ILocaleService { const restartDialog = await this.dialogService.confirm({ type: 'info', - message: localize('clearDisplayLanguageMessage', "{0} needs to reload to change the display language", this.productService.nameLong), + message: localize('clearDisplayLanguageMessage', "To change the display language, {0} needs to reload", this.productService.nameLong), detail: localize('clearDisplayLanguageDetail', "Press the reload button to refresh the page and use your browser's language."), primaryButton: localize({ key: 'reload', comment: ['&& denotes a mnemonic character'] }, "&&Reload"), }); diff --git a/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts b/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts index 59b10dc5fcf..4c0da0bc253 100644 --- a/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts +++ b/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts @@ -130,7 +130,7 @@ export class NativeLocaleService implements ILocaleService { private async showRestartDialog(languageName: string) { const restartDialog = await this.dialogService.confirm({ type: 'info', - message: localize('restartDisplayLanguageMessage', "{0} needs to restart to change the display language", this.productService.nameLong), + message: localize('restartDisplayLanguageMessage', "To change the display language, {0} needs to restart", this.productService.nameLong), detail: localize( 'restartDisplayLanguageDetail', "Press the restart button to restart {0} and set the display language to {1}.", -- cgit v1.2.3 From ac70882663dd94883d9b86579b408df02aa3af24 Mon Sep 17 00:00:00 2001 From: jeanp413 Date: Thu, 7 Jul 2022 23:42:43 -0500 Subject: :lipstick: --- src/vs/workbench/api/browser/mainThreadTerminalService.ts | 2 +- src/vs/workbench/api/common/extHost.protocol.ts | 2 +- src/vs/workbench/api/common/extHostTerminalService.ts | 4 ++-- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 5 ++++- 4 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 6759edbcd59..23802f649dc 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -253,7 +253,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } private _onTerminalDisposed(terminalInstance: ITerminalInstance): void { - this._proxy.$acceptTerminalClosed(terminalInstance.instanceId, terminalInstance.exitCode, terminalInstance.exitReason); + this._proxy.$acceptTerminalClosed(terminalInstance.instanceId, terminalInstance.exitCode, terminalInstance.exitReason ?? TerminalExitReason.Unknown); } private _onTerminalOpened(terminalInstance: ITerminalInstance): void { diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 1f0b894d033..492e95a1b97 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1785,7 +1785,7 @@ export interface ITerminalDimensionsDto { } export interface ExtHostTerminalServiceShape { - $acceptTerminalClosed(id: number, exitCode: number | undefined, exitReason: TerminalExitReason | undefined): void; + $acceptTerminalClosed(id: number, exitCode: number | undefined, exitReason: TerminalExitReason): void; $acceptTerminalOpened(id: number, extHostTerminalId: string | undefined, name: string, shellLaunchConfig: IShellLaunchConfigDto): void; $acceptActiveTerminalChanged(id: number | null): void; $acceptTerminalProcessId(id: number, processId: number): void; diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index 05631f9eaef..69560c5729d 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -203,7 +203,7 @@ export class ExtHostTerminal { this._name = name; } - public setExitCode(code: number | undefined, reason: TerminalExitReason | undefined) { + public setExitCode(code: number | undefined, reason: TerminalExitReason) { this._exitStatus = Object.freeze({ code, reason }); } @@ -500,7 +500,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I } } - public async $acceptTerminalClosed(id: number, exitCode: number | undefined, exitReason: TerminalExitReason | undefined): Promise { + public async $acceptTerminalClosed(id: number, exitCode: number | undefined, exitReason: TerminalExitReason): Promise { const index = this._getTerminalObjectIndexById(this._terminals, id); if (index !== null) { const terminal = this._terminals.splice(index, 1)[0]; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index de3acb2313b..5a98560dae0 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1368,7 +1368,10 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._pressAnyKeyToCloseListener = undefined; } - this._exitReason = reason || TerminalExitReason.Unknown; + if (typeof this._exitReason === 'undefined') { + this._exitReason = reason ?? TerminalExitReason.Unknown; + } + this._processManager.dispose(); // Process manager dispose/shutdown doesn't fire process exit, trigger with undefined if it // hasn't happened yet -- cgit v1.2.3 From ef14540c30ce17786b3902d7c3a82add0c20d033 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 8 Jul 2022 08:15:44 +0200 Subject: Process explorer: indicate extension host better (fix #150820 on windows too) (#154454) --- src/vs/base/node/ps.ts | 2 +- src/vs/platform/extensions/electron-main/extensionHostStarter.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/base/node/ps.ts b/src/vs/base/node/ps.ts index 8fd62606254..38cd56f7d75 100644 --- a/src/vs/base/node/ps.ts +++ b/src/vs/base/node/ps.ts @@ -52,7 +52,7 @@ export function listProcesses(rootPid: number): Promise { const ISSUE_REPORTER_HINT = /--vscode-window-kind=issue-reporter/; const PROCESS_EXPLORER_HINT = /--vscode-window-kind=process-explorer/; const UTILITY_NETWORK_HINT = /--utility-sub-type=network/; - const UTILITY_EXTENSION_HOST_HINT = /--vscode-utility-kind=extensionHost/; + const UTILITY_EXTENSION_HOST_HINT = /--vscode-utility-kind=extension-host/; const WINDOWS_CRASH_REPORTER = /--crashes-directory/; const WINDOWS_PTY = /\\pipe\\winpty-control/; const WINDOWS_CONSOLE_HOST = /conhost\.exe/; diff --git a/src/vs/platform/extensions/electron-main/extensionHostStarter.ts b/src/vs/platform/extensions/electron-main/extensionHostStarter.ts index 027748ea8c1..832a28daaa0 100644 --- a/src/vs/platform/extensions/electron-main/extensionHostStarter.ts +++ b/src/vs/platform/extensions/electron-main/extensionHostStarter.ts @@ -324,7 +324,7 @@ class UtilityExtensionHostProcess extends Disposable { const modulePath = FileAccess.asFileUri('bootstrap-fork.js', require).fsPath; const args: string[] = ['--type=extensionHost', '--skipWorkspaceStorageLock']; const execArgv: string[] = opts.execArgv || []; - execArgv.push(`--vscode-utility-kind=extensionHost`); + execArgv.push(`--vscode-utility-kind=extension-host`); const env: { [key: string]: any } = { ...opts.env }; // Make sure all values are strings, otherwise the process will not start -- cgit v1.2.3 From 37c6c1ce340026317de409b110f9a1f19ffc55a8 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 8 Jul 2022 08:41:57 +0200 Subject: editors - let editors fully control confirmation on close (#152841) --- .../browser/parts/editor/editorActions.ts | 31 ++++++---- .../browser/parts/editor/editorGroupView.ts | 68 +++++++++++++--------- src/vs/workbench/common/editor/editorInput.ts | 45 +++++++++----- .../mergeEditor/browser/mergeEditorInput.ts | 23 ++++---- .../terminal/browser/terminalEditorInput.ts | 12 +++- 5 files changed, 110 insertions(+), 69 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index bf39a77a241..455e2deec30 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -573,24 +573,31 @@ abstract class AbstractCloseAllAction extends Action { override async run(): Promise { // Depending on the editor and auto save configuration, - // split dirty editors into buckets + // split editors into buckets for handling confirmation const dirtyEditorsWithDefaultConfirm = new Set(); const dirtyAutoSaveOnFocusChangeEditors = new Set(); const dirtyAutoSaveOnWindowChangeEditors = new Set(); - const dirtyEditorsWithCustomConfirm = new Map>(); + const editorsWithCustomConfirm = new Map>(); for (const { editor, groupId } of this.editorService.getEditors(EditorsOrder.SEQUENTIAL, { excludeSticky: this.excludeSticky })) { - if (!editor.isDirty() || editor.isSaving()) { - continue; // only interested in dirty editors that are not in the process of saving + let confirmClose = false; + if (editor.closeHandler) { + confirmClose = editor.closeHandler.showConfirm(); // custom handling of confirmation on close + } else { + confirmClose = editor.isDirty() && !editor.isSaving(); // default confirm only when dirty and not saving + } + + if (!confirmClose) { + continue; } // Editor has custom confirm implementation - if (typeof editor.confirm === 'function') { - let customEditorsToConfirm = dirtyEditorsWithCustomConfirm.get(editor.typeId); + if (typeof editor.closeHandler?.confirm === 'function') { + let customEditorsToConfirm = editorsWithCustomConfirm.get(editor.typeId); if (!customEditorsToConfirm) { customEditorsToConfirm = new Set(); - dirtyEditorsWithCustomConfirm.set(editor.typeId, customEditorsToConfirm); + editorsWithCustomConfirm.set(editor.typeId, customEditorsToConfirm); } customEditorsToConfirm.add({ editor, groupId }); @@ -619,7 +626,7 @@ abstract class AbstractCloseAllAction extends Action { if (dirtyEditorsWithDefaultConfirm.size > 0) { const editors = Array.from(dirtyEditorsWithDefaultConfirm.values()); - await this.revealDirtyEditors(editors); // help user make a decision by revealing editors + await this.revealEditorsToConfirm(editors); // help user make a decision by revealing editors const confirmation = await this.fileDialogService.showSaveConfirm(editors.map(({ editor }) => { if (editor instanceof SideBySideEditorInput) { @@ -642,12 +649,12 @@ abstract class AbstractCloseAllAction extends Action { } // 2.) Show custom confirm based dialog - for (const [, editorIdentifiers] of dirtyEditorsWithCustomConfirm) { + for (const [, editorIdentifiers] of editorsWithCustomConfirm) { const editors = Array.from(editorIdentifiers.values()); - await this.revealDirtyEditors(editors); // help user make a decision by revealing editors + await this.revealEditorsToConfirm(editors); // help user make a decision by revealing editors - const confirmation = await firstOrDefault(editors)?.editor.confirm?.(editors); + const confirmation = await firstOrDefault(editors)?.editor.closeHandler?.confirm?.(editors); if (typeof confirmation === 'number') { switch (confirmation) { case ConfirmResult.CANCEL: @@ -683,7 +690,7 @@ abstract class AbstractCloseAllAction extends Action { return this.doCloseAll(); } - private async revealDirtyEditors(editors: ReadonlyArray): Promise { + private async revealEditorsToConfirm(editors: ReadonlyArray): Promise { try { const handledGroups = new Set(); for (const { editor, groupId } of editors) { diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 21b5d732107..52ea45c47a4 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -1322,16 +1322,16 @@ export class EditorGroupView extends Themable implements IEditorGroupView { //#region closeEditor() async closeEditor(editor: EditorInput | undefined = this.activeEditor || undefined, options?: ICloseEditorOptions): Promise { - return this.doCloseEditorWithDirtyHandling(editor, options); + return this.doCloseEditorWithConfirmationHandling(editor, options); } - private async doCloseEditorWithDirtyHandling(editor: EditorInput | undefined = this.activeEditor || undefined, options?: ICloseEditorOptions, internalOptions?: IInternalEditorCloseOptions): Promise { + private async doCloseEditorWithConfirmationHandling(editor: EditorInput | undefined = this.activeEditor || undefined, options?: ICloseEditorOptions, internalOptions?: IInternalEditorCloseOptions): Promise { if (!editor) { return false; } - // Check for dirty and veto - const veto = await this.handleDirtyClosing([editor]); + // Check for confirmation and veto + const veto = await this.handleCloseConfirmation([editor]); if (veto) { return false; } @@ -1461,7 +1461,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { return this.model.closeEditor(editor, internalOptions?.context)?.editorIndex; } - private async handleDirtyClosing(editors: EditorInput[]): Promise { + private async handleCloseConfirmation(editors: EditorInput[]): Promise { if (!editors.length) { return false; // no veto } @@ -1470,15 +1470,15 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // To prevent multiple confirmation dialogs from showing up one after the other // we check if a pending confirmation is currently showing and if so, join that - let handleDirtyClosingPromise = this.mapEditorToPendingConfirmation.get(editor); - if (!handleDirtyClosingPromise) { - handleDirtyClosingPromise = this.doHandleDirtyClosing(editor); - this.mapEditorToPendingConfirmation.set(editor, handleDirtyClosingPromise); + let handleCloseConfirmationPromise = this.mapEditorToPendingConfirmation.get(editor); + if (!handleCloseConfirmationPromise) { + handleCloseConfirmationPromise = this.doHandleCloseConfirmation(editor); + this.mapEditorToPendingConfirmation.set(editor, handleCloseConfirmationPromise); } let veto: boolean; try { - veto = await handleDirtyClosingPromise; + veto = await handleCloseConfirmationPromise; } finally { this.mapEditorToPendingConfirmation.delete(editor); } @@ -1489,12 +1489,12 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } // Otherwise continue with the remainders - return this.handleDirtyClosing(editors); + return this.handleCloseConfirmation(editors); } - private async doHandleDirtyClosing(editor: EditorInput, options?: { skipAutoSave: boolean }): Promise { - if (!editor.isDirty() || editor.isSaving()) { - return false; // editor must be dirty and not saving + private async doHandleCloseConfirmation(editor: EditorInput, options?: { skipAutoSave: boolean }): Promise { + if (!this.shouldConfirmClose(editor)) { + return false; // no veto } if (editor instanceof SideBySideEditorInput && this.model.contains(editor.primary)) { @@ -1531,10 +1531,11 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // on auto-save configuration. // However, make sure to respect `skipAutoSave` option in case the automated // save fails which would result in the editor never closing. + // Also, we only do this if no custom confirmation handling is implemented. let confirmation = ConfirmResult.CANCEL; let saveReason = SaveReason.EXPLICIT; let autoSave = false; - if (!editor.hasCapability(EditorInputCapabilities.Untitled) && !options?.skipAutoSave) { + if (!editor.hasCapability(EditorInputCapabilities.Untitled) && !options?.skipAutoSave && !editor.closeHandler) { // Auto-save on focus change: save, because a dialog would steal focus // (see https://github.com/microsoft/vscode/issues/108752) @@ -1554,15 +1555,15 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } } - // No auto-save on focus change: ask user + // No auto-save on focus change or custom confirmation handler: ask user if (!autoSave) { - // Switch to editor that we want to handle and confirm to save/revert + // Switch to editor that we want to handle for confirmation await this.doOpenEditor(editor); // Let editor handle confirmation if implemented - if (typeof editor.confirm === 'function') { - confirmation = await editor.confirm(); + if (typeof editor.closeHandler?.confirm === 'function') { + confirmation = await editor.closeHandler.confirm(); } // Show a file specific confirmation @@ -1578,11 +1579,12 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } } - // It could be that the editor saved meanwhile or is saving, so we check + // It could be that the editor's choice of confirmation has changed + // given the check for confirmation is long running, so we check // again to see if anything needs to happen before closing for good. - // This can happen for example if autoSave: onFocusChange is configured + // This can happen for example if `autoSave: onFocusChange` is configured // so that the save happens when the dialog opens. - if (!editor.isDirty() || editor.isSaving()) { + if (!this.shouldConfirmClose(editor)) { return confirmation === ConfirmResult.CANCEL ? true : false; } @@ -1595,7 +1597,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // we handle the dirty editor again but this time ensuring to // show the confirm dialog // (see https://github.com/microsoft/vscode/issues/108752) - return this.doHandleDirtyClosing(editor, { skipAutoSave: true }); + return this.doHandleCloseConfirmation(editor, { skipAutoSave: true }); } return editor.isDirty(); // veto if still dirty @@ -1621,6 +1623,14 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } } + private shouldConfirmClose(editor: EditorInput): boolean { + if (editor.closeHandler) { + return editor.closeHandler.showConfirm(); // custom handling of confirmation on close + } + + return editor.isDirty() && !editor.isSaving(); // editor must be dirty and not saving + } + //#endregion //#region closeEditors() @@ -1632,8 +1642,8 @@ export class EditorGroupView extends Themable implements IEditorGroupView { const editors = this.doGetEditorsToClose(args); - // Check for dirty and veto - const veto = await this.handleDirtyClosing(editors.slice(0)); + // Check for confirmation and veto + const veto = await this.handleCloseConfirmation(editors.slice(0)); if (veto) { return false; } @@ -1714,8 +1724,8 @@ export class EditorGroupView extends Themable implements IEditorGroupView { return true; } - // Check for dirty and veto - const veto = await this.handleDirtyClosing(this.model.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE, options)); + // Check for confirmation and veto + const veto = await this.handleCloseConfirmation(this.model.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE, options)); if (veto) { return false; } @@ -1795,7 +1805,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this.doCloseEditor(editor, false, { context: EditorCloseContext.REPLACE }); closed = true; } else { - closed = await this.doCloseEditorWithDirtyHandling(editor, { preserveFocus: true }, { context: EditorCloseContext.REPLACE }); + closed = await this.doCloseEditorWithConfirmationHandling(editor, { preserveFocus: true }, { context: EditorCloseContext.REPLACE }); } if (!closed) { @@ -1815,7 +1825,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { if (activeReplacement.forceReplaceDirty) { this.doCloseEditor(activeReplacement.editor, false, { context: EditorCloseContext.REPLACE }); } else { - await this.doCloseEditorWithDirtyHandling(activeReplacement.editor, { preserveFocus: true }, { context: EditorCloseContext.REPLACE }); + await this.doCloseEditorWithConfirmationHandling(activeReplacement.editor, { preserveFocus: true }, { context: EditorCloseContext.REPLACE }); } } diff --git a/src/vs/workbench/common/editor/editorInput.ts b/src/vs/workbench/common/editor/editorInput.ts index 023e15af1af..86b53423c60 100644 --- a/src/vs/workbench/common/editor/editorInput.ts +++ b/src/vs/workbench/common/editor/editorInput.ts @@ -11,6 +11,31 @@ import { EditorInputCapabilities, Verbosity, GroupIdentifier, ISaveOptions, IRev import { isEqual } from 'vs/base/common/resources'; import { ConfirmResult } from 'vs/platform/dialogs/common/dialogs'; +export interface IEditorCloseHandler { + + /** + * If `true`, will call into the `confirm` method to ask for confirmation + * before closing the editor. + */ + showConfirm(): boolean; + + /** + * Allows an editor to control what should happen when the editor + * (or a list of editor of the same kind) is being closed. + * + * By default a file specific dialog will open if the editor is + * dirty and not in the process of saving. + * + * If the editor is not dealing with files or another condition + * should be used besides dirty state, this method should be + * implemented to show a different dialog. + * + * @param editors if more than one editor is closed, will pass in + * each editor of the same kind to be able to show a combined dialog. + */ + confirm(editors?: ReadonlyArray): Promise; +} + /** * Editor inputs are lightweight objects that can be passed to the workbench API to open inside the editor part. * Each editor input is mapped to an editor that is capable of opening it through the Platform facade. @@ -45,6 +70,12 @@ export abstract class EditorInput extends AbstractEditorInput { private disposed: boolean = false; + /** + * Optional: subclasses can override to implement + * custom confirmation on close behavior. + */ + readonly closeHandler?: IEditorCloseHandler; + /** * Unique type identifier for this input. Every editor input of the * same class should share the same type identifier. The type identifier @@ -168,20 +199,6 @@ export abstract class EditorInput extends AbstractEditorInput { return null; } - /** - * Optional: if this method is implemented, allows an editor to - * control what should happen when the editor (or a list of editors - * of the same kind) is dirty and there is an intent to close it. - * - * By default a file specific dialog will open. If the editor is - * not dealing with files, this method should be implemented to - * show a different dialog. - * - * @param editors if more than one editor is closed, will pass in - * each editor of the same kind to be able to show a combined dialog. - */ - confirm?(editors?: ReadonlyArray): Promise; - /** * Saves the editor. The provided groupId helps implementors * to e.g. preserve view state of the editor and re-open it diff --git a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts index 053c7309754..377dc53be55 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts @@ -14,7 +14,7 @@ import { IFileService } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILabelService } from 'vs/platform/label/common/label'; import { IEditorIdentifier, IUntypedEditorInput } from 'vs/workbench/common/editor'; -import { EditorInput } from 'vs/workbench/common/editor/editorInput'; +import { EditorInput, IEditorCloseHandler } from 'vs/workbench/common/editor/editorInput'; import { AbstractTextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { EditorWorkerServiceDiffComputer } from 'vs/workbench/contrib/mergeEditor/browser/model/diffComputer'; import { MergeEditorModel } from 'vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel'; @@ -22,7 +22,6 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { ILanguageSupport, ITextFileEditorModel, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { assertType } from 'vs/base/common/types'; -import { Event } from 'vs/base/common/event'; export class MergeEditorInputData { constructor( @@ -33,7 +32,7 @@ export class MergeEditorInputData { ) { } } -export class MergeEditorInput extends AbstractTextResourceEditorInput implements ILanguageSupport { +export class MergeEditorInput extends AbstractTextResourceEditorInput implements ILanguageSupport, IEditorCloseHandler { static readonly ID = 'mergeEditor.Input'; @@ -125,8 +124,6 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements this._store.add(input1); this._store.add(input2); this._store.add(result); - - this._store.add(Event.fromObservable(this._model.hasUnhandledConflicts)(() => this._onDidChangeDirty.fire(undefined))); } this._ignoreUnhandledConflictsForDirtyState = undefined; @@ -146,21 +143,25 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements // ---- FileEditorInput override isDirty(): boolean { - const textModelDirty = Boolean(this._outTextModel?.isDirty()); - if (textModelDirty) { + return Boolean(this._outTextModel?.isDirty()); + } + + override readonly closeHandler = this; + + showConfirm(): boolean { + if (this.isDirty()) { // text model dirty -> 3wm is dirty return true; } if (!this._ignoreUnhandledConflictsForDirtyState) { - // unhandled conflicts -> 3wm is dirty UNLESS we explicitly set this input - // to ignore unhandled conflicts for the dirty-state. This happens only - // after confirming to ignore unhandled changes + // unhandled conflicts -> 3wm asks to confirm UNLESS we explicitly set this input + // to ignore unhandled conflicts. This happens only after confirming to ignore unhandled changes return Boolean(this._model && this._model.hasUnhandledConflicts.get()); } return false; } - override async confirm(editors?: ReadonlyArray): Promise { + async confirm(editors?: ReadonlyArray): Promise { const inputs: MergeEditorInput[] = [this]; if (editors) { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts index b80d8fae41c..f5e73947655 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts @@ -9,7 +9,7 @@ import { dispose, toDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { EditorInputCapabilities, IEditorIdentifier, IUntypedEditorInput } from 'vs/workbench/common/editor'; import { IThemeService, ThemeIcon } from 'vs/platform/theme/common/themeService'; -import { EditorInput } from 'vs/workbench/common/editor/editorInput'; +import { EditorInput, IEditorCloseHandler } from 'vs/workbench/common/editor/editorInput'; import { ITerminalInstance, ITerminalInstanceService, terminalEditorId } from 'vs/workbench/contrib/terminal/browser/terminal'; import { getColorClass, getUriClasses } from 'vs/workbench/contrib/terminal/browser/terminalIcon'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -23,7 +23,7 @@ import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/termin import { ConfirmResult, IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { Emitter } from 'vs/base/common/event'; -export class TerminalEditorInput extends EditorInput { +export class TerminalEditorInput extends EditorInput implements IEditorCloseHandler { protected readonly _onDidRequestAttach = this._register(new Emitter()); readonly onDidRequestAttach = this._onDidRequestAttach.event; @@ -106,7 +106,13 @@ export class TerminalEditorInput extends EditorInput { return false; } - override async confirm(terminals?: ReadonlyArray): Promise { + override readonly closeHandler = this; + + showConfirm(): boolean { + return this.isDirty(); + } + + async confirm(terminals?: ReadonlyArray): Promise { const { choice } = await this._dialogService.show( Severity.Warning, localize('confirmDirtyTerminal.message', "Do you want to terminate running processes?"), -- cgit v1.2.3 From 4f991f848706ea963ccbd79887a92b4cd7dd1991 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 8 Jul 2022 10:21:38 +0200 Subject: Fix `View: Toggle Editor Group Sizes` (#154467) Figuring out whether a view was maximized was faulty, since it doesn't necessarily mean that all other views are minimized. Pushed the logic down to grid/gridview/splitview so it's now just simple widget API. Fixes: #154068 --- src/vs/base/browser/ui/grid/grid.ts | 10 +++++++++ src/vs/base/browser/ui/grid/gridview.ts | 25 ++++++++++++++++++++++ src/vs/base/browser/ui/splitview/splitview.ts | 17 +++++++++++++++ src/vs/workbench/browser/parts/editor/editor.ts | 2 -- .../browser/parts/editor/editorActions.ts | 4 ++-- .../browser/parts/editor/editorGroupView.ts | 8 ------- .../workbench/browser/parts/editor/editorPart.ts | 20 +++++------------ .../services/editor/common/editorGroupsService.ts | 2 +- .../editor/test/browser/editorService.test.ts | 8 +++---- .../test/browser/workbenchTestServices.ts | 1 - 10 files changed, 64 insertions(+), 33 deletions(-) (limited to 'src/vs') diff --git a/src/vs/base/browser/ui/grid/grid.ts b/src/vs/base/browser/ui/grid/grid.ts index e4cbed18667..cf8798982b0 100644 --- a/src/vs/base/browser/ui/grid/grid.ts +++ b/src/vs/base/browser/ui/grid/grid.ts @@ -527,6 +527,16 @@ export class Grid extends Disposable { return this.gridview.resizeView(location, size); } + /** + * Returns whether all other {@link IView views} are at their minimum size. + * + * @param view The reference {@link IView view}. + */ + isViewSizeMaximized(view: T): boolean { + const location = this.getViewLocation(view); + return this.gridview.isViewSizeMaximized(location); + } + /** * Get the size of a {@link IView view}. * diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index e121bcc10c8..8457663d657 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -592,6 +592,10 @@ class BranchNode implements ISplitView, IDisposable { this.splitview.resizeView(index, size); } + isChildSizeMaximized(index: number): boolean { + return this.splitview.isViewSizeMaximized(index); + } + distributeViewSizes(recursive = false): void { this.splitview.distributeViewSizes(); @@ -1431,6 +1435,27 @@ export class GridView implements IDisposable { } } + /** + * Returns whether all other {@link IView views} are at their minimum size. + * + * @param location The {@link GridLocation location} of the view. + */ + isViewSizeMaximized(location: GridLocation): boolean { + const [ancestors, node] = this.getNode(location); + + if (!(node instanceof LeafNode)) { + throw new Error('Invalid location'); + } + + for (let i = 0; i < ancestors.length; i++) { + if (!ancestors[i].isChildSizeMaximized(location[i])) { + return false; + } + } + + return true; + } + /** * Distribute the size among all {@link IView views} within the entire * grid or within a single {@link SplitView}. diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 57fbf0b1544..393f3ea3fda 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -931,6 +931,23 @@ export class SplitView extends Disposable { this.state = State.Idle; } + /** + * Returns whether all other {@link IView views} are at their minimum size. + */ + isViewSizeMaximized(index: number): boolean { + if (index < 0 || index >= this.viewItems.length) { + return false; + } + + for (const item of this.viewItems) { + if (item !== this.viewItems[index] && item.size > item.minimumSize) { + return false; + } + } + + return true; + } + /** * Distribute the entire {@link SplitView} size among all {@link IView views}. */ diff --git a/src/vs/workbench/browser/parts/editor/editor.ts b/src/vs/workbench/browser/parts/editor/editor.ts index 22791e7c00f..6703baae100 100644 --- a/src/vs/workbench/browser/parts/editor/editor.ts +++ b/src/vs/workbench/browser/parts/editor/editor.ts @@ -135,8 +135,6 @@ export interface IEditorGroupView extends IDisposable, ISerializableView, IEdito readonly titleHeight: IEditorGroupTitleHeight; - readonly isMinimized: boolean; - readonly disposed: boolean; setActive(isActive: boolean): void; diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index 455e2deec30..c93f52e60c6 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -1023,7 +1023,7 @@ export class MinimizeOtherGroupsAction extends Action { } override async run(): Promise { - this.editorGroupService.arrangeGroups(GroupsArrangement.MINIMIZE_OTHERS); + this.editorGroupService.arrangeGroups(GroupsArrangement.MAXIMIZE); } } @@ -1074,7 +1074,7 @@ export class MaximizeGroupAction extends Action { if (this.editorService.activeEditor) { this.layoutService.setPartHidden(true, Parts.SIDEBAR_PART); this.layoutService.setPartHidden(true, Parts.AUXILIARYBAR_PART); - this.editorGroupService.arrangeGroups(GroupsArrangement.MINIMIZE_OTHERS); + this.editorGroupService.arrangeGroups(GroupsArrangement.MAXIMIZE); } } } diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 52ea45c47a4..bdeec719d93 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -781,14 +781,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView { return this.titleAreaControl.getHeight(); } - get isMinimized(): boolean { - if (!this.dimension) { - return false; - } - - return this.dimension.width === this.minimumWidth || this.dimension.height === this.minimumHeight; - } - notifyIndexChanged(newIndex: number): void { if (this._index !== newIndex) { this._index = newIndex; diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index cf162aa9dae..da027276bd8 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -362,32 +362,22 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro case GroupsArrangement.EVEN: this.gridWidget.distributeViewSizes(); break; - case GroupsArrangement.MINIMIZE_OTHERS: + case GroupsArrangement.MAXIMIZE: this.gridWidget.maximizeViewSize(target); break; case GroupsArrangement.TOGGLE: if (this.isGroupMaximized(target)) { this.arrangeGroups(GroupsArrangement.EVEN); } else { - this.arrangeGroups(GroupsArrangement.MINIMIZE_OTHERS); + this.arrangeGroups(GroupsArrangement.MAXIMIZE); } break; } } - private isGroupMaximized(targetGroup: IEditorGroupView): boolean { - for (const group of this.groups) { - if (group === targetGroup) { - continue; // ignore target group - } - - if (!group.isMinimized) { - return false; // target cannot be maximized if one group is not minimized - } - } - - return true; + isGroupMaximized(targetGroup: IEditorGroupView): boolean { + return this.gridWidget.isViewSizeMaximized(targetGroup); } setGroupOrientation(orientation: GroupOrientation): void { @@ -609,7 +599,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro if (this.gridWidget) { const viewSize = this.gridWidget.getViewSize(group); if (viewSize.width === group.minimumWidth || viewSize.height === group.minimumHeight) { - this.arrangeGroups(GroupsArrangement.MINIMIZE_OTHERS, group); + this.arrangeGroups(GroupsArrangement.MAXIMIZE, group); } } } diff --git a/src/vs/workbench/services/editor/common/editorGroupsService.ts b/src/vs/workbench/services/editor/common/editorGroupsService.ts index aae30a8d46e..2e19d0d0cbf 100644 --- a/src/vs/workbench/services/editor/common/editorGroupsService.ts +++ b/src/vs/workbench/services/editor/common/editorGroupsService.ts @@ -47,7 +47,7 @@ export const enum GroupsArrangement { * Make the current active group consume the maximum * amount of space possible. */ - MINIMIZE_OTHERS, + MAXIMIZE, /** * Size all groups evenly. diff --git a/src/vs/workbench/services/editor/test/browser/editorService.test.ts b/src/vs/workbench/services/editor/test/browser/editorService.test.ts index e4da27e5ebc..f193e7d69b0 100644 --- a/src/vs/workbench/services/editor/test/browser/editorService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorService.test.ts @@ -1661,7 +1661,7 @@ suite('EditorService', () => { editor = await service.openEditor(input2, { pinned: true, activation: EditorActivation.ACTIVATE }, sideGroup); assert.strictEqual(part.activeGroup, sideGroup); - part.arrangeGroups(GroupsArrangement.MINIMIZE_OTHERS); + part.arrangeGroups(GroupsArrangement.MAXIMIZE); editor = await service.openEditor(input1, { pinned: true, preserveFocus: true, activation: EditorActivation.RESTORE }, rootGroup); assert.strictEqual(part.activeGroup, sideGroup); }); @@ -1681,13 +1681,13 @@ suite('EditorService', () => { assert.strictEqual(part.activeGroup, sideGroup); assert.notStrictEqual(rootGroup, sideGroup); - part.arrangeGroups(GroupsArrangement.MINIMIZE_OTHERS, part.activeGroup); + part.arrangeGroups(GroupsArrangement.MAXIMIZE, part.activeGroup); await rootGroup.closeEditor(input2); assert.strictEqual(part.activeGroup, sideGroup); - assert.strictEqual(rootGroup.isMinimized, true); - assert.strictEqual(part.activeGroup.isMinimized, false); + assert(!part.isGroupMaximized(rootGroup)); + assert(part.isGroupMaximized(part.activeGroup)); }); test('active editor change / visible editor change events', async function () { diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index f7e9543fb3f..1a2209c0e43 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -853,7 +853,6 @@ export class TestEditorGroupView implements IEditorGroupView { titleHeight!: IEditorGroupTitleHeight; isEmpty = true; - isMinimized = false; onWillDispose: Event = Event.None; onDidModelChange: Event = Event.None; -- cgit v1.2.3 From d7de53f956a9300e9608c48a7728371f05a8a8ba Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 8 Jul 2022 11:15:50 +0200 Subject: add `vscode-coi`-search-param when making requests for the webview and its worker --- .../services/extensions/browser/webWorkerExtensionHost.ts | 10 +++++++++- .../extensions/worker/webWorkerExtensionHostIframe.html | 6 +++++- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts index 90f4cd0ec56..fc9dcd1125e 100644 --- a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts +++ b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts @@ -82,7 +82,15 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost } private async _getWebWorkerExtensionHostIframeSrc(): Promise { - const suffix = this._environmentService.debugExtensionHost && this._environmentService.debugRenderer ? '?debugged=1' : '?'; + const suffixSearchParams = new URLSearchParams(); + if (this._environmentService.debugExtensionHost && this._environmentService.debugRenderer) { + suffixSearchParams.set('debugged', '1'); + } + if (globalThis.crossOriginIsolated) { + suffixSearchParams.set('vscode-coi', '3' /*COOP+COEP*/); + } + const suffix = `?${suffixSearchParams.toString()}`; + const iframeModulePath = 'vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html'; if (platform.isWeb) { const webEndpointUrlTemplate = this._productService.webEndpointUrlTemplate; diff --git a/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html b/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html index 11135d5fff1..92a1928112f 100644 --- a/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html +++ b/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html @@ -66,7 +66,11 @@ function start() { try { - const worker = new Worker('../../../../base/worker/workerMain.js', { name }); + const workerUrl = new URL('../../../../base/worker/workerMain.js'); + if(crossOriginIsolated) { + workerUrl.searchParams.set('vscode-coi', 2 /*COEP*/) + } + const worker = new Worker(workerUrl.toString(), { name }); worker.postMessage('vs/workbench/api/worker/extensionHostWorker'); const nestedWorkers = new Map(); -- cgit v1.2.3 From cd8dfa1040eb65857da1266cf04d6d4d834dbaf0 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 8 Jul 2022 11:16:25 +0200 Subject: sandbox - log when enabled (#154469) --- src/vs/workbench/electron-sandbox/desktop.main.ts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/vs') diff --git a/src/vs/workbench/electron-sandbox/desktop.main.ts b/src/vs/workbench/electron-sandbox/desktop.main.ts index 38363be6614..f5878699fdf 100644 --- a/src/vs/workbench/electron-sandbox/desktop.main.ts +++ b/src/vs/workbench/electron-sandbox/desktop.main.ts @@ -56,6 +56,7 @@ import { PolicyChannelClient } from 'vs/platform/policy/common/policyIpc'; import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/policy'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { process } from 'vs/base/parts/sandbox/electron-sandbox/globals'; export class DesktopMain extends Disposable { @@ -184,6 +185,9 @@ export class DesktopMain extends Disposable { if (logService.getLevel() === LogLevel.Trace) { logService.trace('workbench#open(): with configuration', safeStringify(this.configuration)); } + if (process.sandboxed) { + logService.info('Electron sandbox mode is enabled!'); + } // Shared Process const sharedProcessService = new SharedProcessService(this.configuration.windowId, logService); -- cgit v1.2.3 From 0f1adf394001248c1cc251f7a2290a8b5581b906 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 8 Jul 2022 13:05:06 +0200 Subject: only reveal first conflict when not having previous view state (#154482) fixes https://github.com/microsoft/vscode/issues/153962 --- .../contrib/mergeEditor/browser/view/mergeEditor.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts index ff44bc01163..abd5efbe468 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts @@ -307,16 +307,17 @@ export class MergeEditor extends AbstractTextEditor { this._ctxBaseResourceScheme.set(model.base.uri.scheme); const viewState = this.loadEditorViewState(input, context); - this._applyViewState(viewState); - - this._sessionDisposables.add(thenIfNotDisposed(model.onInitialized, () => { - const firstConflict = model.modifiedBaseRanges.get().find(r => r.isConflicting); - if (!firstConflict) { - return; - } - - this.input1View.editor.revealLineInCenter(firstConflict.input1Range.startLineNumber); - })); + if (viewState) { + this._applyViewState(viewState); + } else { + this._sessionDisposables.add(thenIfNotDisposed(model.onInitialized, () => { + const firstConflict = model.modifiedBaseRanges.get().find(r => r.isConflicting); + if (!firstConflict) { + return; + } + this.input1View.editor.revealLineInCenter(firstConflict.input1Range.startLineNumber); + })); + } this._sessionDisposables.add(autorunWithStore((reader, store) => { -- cgit v1.2.3 From 1c51e8fb91269fb765949794f3cc067349ed89d6 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 8 Jul 2022 13:20:44 +0200 Subject: Add a specialized unhandled conflicts close handler (#154471) This is set dynamically whenever unhandled conflicts are detected. It unsets itself when merging is done so that the normal save-close-handler comes to place https://github.com/microsoft/vscode/issues/152841 --- .../mergeEditor/browser/mergeEditorInput.ts | 110 +++++++++------------ 1 file changed, 46 insertions(+), 64 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts index 377dc53be55..4f29941dc13 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts @@ -19,9 +19,8 @@ import { AbstractTextResourceEditorInput } from 'vs/workbench/common/editor/text import { EditorWorkerServiceDiffComputer } from 'vs/workbench/contrib/mergeEditor/browser/model/diffComputer'; import { MergeEditorModel } from 'vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { ILanguageSupport, ITextFileEditorModel, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { assertType } from 'vs/base/common/types'; +import { autorun } from 'vs/base/common/observable'; export class MergeEditorInputData { constructor( @@ -32,13 +31,14 @@ export class MergeEditorInputData { ) { } } -export class MergeEditorInput extends AbstractTextResourceEditorInput implements ILanguageSupport, IEditorCloseHandler { +export class MergeEditorInput extends AbstractTextResourceEditorInput implements ILanguageSupport { static readonly ID = 'mergeEditor.Input'; private _model?: MergeEditorModel; private _outTextModel?: ITextFileEditorModel; - private _ignoreUnhandledConflictsForDirtyState?: true; + + override closeHandler: MergeEditorCloseHandler | undefined; constructor( public readonly base: URI, @@ -47,8 +47,6 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements public readonly result: URI, @IInstantiationService private readonly _instaService: IInstantiationService, @ITextModelService private readonly _textModelService: ITextModelService, - @IDialogService private readonly _dialogService: IDialogService, - @IFilesConfigurationService private readonly _filesConfigurationService: IFilesConfigurationService, @IEditorService editorService: IEditorService, @ITextFileService textFileService: ITextFileService, @ILabelService labelService: ILabelService, @@ -117,6 +115,13 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements }, ); + // set/unset the closeHandler whenever unhandled conflicts are detected + const closeHandler = this._instaService.createInstance(MergeEditorCloseHandler, this._model); + this._store.add(autorun('closeHandler', reader => { + const value = this._model!.hasUnhandledConflicts.read(reader); + this.closeHandler = value ? closeHandler : undefined; + })); + await this._model.onInitialized; this._store.add(this._model); @@ -126,7 +131,6 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements this._store.add(result); } - this._ignoreUnhandledConflictsForDirtyState = undefined; return this._model; } @@ -146,67 +150,54 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements return Boolean(this._outTextModel?.isDirty()); } - override readonly closeHandler = this; + setLanguageId(languageId: string, _setExplicitly?: boolean): void { + this._model?.setLanguageId(languageId); + } + + // implement get/set languageId + // implement get/set encoding +} + +class MergeEditorCloseHandler implements IEditorCloseHandler { + + private _ignoreUnhandledConflicts: boolean = false; + + constructor( + private readonly _model: MergeEditorModel, + @IDialogService private readonly _dialogService: IDialogService, + ) { } showConfirm(): boolean { - if (this.isDirty()) { - // text model dirty -> 3wm is dirty - return true; - } - if (!this._ignoreUnhandledConflictsForDirtyState) { - // unhandled conflicts -> 3wm asks to confirm UNLESS we explicitly set this input - // to ignore unhandled conflicts. This happens only after confirming to ignore unhandled changes - return Boolean(this._model && this._model.hasUnhandledConflicts.get()); - } - return false; + // unhandled conflicts -> 3wm asks to confirm UNLESS we explicitly set this input + // to ignore unhandled conflicts. This happens only after confirming to ignore unhandled changes + return !this._ignoreUnhandledConflicts && this._model.hasUnhandledConflicts.get(); } - async confirm(editors?: ReadonlyArray): Promise { + async confirm(editors?: readonly IEditorIdentifier[] | undefined): Promise { - const inputs: MergeEditorInput[] = [this]; - if (editors) { - for (const { editor } of editors) { - if (editor instanceof MergeEditorInput) { - inputs.push(editor); - } - } - } + const handler: MergeEditorCloseHandler[] = [this]; + editors?.forEach(candidate => candidate.editor.closeHandler instanceof MergeEditorCloseHandler && handler.push(candidate.editor.closeHandler)); - const inputsWithUnhandledConflicts = inputs + const inputsWithUnhandledConflicts = handler .filter(input => input._model && input._model.hasUnhandledConflicts.get()); if (inputsWithUnhandledConflicts.length === 0) { + // shouldn't happen return ConfirmResult.SAVE; } - const actions: string[] = []; + const actions: string[] = [ + localize('unhandledConflicts.ignore', "Continue with Conflicts"), + localize('unhandledConflicts.discard', "Discard Merge Changes"), + localize('unhandledConflicts.cancel', "Cancel"), + ]; const options = { - cancelId: 0, - detail: inputs.length > 1 - ? localize('unhandledConflicts.detailN', 'Merge conflicts in {0} editors will remain unhandled.', inputs.length) + cancelId: 2, + detail: handler.length > 1 + ? localize('unhandledConflicts.detailN', 'Merge conflicts in {0} editors will remain unhandled.', handler.length) : localize('unhandledConflicts.detail1', 'Merge conflicts in this editor will remain unhandled.') }; - const isAnyAutoSave = this._filesConfigurationService.getAutoSaveMode() !== AutoSaveMode.OFF; - if (!isAnyAutoSave) { - // manual-save: FYI and discard - actions.push( - localize('unhandledConflicts.manualSaveIgnore', "Save and Continue with Conflicts"), // 0 - localize('unhandledConflicts.discard', "Discard Merge Changes"), // 1 - localize('unhandledConflicts.manualSaveNoSave', "Don't Save"), // 2 - ); - - } else { - // auto-save: only FYI - actions.push( - localize('unhandledConflicts.ignore', "Continue with Conflicts"), // 0 - localize('unhandledConflicts.discard', "Discard Merge Changes"), // 1 - ); - } - - actions.push(localize('unhandledConflicts.cancel', "Cancel")); - options.cancelId = actions.length - 1; - const { choice } = await this._dialogService.show( Severity.Info, localize('unhandledConflicts.msg', 'Do you want to continue with unhandled conflicts?'), // 1 @@ -221,8 +212,8 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements // save or revert: in both cases we tell the inputs to ignore unhandled conflicts // for the dirty state computation. - for (const input of inputs) { - input._ignoreUnhandledConflictsForDirtyState = true; + for (const input of handler) { + input._ignoreUnhandledConflicts = true; } if (choice === 0) { @@ -231,7 +222,7 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements } else if (choice === 1) { // discard: undo all changes and save original (pre-merge) state - for (const input of inputs) { + for (const input of handler) { input._discardMergeChanges(); } return ConfirmResult.SAVE; @@ -243,8 +234,6 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements } private _discardMergeChanges(): void { - assertType(this._model !== undefined); - const chunks: string[] = []; while (true) { const chunk = this._model.resultSnapshot.read(); @@ -255,11 +244,4 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements } this._model.result.setValue(chunks.join()); } - - setLanguageId(languageId: string, _setExplicitly?: boolean): void { - this._model?.setLanguageId(languageId); - } - - // implement get/set languageId - // implement get/set encoding } -- cgit v1.2.3 From c6736e14839a020b2a4fc656b6fe672471eaf17e Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Jul 2022 04:45:16 -0700 Subject: Remove ability for terminal editors to be dirty Fixes #154496 --- .../terminal/browser/terminalEditorInput.ts | 31 +++++----------------- 1 file changed, 6 insertions(+), 25 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts index f5e73947655..e851f6a8cf2 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts @@ -25,19 +25,20 @@ import { Emitter } from 'vs/base/common/event'; export class TerminalEditorInput extends EditorInput implements IEditorCloseHandler { - protected readonly _onDidRequestAttach = this._register(new Emitter()); - readonly onDidRequestAttach = this._onDidRequestAttach.event; - static readonly ID = 'workbench.editors.terminal'; + override readonly closeHandler = this; + private _isDetached = false; private _isShuttingDown = false; private _isReverted = false; private _copyLaunchConfig?: IShellLaunchConfig; private _terminalEditorFocusContextKey: IContextKey; - private _group: IEditorGroup | undefined; + protected readonly _onDidRequestAttach = this._register(new Emitter()); + readonly onDidRequestAttach = this._onDidRequestAttach.event; + setGroup(group: IEditorGroup | undefined) { this._group = group; } @@ -64,13 +65,6 @@ export class TerminalEditorInput extends EditorInput implements IEditorCloseHand } this._terminalInstance = instance; this._setupInstanceListeners(); - - // Refresh dirty state when the confirm on kill setting is changed - this._configurationService.onDidChangeConfiguration(e => { - if (e.affectsConfiguration(TerminalSettingId.ConfirmOnKill)) { - this._onDidChangeDirty.fire(); - } - }); } override copy(): EditorInput { @@ -95,7 +89,7 @@ export class TerminalEditorInput extends EditorInput implements IEditorCloseHand return this._isDetached ? undefined : this._terminalInstance; } - override isDirty(): boolean { + showConfirm(): boolean { if (this._isReverted) { return false; } @@ -106,12 +100,6 @@ export class TerminalEditorInput extends EditorInput implements IEditorCloseHand return false; } - override readonly closeHandler = this; - - showConfirm(): boolean { - return this.isDirty(); - } - async confirm(terminals?: ReadonlyArray): Promise { const { choice } = await this._dialogService.show( Severity.Warning, @@ -154,12 +142,6 @@ export class TerminalEditorInput extends EditorInput implements IEditorCloseHand this._terminalEditorFocusContextKey = TerminalContextKeys.editorFocus.bindTo(_contextKeyService); - // Refresh dirty state when the confirm on kill setting is changed - this._configurationService.onDidChangeConfiguration(e => { - if (e.affectsConfiguration(TerminalSettingId.ConfirmOnKill)) { - this._onDidChangeDirty.fire(); - } - }); if (_terminalInstance) { this._setupInstanceListeners(); } @@ -184,7 +166,6 @@ export class TerminalEditorInput extends EditorInput implements IEditorCloseHand instance.onIconChanged(() => this._onDidChangeLabel.fire()), instance.onDidFocus(() => this._terminalEditorFocusContextKey.set(true)), instance.onDidBlur(() => this._terminalEditorFocusContextKey.reset()), - instance.onDidChangeHasChildProcesses(() => this._onDidChangeDirty.fire()), instance.statusList.onDidChangePrimaryStatus(() => this._onDidChangeLabel.fire()) ]; -- cgit v1.2.3 From 96f310e3ebee05189f03e974713ec1c666b15b6a Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Jul 2022 04:53:28 -0700 Subject: Including whitespace in query for contiguous search Fixes #154497 --- src/vs/base/parts/quickinput/browser/quickInputList.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/vs') diff --git a/src/vs/base/parts/quickinput/browser/quickInputList.ts b/src/vs/base/parts/quickinput/browser/quickInputList.ts index d2c58f8c6f7..3292370eb5a 100644 --- a/src/vs/base/parts/quickinput/browser/quickInputList.ts +++ b/src/vs/base/parts/quickinput/browser/quickInputList.ts @@ -612,6 +612,8 @@ export class QuickInputList { this.list.layout(); return false; } + + const queryWithWhitespace = query; query = query.trim(); // Reset filtering @@ -634,7 +636,7 @@ export class QuickInputList { if (this.matchOnLabelMode === 'fuzzy') { labelHighlights = this.matchOnLabel ? withNullAsUndefined(matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneLabel))) : undefined; } else { - labelHighlights = this.matchOnLabel ? withNullAsUndefined(matchesContiguousIconAware(query, parseLabelWithIcons(element.saneLabel))) : undefined; + labelHighlights = this.matchOnLabel ? withNullAsUndefined(matchesContiguousIconAware(queryWithWhitespace, parseLabelWithIcons(element.saneLabel))) : undefined; } const descriptionHighlights = this.matchOnDescription ? withNullAsUndefined(matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneDescription || ''))) : undefined; const detailHighlights = this.matchOnDetail ? withNullAsUndefined(matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneDetail || ''))) : undefined; @@ -733,13 +735,13 @@ export class QuickInputList { } } -export function matchesContiguousIconAware(query: string, target: IParsedLabelWithIcons, enableSeparateSubstringMatching = false): IMatch[] | null { +export function matchesContiguousIconAware(query: string, target: IParsedLabelWithIcons): IMatch[] | null { const { text, iconOffsets } = target; // Return early if there are no icon markers in the word to match against if (!iconOffsets || iconOffsets.length === 0) { - return matchesContiguous(query, text, enableSeparateSubstringMatching); + return matchesContiguous(query, text); } // Trim the word to match against because it could have leading @@ -748,7 +750,7 @@ export function matchesContiguousIconAware(query: string, target: IParsedLabelWi const leadingWhitespaceOffset = text.length - wordToMatchAgainstWithoutIconsTrimmed.length; // match on value without icon - const matches = matchesContiguous(query, wordToMatchAgainstWithoutIconsTrimmed, enableSeparateSubstringMatching); + const matches = matchesContiguous(query, wordToMatchAgainstWithoutIconsTrimmed); // Map matches back to offsets with icon and trimming if (matches) { @@ -762,7 +764,7 @@ export function matchesContiguousIconAware(query: string, target: IParsedLabelWi return matches; } -function matchesContiguous(word: string, wordToMatchAgainst: string, enableSeparateSubstringMatching = false): IMatch[] | null { +function matchesContiguous(word: string, wordToMatchAgainst: string): IMatch[] | null { const matchIndex = wordToMatchAgainst.toLowerCase().indexOf(word.toLowerCase()); if (matchIndex !== -1) { return [{ start: matchIndex, end: matchIndex + word.length }]; -- cgit v1.2.3 From 1eb2480d91650f82b3b1da0b05d382a01b2d38e2 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Jul 2022 07:23:00 -0700 Subject: Don't write initialText new line when echo is false Fixes #152645 --- src/vs/platform/terminal/common/terminal.ts | 8 +++--- src/vs/platform/terminal/node/ptyService.ts | 2 +- .../contrib/tasks/browser/terminalTaskSystem.ts | 10 +++++-- .../contrib/terminal/browser/terminalInstance.ts | 32 ++++++++++++++++++---- 4 files changed, 39 insertions(+), 13 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 4ef5e51de3e..5ce915d4946 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -443,11 +443,11 @@ export interface IShellLaunchConfig { /** * A string including ANSI escape sequences that will be written to the terminal emulator - * _before_ the terminal process has launched, a trailing \n is added at the end of the string. - * This allows for example the terminal instance to display a styled message as the first line - * of the terminal. Use \x1b over \033 or \e for the escape control character. + * _before_ the terminal process has launched, when a string is specified, a trailing \n is + * added at the end. This allows for example the terminal instance to display a styled message + * as the first line of the terminal. Use \x1b over \033 or \e for the escape control character. */ - initialText?: string; + initialText?: string | { text: string; trailingNewLine: boolean }; /** * Custom PTY/pseudoterminal process to use. diff --git a/src/vs/platform/terminal/node/ptyService.ts b/src/vs/platform/terminal/node/ptyService.ts index bdecef41367..c45d75bbb12 100644 --- a/src/vs/platform/terminal/node/ptyService.ts +++ b/src/vs/platform/terminal/node/ptyService.ts @@ -190,7 +190,7 @@ export class PtyService extends Disposable implements IPtyService { executableEnv, options }; - const persistentProcess = new PersistentTerminalProcess(id, process, workspaceId, workspaceName, shouldPersist, cols, rows, processLaunchOptions, unicodeVersion, this._reconnectConstants, this._logService, isReviving ? shellLaunchConfig.initialText : undefined, rawReviveBuffer, shellLaunchConfig.icon, shellLaunchConfig.color, shellLaunchConfig.name, shellLaunchConfig.fixedDimensions); + const persistentProcess = new PersistentTerminalProcess(id, process, workspaceId, workspaceName, shouldPersist, cols, rows, processLaunchOptions, unicodeVersion, this._reconnectConstants, this._logService, isReviving && typeof shellLaunchConfig.initialText === 'string' ? shellLaunchConfig.initialText : undefined, rawReviveBuffer, shellLaunchConfig.icon, shellLaunchConfig.color, shellLaunchConfig.name, shellLaunchConfig.fixedDimensions); process.onDidChangeProperty(property => this._onDidChangeProperty.fire({ id, property })); process.onProcessExit(event => { persistentProcess.dispose(); diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index 754a84163c1..7cfab363b6d 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -1157,7 +1157,10 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { }, 'Executing task: {0}', commandLine), { excludeLeadingNewLine: true }) + this.taskShellIntegrationOutputSequence; } } else { - shellLaunchConfig.initialText = this.taskShellIntegrationStartSequence + this.taskShellIntegrationOutputSequence; + shellLaunchConfig.initialText = { + text: this.taskShellIntegrationStartSequence + this.taskShellIntegrationOutputSequence, + trailingNewLine: false + }; } } else { const commandExecutable = (task.command.runtime !== RuntimeType.CustomExecution) ? CommandString.value(command) : undefined; @@ -1197,7 +1200,10 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { }, 'Executing task: {0}', `${shellLaunchConfig.executable} ${getArgsToEcho(shellLaunchConfig.args)}`), { excludeLeadingNewLine: true }) + this.taskShellIntegrationOutputSequence; } } else { - shellLaunchConfig.initialText = this.taskShellIntegrationStartSequence + this.taskShellIntegrationOutputSequence; + shellLaunchConfig.initialText = { + text: this.taskShellIntegrationStartSequence + this.taskShellIntegrationOutputSequence, + trailingNewLine: false + }; } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 8d398d7a8be..e4187f6ab3c 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -698,7 +698,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { // Write initial text, deferring onLineFeed listener when applicable to avoid firing // onLineData events containing initialText if (this._shellLaunchConfig.initialText) { - this.xterm.raw.writeln(this._shellLaunchConfig.initialText, () => { + this._writeInitialText(this.xterm, () => { lineDataEventAddon.onLineData(e => this._onLineData.fire(e)); }); } else { @@ -1821,29 +1821,49 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } } + private _writeInitialText(xterm: XtermTerminal, callback?: () => void): void { + if (!this._shellLaunchConfig.initialText) { + callback?.(); + return; + } + const text = typeof this._shellLaunchConfig.initialText === 'string' + ? this._shellLaunchConfig.initialText + : this._shellLaunchConfig.initialText?.text; + if (typeof this._shellLaunchConfig.initialText === 'string') { + xterm.raw.writeln(text, callback); + } else { + if (this._shellLaunchConfig.initialText.trailingNewLine) { + xterm.raw.writeln(text, callback); + } else { + xterm.raw.write(text, callback); + } + } + } + async reuseTerminal(shell: IShellLaunchConfig, reset: boolean = false): Promise { // Unsubscribe any key listener we may have. this._pressAnyKeyToCloseListener?.dispose(); this._pressAnyKeyToCloseListener = undefined; - if (this.xterm) { + const xterm = this.xterm; + if (xterm) { if (!reset) { // Ensure new processes' output starts at start of new line - await new Promise(r => this.xterm!.raw.write('\n\x1b[G', r)); + await new Promise(r => xterm.raw.write('\n\x1b[G', r)); } // Print initialText if specified if (shell.initialText) { - await new Promise(r => this.xterm!.raw.writeln(shell.initialText!, r)); + await new Promise(r => this._writeInitialText(xterm, r)); } // Clean up waitOnExit state if (this._isExiting && this._shellLaunchConfig.waitOnExit) { - this.xterm.raw.options.disableStdin = false; + xterm.raw.options.disableStdin = false; this._isExiting = false; } if (reset) { - this.xterm.clearDecorations(); + xterm.clearDecorations(); } } -- cgit v1.2.3 From 62cd4c595feca8ce1887d8374fbe859510ac0427 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 8 Jul 2022 16:35:29 +0200 Subject: add logging to understand why/how test sometimes fails, https://github.com/microsoft/vscode/issues/154237 (#154514) --- src/vs/base/test/common/map.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/base/test/common/map.test.ts b/src/vs/base/test/common/map.test.ts index 3a979de3229..896d06ec812 100644 --- a/src/vs/base/test/common/map.test.ts +++ b/src/vs/base/test/common/map.test.ts @@ -852,12 +852,12 @@ suite('Map', () => { for (const item of keys) { tst.set(item, true); - assert.ok(tst._isBalanced()); + assert.ok(tst._isBalanced(), `SET${item}|${keys.map(String).join()}`); } for (const item of keys) { tst.delete(item); - assert.ok(tst._isBalanced()); + assert.ok(tst._isBalanced(), `DEL${item}|${keys.map(String).join()}`); } } }); -- cgit v1.2.3 From 4ccbed762465c3fc7cabb2837652aa35c289ebb6 Mon Sep 17 00:00:00 2001 From: Jean Pierre Date: Fri, 8 Jul 2022 10:10:04 -0500 Subject: Update src/vs/workbench/contrib/terminal/browser/terminalInstance.ts Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com> --- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 5a98560dae0..c1bbe018ea2 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1368,7 +1368,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._pressAnyKeyToCloseListener = undefined; } - if (typeof this._exitReason === 'undefined') { + if (this._exitReason === undefined) { this._exitReason = reason ?? TerminalExitReason.Unknown; } -- cgit v1.2.3 From d4447ae79c782e4073148a1a88a91e4a5207a3da Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 8 Jul 2022 18:39:52 +0200 Subject: check application scope in abstract layer --- .../common/abstractExtensionManagementService.ts | 24 ++++++++++++++--- .../node/extensionManagementService.ts | 30 ++++++++-------------- .../common/webExtensionManagementService.ts | 4 +-- 3 files changed, 33 insertions(+), 25 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts index 0a06843fb5d..0e19fa5b37b 100644 --- a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts +++ b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts @@ -18,10 +18,11 @@ import { ServerInstallOptions, ServerInstallVSIXOptions, ServerUninstallOptions, Metadata, ServerInstallExtensionEvent, ServerInstallExtensionResult, ServerUninstallExtensionEvent, ServerDidUninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions, ExtensionKey, getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, getMaliciousExtensionsSet } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { ExtensionType, IExtensionManifest, TargetPlatform } from 'vs/platform/extensions/common/extensions'; +import { ExtensionType, IExtensionManifest, isApplicationScopedExtension, TargetPlatform } from 'vs/platform/extensions/common/extensions'; import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; export interface IInstallExtensionTask { readonly identifier: IExtensionIdentifier; @@ -66,7 +67,8 @@ export abstract class AbstractExtensionManagementService extends Disposable impl @IExtensionGalleryService protected readonly galleryService: IExtensionGalleryService, @ITelemetryService protected readonly telemetryService: ITelemetryService, @ILogService protected readonly logService: ILogService, - @IProductService protected readonly productService: IProductService + @IProductService protected readonly productService: IProductService, + @IUserDataProfilesService protected readonly userDataProfilesService: IUserDataProfilesService, ) { super(); this._register(toDisposable(() => { @@ -599,6 +601,20 @@ export abstract class AbstractExtensionManagementService extends Disposable impl } } + private createInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask { + if (options.profileLocation && isApplicationScopedExtension(manifest)) { + options = { ...options, profileLocation: this.userDataProfilesService.defaultProfile.extensionsResource }; + } + return this.doCreateInstallExtensionTask(manifest, extension, options); + } + + private createUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions): IUninstallExtensionTask { + if (options.profileLocation && extension.isApplicationScoped) { + options = { ...options, profileLocation: this.userDataProfilesService.defaultProfile.extensionsResource }; + } + return this.doCreateUninstallExtensionTask(extension, options); + } + abstract getTargetPlatform(): Promise; abstract zip(extension: ILocalExtension): Promise; abstract unzip(zipLocation: URI): Promise; @@ -610,8 +626,8 @@ export abstract class AbstractExtensionManagementService extends Disposable impl abstract updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): Promise; abstract updateExtensionScope(local: ILocalExtension, isMachineScoped: boolean): Promise; - protected abstract createInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask; - protected abstract createUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions): IUninstallExtensionTask; + protected abstract doCreateInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask; + protected abstract doCreateUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions): IUninstallExtensionTask; } export function joinErrors(errorOrErrors: (Error | string) | (Array)): Error { diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 5171a2fa2e4..a5f367b4124 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -79,9 +79,9 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi @IFileService private readonly fileService: IFileService, @IProductService productService: IProductService, @IUriIdentityService uriIdentityService: IUriIdentityService, - @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, + @IUserDataProfilesService userDataProfilesService: IUserDataProfilesService, ) { - super(galleryService, telemetryService, logService, productService); + super(galleryService, telemetryService, logService, productService, userDataProfilesService); const extensionLifecycle = this._register(instantiationService.createInstance(ExtensionsLifecycle)); this.extensionsScanner = this._register(instantiationService.createInstance(ExtensionsScanner, extension => extensionLifecycle.postUninstall(extension))); this.manifestCache = this._register(new ExtensionsManifestCache(environmentService, this)); @@ -178,7 +178,7 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi return downloadedLocation; } - protected createInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask { + protected doCreateInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask { let installExtensionTask: IInstallExtensionTask | undefined; if (URI.isUri(extension)) { installExtensionTask = new InstallVSIXTask(manifest, extension, options, this.galleryService, this.extensionsScanner, this.logService); @@ -190,15 +190,15 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi installExtensionTask.waitUntilTaskIsFinished().then(() => this.installGalleryExtensionsTasks.delete(key)); } } - if (options.profileLocation && this.userDataProfilesService.defaultProfile.extensionsResource) { - return new InstallExtensionInProfileTask(installExtensionTask, options.profileLocation, this.userDataProfilesService.defaultProfile.extensionsResource, this.extensionsProfileScannerService); + if (options.profileLocation) { + return new InstallExtensionInProfileTask(installExtensionTask, options.profileLocation, this.extensionsProfileScannerService); } return installExtensionTask; } - protected createUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions): IUninstallExtensionTask { - if (options.profileLocation && this.userDataProfilesService.defaultProfile.extensionsResource) { - return new UninstallExtensionFromProfileTask(extension, options.profileLocation, this.userDataProfilesService, this.extensionsProfileScannerService); + protected doCreateUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions): IUninstallExtensionTask { + if (options.profileLocation) { + return new UninstallExtensionFromProfileTask(extension, options.profileLocation, this.extensionsProfileScannerService); } return new UninstallExtensionTask(extension, options, this.extensionsScanner); } @@ -735,8 +735,7 @@ class InstallExtensionInProfileTask implements IInstallExtensionTask { constructor( private readonly task: IInstallExtensionTask, - readonly profileLocation: URI, - private readonly defaultProfileLocation: URI, + private readonly profileLocation: URI, private readonly extensionsProfileScannerService: IExtensionsProfileScannerService, ) { this.promise = this.waitAndAddExtensionToProfile(); @@ -744,8 +743,7 @@ class InstallExtensionInProfileTask implements IInstallExtensionTask { private async waitAndAddExtensionToProfile(): Promise<{ local: ILocalExtension; metadata: Metadata }> { const result = await this.task.waitUntilTaskIsFinished(); - const profileLocation = result.local.isApplicationScoped ? this.defaultProfileLocation : this.profileLocation; - await this.extensionsProfileScannerService.addExtensionsToProfile([[result.local, result.metadata]], profileLocation); + await this.extensionsProfileScannerService.addExtensionsToProfile([[result.local, result.metadata]], this.profileLocation); return result; } @@ -808,19 +806,13 @@ class UninstallExtensionFromProfileTask extends AbstractExtensionTask impl constructor( readonly extension: ILocalExtension, private readonly profileLocation: URI, - private readonly userDataProfilesService: IUserDataProfilesService, private readonly extensionsProfileScannerService: IExtensionsProfileScannerService, ) { super(); } protected async doRun(token: CancellationToken): Promise { - const promises: Promise[] = []; - promises.push(this.extensionsProfileScannerService.removeExtensionFromProfile(this.extension.identifier, this.profileLocation)); - if (this.extension.isApplicationScoped && this.userDataProfilesService.defaultProfile.extensionsResource) { - promises.push(this.extensionsProfileScannerService.removeExtensionFromProfile(this.extension.identifier, this.userDataProfilesService.defaultProfile.extensionsResource)); - } - await Promise.all(promises); + await this.extensionsProfileScannerService.removeExtensionFromProfile(this.extension.identifier, this.profileLocation); } } diff --git a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts index 720b7ebed1d..f7369b487ad 100644 --- a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts @@ -95,11 +95,11 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe return local; } - protected createInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: InstallOptions): IInstallExtensionTask { + protected doCreateInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: InstallOptions): IInstallExtensionTask { return new InstallExtensionTask(manifest, extension, options, this.webExtensionsScannerService); } - protected createUninstallExtensionTask(extension: ILocalExtension, options: UninstallOptions): IUninstallExtensionTask { + protected doCreateUninstallExtensionTask(extension: ILocalExtension, options: UninstallOptions): IUninstallExtensionTask { return new UninstallExtensionTask(extension, options, this.webExtensionsScannerService); } -- cgit v1.2.3 From c5a92805343a1ff1051646771650e6dbe8fb331a Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Fri, 8 Jul 2022 18:48:09 +0200 Subject: ButtonWithDropdown separator style update (#154109) --- src/vs/base/browser/ui/button/button.css | 9 +++++++-- src/vs/base/browser/ui/button/button.ts | 13 +++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/base/browser/ui/button/button.css b/src/vs/base/browser/ui/button/button.css index 5327fb0e1e3..66e61c3c398 100644 --- a/src/vs/base/browser/ui/button/button.css +++ b/src/vs/base/browser/ui/button/button.css @@ -42,8 +42,13 @@ outline-offset: -1px !important; } -.monaco-button-dropdown > .monaco-dropdown-button { - margin-left: 1px; +.monaco-button-dropdown .monaco-button-dropdown-separator { + padding: 4px 0; +} + +.monaco-button-dropdown .monaco-button-dropdown-separator > div { + height: 100%; + width: 1px; } .monaco-description-button { diff --git a/src/vs/base/browser/ui/button/button.ts b/src/vs/base/browser/ui/button/button.ts index 3187254843b..4ae8b9d6239 100644 --- a/src/vs/base/browser/ui/button/button.ts +++ b/src/vs/base/browser/ui/button/button.ts @@ -247,6 +247,8 @@ export class ButtonWithDropdown extends Disposable implements IButton { private readonly button: Button; private readonly action: Action; private readonly dropdownButton: Button; + private readonly separatorContainer: HTMLDivElement; + private readonly separator: HTMLDivElement; readonly element: HTMLElement; private readonly _onDidClick = this._register(new Emitter()); @@ -263,6 +265,13 @@ export class ButtonWithDropdown extends Disposable implements IButton { this._register(this.button.onDidClick(e => this._onDidClick.fire(e))); this.action = this._register(new Action('primaryAction', this.button.label, undefined, true, async () => this._onDidClick.fire(undefined))); + this.separatorContainer = document.createElement('div'); + this.separatorContainer.classList.add('monaco-button-dropdown-separator'); + + this.separator = document.createElement('div'); + this.separatorContainer.appendChild(this.separator); + this.element.appendChild(this.separatorContainer); + this.dropdownButton = this._register(new Button(this.element, { ...options, title: false, supportIcons: true })); this.dropdownButton.element.title = localize("button dropdown more actions", 'More Actions...'); this.dropdownButton.element.classList.add('monaco-dropdown-button'); @@ -299,6 +308,10 @@ export class ButtonWithDropdown extends Disposable implements IButton { style(styles: IButtonStyles): void { this.button.style(styles); this.dropdownButton.style(styles); + + // Separator + this.separatorContainer.style.backgroundColor = styles.buttonBackground?.toString() ?? ''; + this.separator.style.backgroundColor = styles.buttonForeground?.toString() ?? ''; } focus(): void { -- cgit v1.2.3 From 6f672e5d222bf5c563fdb97b2427afafc015cc62 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 8 Jul 2022 19:07:09 +0200 Subject: scanner service: take profile as input --- .../browser/webExtensionsScannerService.ts | 105 ++++++++++----------- .../common/extensionManagement.ts | 15 ++- .../common/webExtensionManagementService.ts | 63 +++++++++---- .../extensions/browser/extensionService.ts | 7 +- .../extensions/common/abstractExtensionService.ts | 4 +- .../electron-sandbox/electronExtensionService.ts | 5 +- .../test/browser/workbenchTestServices.ts | 7 +- 7 files changed, 118 insertions(+), 88 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts b/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts index 588ca24cc10..bc5e140d42a 100644 --- a/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts +++ b/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IBuiltinExtensionsScannerService, ExtensionType, IExtensionIdentifier, IExtension, IExtensionManifest, TargetPlatform, ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { IBuiltinExtensionsScannerService, ExtensionType, IExtensionIdentifier, IExtension, IExtensionManifest, TargetPlatform } from 'vs/platform/extensions/common/extensions'; import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'; import { IScannedExtension, IWebExtensionsScannerService, ScanOptions } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { isWeb, Language } from 'vs/base/common/platform'; @@ -33,17 +33,16 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { basename } from 'vs/base/common/path'; import { IExtensionStorageService } from 'vs/platform/extensionManagement/common/extensionStorage'; -import { delta, isNonEmptyArray } from 'vs/base/common/arrays'; +import { isNonEmptyArray } from 'vs/base/common/arrays'; import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { IProductService } from 'vs/platform/product/common/productService'; import { validateExtensionManifest } from 'vs/platform/extensions/common/extensionValidator'; import Severity from 'vs/base/common/severity'; import { IStringDictionary } from 'vs/base/common/collections'; -import { DidChangeUserDataProfileEvent, IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; -import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; -import { Emitter } from 'vs/base/common/event'; -import { compare } from 'vs/base/common/strings'; +import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; type GalleryExtensionInfo = { readonly id: string; preRelease?: boolean; migrateStorageFrom?: string }; type ExtensionInfo = { readonly id: string; preRelease: boolean }; @@ -89,9 +88,6 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten private readonly customBuiltinExtensionsCacheResource: URI | undefined = undefined; private readonly resourcesAccessQueueMap = new ResourceMap>(); - private readonly _onDidChangeProfileExtensions = this._register(new Emitter<{ readonly added: IScannedExtension[]; readonly removed: IScannedExtension[] }>()); - readonly onDidChangeProfileExtensions = this._onDidChangeProfileExtensions.event; - constructor( @IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService, @IBuiltinExtensionsScannerService private readonly builtinExtensionsScannerService: IBuiltinExtensionsScannerService, @@ -103,8 +99,8 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten @IExtensionStorageService private readonly extensionStorageService: IExtensionStorageService, @IStorageService private readonly storageService: IStorageService, @IProductService private readonly productService: IProductService, - @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, + @IUriIdentityService private readonly uriIdentityService: IUriIdentityService, @ILifecycleService lifecycleService: ILifecycleService, ) { super(); @@ -115,7 +111,6 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten // Eventually update caches lifecycleService.when(LifecyclePhase.Eventually).then(() => this.updateCaches()); - this._register(userDataProfileService.onDidChangeCurrentProfile(e => e.join(this.whenProfileChanged(e)))); } } @@ -377,7 +372,7 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten return this.readSystemExtensions(); } - async scanUserExtensions(scanOptions?: ScanOptions): Promise { + async scanUserExtensions(profileLocation?: URI, scanOptions?: ScanOptions): Promise { const extensions = new Map(); // Custom builtin extensions defined through `additionalBuiltinExtensions` API @@ -387,7 +382,7 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten } // User Installed extensions - const installedExtensions = await this.scanInstalledExtensions(this.userDataProfileService.currentProfile, scanOptions); + const installedExtensions = await this.scanInstalledExtensions(profileLocation, scanOptions); for (const extension of installedExtensions) { extensions.set(extension.identifier.id.toLowerCase(), extension); } @@ -416,17 +411,17 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten return result; } - async scanExistingExtension(extensionLocation: URI, extensionType: ExtensionType): Promise { + async scanExistingExtension(extensionLocation: URI, extensionType: ExtensionType, profileLocation?: URI): Promise { if (extensionType === ExtensionType.System) { const systemExtensions = await this.scanSystemExtensions(); return systemExtensions.find(e => e.location.toString() === extensionLocation.toString()) || null; } - const userExtensions = await this.scanUserExtensions(); + const userExtensions = await this.scanUserExtensions(profileLocation); return userExtensions.find(e => e.location.toString() === extensionLocation.toString()) || null; } - async scanMetadata(extensionLocation: URI): Promise { - const extension = await this.scanExistingExtension(extensionLocation, ExtensionType.User); + async scanMetadata(extensionLocation: URI, profileLocation?: URI): Promise { + const extension = await this.scanExistingExtension(extensionLocation, ExtensionType.User, profileLocation); return extension?.metadata; } @@ -443,26 +438,38 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten return null; } - async addExtensionFromGallery(galleryExtension: IGalleryExtension, metadata?: Metadata): Promise { + async addExtensionFromGallery(galleryExtension: IGalleryExtension, metadata: Metadata, profileLocation?: URI): Promise { const webExtension = await this.toWebExtensionFromGallery(galleryExtension, metadata); - return this.addWebExtension(webExtension); + return this.addWebExtension(webExtension, profileLocation); } - async addExtension(location: URI, metadata?: Metadata): Promise { + async addExtension(location: URI, metadata: Metadata, profileLocation?: URI): Promise { const webExtension = await this.toWebExtension(location, undefined, undefined, undefined, undefined, undefined, metadata); - return this.addWebExtension(webExtension); + return this.addWebExtension(webExtension, profileLocation); } - async removeExtension(extension: IScannedExtension): Promise { - const profile = extension.metadata?.isApplicationScoped ? this.userDataProfilesService.defaultProfile : this.userDataProfileService.currentProfile; - await this.writeInstalledExtensions(profile, installedExtensions => installedExtensions.filter(installedExtension => !areSameExtensions(installedExtension.identifier, extension.identifier))); + async removeExtension(extension: IScannedExtension, profileLocation?: URI): Promise { + await this.writeInstalledExtensions(profileLocation, installedExtensions => installedExtensions.filter(installedExtension => !areSameExtensions(installedExtension.identifier, extension.identifier))); } - private async addWebExtension(webExtension: IWebExtension): Promise { + async copyExtensions(fromProfileLocation: URI, toProfileLocation: URI, filter: (extension: IScannedExtension) => boolean): Promise { + const extensionsToCopy: IWebExtension[] = []; + const fromWebExtensions = await this.readInstalledExtensions(fromProfileLocation); + await Promise.all(fromWebExtensions.map(async webExtension => { + const scannedExtension = await this.toScannedExtension(webExtension, false); + if (filter(scannedExtension)) { + extensionsToCopy.push(webExtension); + } + })); + if (extensionsToCopy.length) { + await this.addToInstalledExtensions(extensionsToCopy, toProfileLocation); + } + } + + private async addWebExtension(webExtension: IWebExtension, profileLocation?: URI): Promise { const isSystem = !!(await this.scanSystemExtensions()).find(e => areSameExtensions(e.identifier, webExtension.identifier)); const isBuiltin = !!webExtension.metadata?.isBuiltin; const extension = await this.toScannedExtension(webExtension, isBuiltin); - const profile = webExtension.metadata?.isApplicationScoped ? this.userDataProfilesService.defaultProfile : this.userDataProfileService.currentProfile; if (isSystem) { await this.writeSystemExtensionsCache(systemExtensions => { @@ -483,21 +490,21 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten return customBuiltinExtensions; }); - const installedExtensions = await this.readInstalledExtensions(profile); + const installedExtensions = await this.readInstalledExtensions(profileLocation); // Also add to installed extensions if it is installed to update its version if (installedExtensions.some(e => areSameExtensions(e.identifier, webExtension.identifier))) { - await this.addToInstalledExtensions([webExtension], profile); + await this.addToInstalledExtensions([webExtension], profileLocation); } return extension; } // Add to installed extensions - await this.addToInstalledExtensions([webExtension], profile); + await this.addToInstalledExtensions([webExtension], profileLocation); return extension; } - private async addToInstalledExtensions(webExtensions: IWebExtension[], profile: IUserDataProfile): Promise { - await this.writeInstalledExtensions(profile, installedExtensions => { + private async addToInstalledExtensions(webExtensions: IWebExtension[], profileLocation?: URI): Promise { + await this.writeInstalledExtensions(profileLocation, installedExtensions => { // Remove the existing extension to avoid duplicates installedExtensions = installedExtensions.filter(installedExtension => webExtensions.some(extension => !areSameExtensions(installedExtension.identifier, extension.identifier))); installedExtensions.push(...webExtensions); @@ -505,15 +512,15 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten }); } - private async scanInstalledExtensions(profile: IUserDataProfile, scanOptions?: ScanOptions): Promise { - let installedExtensions = await this.readInstalledExtensions(profile); + private async scanInstalledExtensions(profileLocation?: URI, scanOptions?: ScanOptions): Promise { + let installedExtensions = await this.readInstalledExtensions(profileLocation); // If current profile is not a default profile, then add the application extensions to the list - if (!profile.isDefault) { + if (this.userDataProfilesService.defaultProfile.extensionsResource && !this.uriIdentityService.extUri.isEqual(profileLocation, this.userDataProfilesService.defaultProfile.extensionsResource)) { // Remove application extensions from the non default profile installedExtensions = installedExtensions.filter(i => !i.metadata?.isApplicationScoped); // Add application extensions from the default profile to the list - const defaultProfileExtensions = await this.readInstalledExtensions(this.userDataProfilesService.defaultProfile); + const defaultProfileExtensions = await this.readInstalledExtensions(this.userDataProfilesService.defaultProfile.extensionsResource); installedExtensions.push(...defaultProfileExtensions.filter(i => i.metadata?.isApplicationScoped)); } @@ -713,15 +720,15 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten return this._migratePackageNLSUrisPromise; } - private async readInstalledExtensions(profile: IUserDataProfile): Promise { - if (profile.isDefault) { + private async readInstalledExtensions(profileLocation?: URI): Promise { + if (this.uriIdentityService.extUri.isEqual(profileLocation, this.userDataProfilesService.defaultProfile.extensionsResource)) { await this.migratePackageNLSUris(); } - return this.withWebExtensions(profile.extensionsResource); + return this.withWebExtensions(profileLocation); } - private writeInstalledExtensions(profile: IUserDataProfile, updateFn: (extensions: IWebExtension[]) => IWebExtension[]): Promise { - return this.withWebExtensions(profile.extensionsResource, updateFn); + private writeInstalledExtensions(profileLocation: URI | undefined, updateFn: (extensions: IWebExtension[]) => IWebExtension[]): Promise { + return this.withWebExtensions(profileLocation, updateFn); } private readCustomBuiltinExtensionsCache(): Promise { @@ -819,7 +826,6 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten } private registerActions(): void { - const that = this; this._register(registerAction2(class extends Action2 { constructor() { super({ @@ -831,24 +837,13 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten }); } run(serviceAccessor: ServicesAccessor): void { - serviceAccessor.get(IEditorService).openEditor({ resource: that.userDataProfileService.currentProfile.extensionsResource }); + const editorService = serviceAccessor.get(IEditorService); + const userDataProfileService = serviceAccessor.get(IUserDataProfileService); + editorService.openEditor({ resource: userDataProfileService.currentProfile.extensionsResource }); } })); } - private async whenProfileChanged(e: DidChangeUserDataProfileEvent): Promise { - if (e.preserveData) { - const extensions = (await this.readInstalledExtensions(e.previous)).filter(e => !e.metadata?.isApplicationScoped); /* remove application scoped extensions */ - await this.addToInstalledExtensions(extensions, e.profile); - } else { - const oldExtensions = await this.scanInstalledExtensions(e.previous); - const newExtensions = await this.scanInstalledExtensions(e.profile); - const { added, removed } = delta(oldExtensions, newExtensions, (a, b) => compare(`${ExtensionIdentifier.toKey(a.identifier.id)}@${a.manifest.version}`, `${ExtensionIdentifier.toKey(b.identifier.id)}@${b.manifest.version}`)); - if (added.length || removed.length) { - this._onDidChangeProfileExtensions.fire({ added, removed }); - } - } - } } registerSingleton(IWebExtensionsScannerService, WebExtensionsScannerService); diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts index 668f143421e..1cad71d1c3a 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts @@ -157,17 +157,16 @@ export const IWebExtensionsScannerService = createDecorator; - scanSystemExtensions(): Promise; - scanUserExtensions(options?: ScanOptions): Promise; + scanUserExtensions(profileLocation: URI | undefined, options?: ScanOptions): Promise; scanExtensionsUnderDevelopment(): Promise; - scanExistingExtension(extensionLocation: URI, extensionType: ExtensionType): Promise; + scanExistingExtension(extensionLocation: URI, extensionType: ExtensionType, profileLocation: URI | undefined): Promise; - addExtension(location: URI, metadata?: Metadata): Promise; - addExtensionFromGallery(galleryExtension: IGalleryExtension, metadata?: Metadata): Promise; - removeExtension(extension: IScannedExtension, version?: string): Promise; + addExtension(location: URI, metadata: Metadata, profileLocation: URI | undefined): Promise; + addExtensionFromGallery(galleryExtension: IGalleryExtension, metadata: Metadata, profileLocation: URI | undefined): Promise; + removeExtension(extension: IScannedExtension, profileLocation: URI | undefined): Promise; + copyExtensions(fromProfileLocation: URI, toProfileLocation: URI, filter: (extension: IScannedExtension) => boolean): Promise; - scanMetadata(extensionLocation: URI): Promise; + scanMetadata(extensionLocation: URI, profileLocation: URI | undefined): Promise; scanExtensionManifest(extensionLocation: URI): Promise; } diff --git a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts index f7369b487ad..23413b1b130 100644 --- a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts @@ -3,10 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ExtensionType, IExtension, IExtensionIdentifier, IExtensionManifest, TargetPlatform } from 'vs/platform/extensions/common/extensions'; -import { ILocalExtension, IGalleryExtension, IGalleryMetadata, InstallOperation, IExtensionGalleryService, InstallOptions, Metadata, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { ExtensionIdentifier, ExtensionType, IExtension, IExtensionIdentifier, IExtensionManifest, TargetPlatform } from 'vs/platform/extensions/common/extensions'; +import { ILocalExtension, IGalleryExtension, IGalleryMetadata, InstallOperation, IExtensionGalleryService, Metadata, ServerInstallOptions, ServerUninstallOptions, IServerExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { URI } from 'vs/base/common/uri'; -import { Event } from 'vs/base/common/event'; +import { Emitter } from 'vs/base/common/event'; import { areSameExtensions, getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IProfileAwareExtensionManagementService, IScannedExtension, IWebExtensionsScannerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { ILogService } from 'vs/platform/log/common/log'; @@ -16,12 +16,17 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService'; import { IProductService } from 'vs/platform/product/common/productService'; import { isBoolean, isUndefined } from 'vs/base/common/types'; +import { DidChangeUserDataProfileEvent, IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { delta } from 'vs/base/common/arrays'; +import { compare } from 'vs/base/common/strings'; +import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; -export class WebExtensionManagementService extends AbstractExtensionManagementService implements IProfileAwareExtensionManagementService { +export class WebExtensionManagementService extends AbstractExtensionManagementService implements IProfileAwareExtensionManagementService, IServerExtensionManagementService { declare readonly _serviceBrand: undefined; - readonly onDidChangeProfileExtensions: Event<{ readonly added: ILocalExtension[]; readonly removed: ILocalExtension[] }>; + private readonly _onDidChangeProfileExtensions = this._register(new Emitter<{ readonly added: ILocalExtension[]; readonly removed: ILocalExtension[] }>()); + readonly onDidChangeProfileExtensions = this._onDidChangeProfileExtensions.event; constructor( @IExtensionGalleryService extensionGalleryService: IExtensionGalleryService, @@ -29,10 +34,12 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe @ILogService logService: ILogService, @IWebExtensionsScannerService private readonly webExtensionsScannerService: IWebExtensionsScannerService, @IExtensionManifestPropertiesService private readonly extensionManifestPropertiesService: IExtensionManifestPropertiesService, + @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, @IProductService productService: IProductService, + @IUserDataProfilesService userDataProfilesService: IUserDataProfilesService, ) { - super(extensionGalleryService, telemetryService, logService, productService); - this.onDidChangeProfileExtensions = Event.map(this.webExtensionsScannerService.onDidChangeProfileExtensions, e => ({ added: e.added.map(a => toLocalExtension(a)), removed: e.removed.map(a => toLocalExtension(a)) })); + super(extensionGalleryService, telemetryService, logService, productService, userDataProfilesService); + this._register(userDataProfileService.onDidChangeCurrentProfile(e => e.join(this.whenProfileChanged(e)))); } async getTargetPlatform(): Promise { @@ -56,13 +63,13 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe extensions.push(...systemExtensions); } if (type === undefined || type === ExtensionType.User) { - const userExtensions = await this.webExtensionsScannerService.scanUserExtensions(); + const userExtensions = await this.webExtensionsScannerService.scanUserExtensions(this.userDataProfileService.currentProfile.extensionsResource); extensions.push(...userExtensions); } return Promise.all(extensions.map(e => toLocalExtension(e))); } - async install(location: URI, options: InstallOptions = {}): Promise { + async install(location: URI, options: ServerInstallOptions = {}): Promise { this.logService.trace('ExtensionManagementService#install', location.toString()); const manifest = await this.webExtensionsScannerService.scanExtensionManifest(location); if (!manifest) { @@ -72,7 +79,7 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe } getMetadata(extension: ILocalExtension): Promise { - return this.webExtensionsScannerService.scanMetadata(extension.location); + return this.webExtensionsScannerService.scanMetadata(extension.location, this.userDataProfileService.currentProfile.extensionsResource); } protected override async getCompatibleVersion(extension: IGalleryExtension, sameVersion: boolean, includePreRelease: boolean): Promise { @@ -95,11 +102,11 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe return local; } - protected doCreateInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: InstallOptions): IInstallExtensionTask { + protected doCreateInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions): IInstallExtensionTask { return new InstallExtensionTask(manifest, extension, options, this.webExtensionsScannerService); } - protected doCreateUninstallExtensionTask(extension: ILocalExtension, options: UninstallOptions): IUninstallExtensionTask { + protected doCreateUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions): IUninstallExtensionTask { return new UninstallExtensionTask(extension, options, this.webExtensionsScannerService); } @@ -107,6 +114,24 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe unzip(zipLocation: URI): Promise { throw new Error('unsupported'); } getManifest(vsix: URI): Promise { throw new Error('unsupported'); } updateExtensionScope(): Promise { throw new Error('unsupported'); } + + private async whenProfileChanged(e: DidChangeUserDataProfileEvent): Promise { + const previousProfileLocation = e.previous.extensionsResource; + const currentProfileLocation = e.profile.extensionsResource; + if (!previousProfileLocation || !currentProfileLocation) { + throw new Error('This should not happen'); + } + if (e.preserveData) { + await this.webExtensionsScannerService.copyExtensions(previousProfileLocation, currentProfileLocation, e => !e.metadata?.isApplicationScoped); + } else { + const oldExtensions = await this.webExtensionsScannerService.scanUserExtensions(previousProfileLocation); + const newExtensions = await this.webExtensionsScannerService.scanUserExtensions(currentProfileLocation); + const { added, removed } = delta(oldExtensions, newExtensions, (a, b) => compare(`${ExtensionIdentifier.toKey(a.identifier.id)}@${a.manifest.version}`, `${ExtensionIdentifier.toKey(b.identifier.id)}@${b.manifest.version}`)); + if (added.length || removed.length) { + this._onDidChangeProfileExtensions.fire({ added: added.map(e => toLocalExtension(e)), removed: removed.map(e => toLocalExtension(e)) }); + } + } + } } function toLocalExtension(extension: IExtension): ILocalExtension { @@ -126,7 +151,7 @@ function toLocalExtension(extension: IExtension): ILocalExtension { }; } -function getMetadata(options?: InstallOptions, existingExtension?: IExtension): Metadata { +function getMetadata(options?: ServerInstallOptions, existingExtension?: IExtension): Metadata { const metadata: Metadata = { ...((existingExtension)?.metadata || {}) }; metadata.isMachineScoped = options?.isMachineScoped || metadata.isMachineScoped; return metadata; @@ -143,7 +168,7 @@ class InstallExtensionTask extends AbstractExtensionTask<{ local: ILocalExtensio constructor( manifest: IExtensionManifest, private readonly extension: URI | IGalleryExtension, - private readonly options: InstallOptions, + private readonly options: ServerInstallOptions, private readonly webExtensionsScannerService: IWebExtensionsScannerService, ) { super(); @@ -152,7 +177,7 @@ class InstallExtensionTask extends AbstractExtensionTask<{ local: ILocalExtensio } protected async doRun(token: CancellationToken): Promise<{ local: ILocalExtension; metadata: Metadata }> { - const userExtensions = await this.webExtensionsScannerService.scanUserExtensions(); + const userExtensions = await this.webExtensionsScannerService.scanUserExtensions(this.options.profileLocation); const existingExtension = userExtensions.find(e => areSameExtensions(e.identifier, this.identifier)); if (existingExtension) { this._operation = InstallOperation.Update; @@ -174,8 +199,8 @@ class InstallExtensionTask extends AbstractExtensionTask<{ local: ILocalExtensio : metadata?.preRelease /* Respect the existing pre-release flag if it was set */); } - const scannedExtension = URI.isUri(this.extension) ? await this.webExtensionsScannerService.addExtension(this.extension, metadata) - : await this.webExtensionsScannerService.addExtensionFromGallery(this.extension, metadata); + const scannedExtension = URI.isUri(this.extension) ? await this.webExtensionsScannerService.addExtension(this.extension, metadata, this.options.profileLocation) + : await this.webExtensionsScannerService.addExtensionFromGallery(this.extension, metadata, this.options.profileLocation); return { local: toLocalExtension(scannedExtension), metadata }; } } @@ -184,13 +209,13 @@ class UninstallExtensionTask extends AbstractExtensionTask implements IUni constructor( readonly extension: ILocalExtension, - options: UninstallOptions, + private readonly options: ServerUninstallOptions, private readonly webExtensionsScannerService: IWebExtensionsScannerService, ) { super(); } protected doRun(token: CancellationToken): Promise { - return this.webExtensionsScannerService.removeExtension(this.extension); + return this.webExtensionsScannerService.removeExtension(this.extension, this.options.profileLocation); } } diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts index acdf6ca2308..8c48d48d131 100644 --- a/src/vs/workbench/services/extensions/browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/browser/extensionService.ts @@ -30,6 +30,7 @@ import { IExtensionManifestPropertiesService } from 'vs/workbench/services/exten import { IUserDataInitializationService } from 'vs/workbench/services/userData/browser/userDataInit'; import { IAutomatedWindow } from 'vs/platform/log/browser/log'; import { ILogService } from 'vs/platform/log/common/log'; +import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; export class ExtensionService extends AbstractExtensionService implements IExtensionService { @@ -54,6 +55,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten @ILifecycleService lifecycleService: ILifecycleService, @IRemoteAuthorityResolverService private readonly _remoteAuthorityResolverService: IRemoteAuthorityResolverService, @IUserDataInitializationService private readonly _userDataInitializationService: IUserDataInitializationService, + @IUserDataProfileService userDataProfileService: IUserDataProfileService, ) { super( instantiationService, @@ -70,7 +72,8 @@ export class ExtensionService extends AbstractExtensionService implements IExten webExtensionsScannerService, logService, remoteAgentService, - lifecycleService + lifecycleService, + userDataProfileService ); // Initialize installed extensions first and do it only after workbench is ready @@ -92,7 +95,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten return this._remoteAgentService.scanSingleExtension(extension.location, extension.type === ExtensionType.System); } - const scannedExtension = await this._webExtensionsScannerService.scanExistingExtension(extension.location, extension.type); + const scannedExtension = await this._webExtensionsScannerService.scanExistingExtension(extension.location, extension.type, this._userDataProfileService.currentProfile.extensionsResource); if (scannedExtension) { return toExtensionDescription(scannedExtension); } diff --git a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts index 76589d23182..057e5467ee9 100644 --- a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts @@ -37,6 +37,7 @@ import { ApiProposalName, allApiProposals } from 'vs/workbench/services/extensio import { ILogService } from 'vs/platform/log/common/log'; import { IExtensionHostExitInfo, IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle'; +import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; const hasOwnProperty = Object.hasOwnProperty; const NO_OP_VOID_PROMISE = Promise.resolve(undefined); @@ -189,6 +190,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx @ILogService protected readonly _logService: ILogService, @IRemoteAgentService protected readonly _remoteAgentService: IRemoteAgentService, @ILifecycleService private readonly _lifecycleService: ILifecycleService, + @IUserDataProfileService protected readonly _userDataProfileService: IUserDataProfileService, ) { super(); @@ -1331,7 +1333,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx try { await Promise.all([ this._webExtensionsScannerService.scanSystemExtensions().then(extensions => system.push(...extensions.map(e => toExtensionDescription(e)))), - this._webExtensionsScannerService.scanUserExtensions({ skipInvalidExtensions: true }).then(extensions => user.push(...extensions.map(e => toExtensionDescription(e)))), + this._webExtensionsScannerService.scanUserExtensions(this._userDataProfileService.currentProfile.extensionsResource, { skipInvalidExtensions: true }).then(extensions => user.push(...extensions.map(e => toExtensionDescription(e)))), this._webExtensionsScannerService.scanExtensionsUnderDevelopment().then(extensions => development.push(...extensions.map(e => toExtensionDescription(e, true)))) ]); } catch (error) { diff --git a/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts b/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts index 3c267c40962..87e9f45b545 100644 --- a/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts +++ b/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts @@ -48,6 +48,7 @@ import { isCI } from 'vs/base/common/platform'; import { IResolveAuthorityErrorResult } from 'vs/workbench/services/extensions/common/extensionHostProxy'; import { URI } from 'vs/base/common/uri'; import { ILocalProcessExtensionHostDataProvider, ILocalProcessExtensionHostInitData, SandboxLocalProcessExtensionHost } from 'vs/workbench/services/extensions/electron-sandbox/localProcessExtensionHost'; +import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; export abstract class ElectronExtensionService extends AbstractExtensionService implements IExtensionService { @@ -80,6 +81,7 @@ export abstract class ElectronExtensionService extends AbstractExtensionService @IRemoteExplorerService private readonly _remoteExplorerService: IRemoteExplorerService, @IExtensionGalleryService private readonly _extensionGalleryService: IExtensionGalleryService, @IWorkspaceTrustManagementService private readonly _workspaceTrustManagementService: IWorkspaceTrustManagementService, + @IUserDataProfileService userDataProfileService: IUserDataProfileService, ) { super( instantiationService, @@ -96,7 +98,8 @@ export abstract class ElectronExtensionService extends AbstractExtensionService webExtensionsScannerService, logService, remoteAgentService, - lifecycleService + lifecycleService, + userDataProfileService ); [this._enableLocalWebWorker, this._lazyLocalWebWorker] = this._isLocalWebWorkerEnabled(); diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index ac262dac6ce..b75b42f8df5 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -163,7 +163,7 @@ import { ILayoutOffsetInfo } from 'vs/platform/layout/browser/layoutService'; import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; -import { EnablementState, IExtensionManagementServer, IScannedExtension, IWebExtensionsScannerService, IWorkbenchExtensionEnablementService, IWorkbenchExtensionManagementService, ScanOptions } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { EnablementState, IExtensionManagementServer, IScannedExtension, IWebExtensionsScannerService, IWorkbenchExtensionEnablementService, IWorkbenchExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { InstallVSIXOptions, ILocalExtension, IGalleryExtension, InstallOptions, IExtensionIdentifier, UninstallOptions, IExtensionsControlManifest, IGalleryMetadata, IExtensionManagementParticipant } from 'vs/platform/extensionManagement/common/extensionManagement'; export function createFileEditorInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { @@ -2003,8 +2003,11 @@ export class TestWorkbenchExtensionManagementService implements IWorkbenchExtens export class TestWebExtensionsScannerService implements IWebExtensionsScannerService { _serviceBrand: undefined; async scanSystemExtensions(): Promise { return []; } - async scanUserExtensions(options?: ScanOptions | undefined): Promise { return []; } + async scanUserExtensions(): Promise { return []; } async scanExtensionsUnderDevelopment(): Promise { return []; } + async copyExtensions(): Promise { + throw new Error('Method not implemented.'); + } scanExistingExtension(extensionLocation: URI, extensionType: ExtensionType): Promise { throw new Error('Method not implemented.'); } -- cgit v1.2.3 From 8f8a5740bf1927fb12624d47811db803db5a505c Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Jul 2022 10:37:00 -0700 Subject: Run recent command: Collapse $HOME into ~ Fixes #153109 --- .../platform/terminal/common/terminalEnvironment.ts | 19 +++++++++++++++++++ .../contrib/terminal/browser/terminalInstance.ts | 4 ++-- 2 files changed, 21 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminalEnvironment.ts b/src/vs/platform/terminal/common/terminalEnvironment.ts index 66b5ad31a3f..eb2ff9d432a 100644 --- a/src/vs/platform/terminal/common/terminalEnvironment.ts +++ b/src/vs/platform/terminal/common/terminalEnvironment.ts @@ -12,3 +12,22 @@ export function escapeNonWindowsPath(path: string): string { newPath = newPath.replace(bannedChars, ''); return `'${newPath}'`; } + +/** + * Collapses the user's home directory into `~` if it exists within the path, this gives a shorter + * path that is more suitable within the context of a terminal. + */ +export function getTildePath(path: string | undefined, userHome: string | undefined, separator: string): string { + if (!path) { + return ''; + } + if (!userHome) { + return path; + } + const normalizedPath = path.replace(/\\/g, '/\//').toLowerCase(); + const normalizedUserHome = userHome.replace(/\\/g, '/\//').toLowerCase(); + if (!normalizedPath.includes(normalizedUserHome)) { + return path; + } + return `~${separator}${path.slice(userHome.length)}`; +} diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index e4187f6ab3c..18e96129340 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -47,7 +47,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITerminalCommand, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; import { TerminalCapabilityStoreMultiplexer } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore'; import { IProcessDataEvent, IProcessPropertyMap, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, PosixShellType, ProcessPropertyType, TerminalIcon, TerminalLocation, TerminalSettingId, TerminalShellType, TitleEventSource, WindowsShellType } from 'vs/platform/terminal/common/terminal'; -import { escapeNonWindowsPath } from 'vs/platform/terminal/common/terminalEnvironment'; +import { escapeNonWindowsPath, getTildePath } from 'vs/platform/terminal/common/terminalEnvironment'; import { activeContrastBorder, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground } from 'vs/platform/theme/common/colorRegistry'; import { IColorTheme, ICssStyleCollector, IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService'; import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; @@ -851,7 +851,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { if (label.length === 0 || commandMap.has(label)) { continue; } - let description = `${entry.cwd}`; + let description = getTildePath(entry.cwd, this._userHome, this._processManager?.os === OperatingSystem.Windows ? '\\' : '/'); if (entry.exitCode) { // Since you cannot get the last command's exit code on pwsh, just whether it failed // or not, -1 is treated specially as simply failed -- cgit v1.2.3 From 60afef73160f3114bbc5c20a0ed3c0f444bc406a Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 8 Jul 2022 19:42:42 +0200 Subject: fix tests --- .../services/extensions/test/browser/extensionService.test.ts | 7 ++++++- .../services/userDataProfile/common/userDataProfileService.ts | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts b/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts index 18d684cacaa..74a3cac60bb 100644 --- a/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts +++ b/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts @@ -33,6 +33,9 @@ import { TestEnvironmentService, TestFileService, TestLifecycleService, TestRemo import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; import { mock } from 'vs/base/test/common/mock'; import { IExtensionHostManager } from 'vs/workbench/services/extensions/common/extensionHostManager'; +import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; +import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; suite('BrowserExtensionService', () => { test('pickRunningLocation', () => { @@ -175,7 +178,9 @@ suite('ExtensionService', () => { [IWorkbenchExtensionEnablementService, TestWorkbenchExtensionEnablementService], [ITelemetryService, NullTelemetryService], [IEnvironmentService, TestEnvironmentService], - [IWorkspaceTrustEnablementService, WorkspaceTrustEnablementService] + [IWorkspaceTrustEnablementService, WorkspaceTrustEnablementService], + [IUserDataProfilesService, UserDataProfilesService], + [IUserDataProfileService, UserDataProfileService], ]); extService = instantiationService.get(IExtensionService); }); diff --git a/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts b/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts index 57c6e4161a2..e03387a0b29 100644 --- a/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts +++ b/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts @@ -19,7 +19,10 @@ export class UserDataProfileService extends Disposable implements IUserDataProfi private _currentProfile: IUserDataProfile; get currentProfile(): IUserDataProfile { return this._currentProfile; } - constructor(currentProfile: IUserDataProfile, userDataProfilesService: IUserDataProfilesService) { + constructor( + currentProfile: IUserDataProfile, + @IUserDataProfilesService userDataProfilesService: IUserDataProfilesService + ) { super(); this._currentProfile = currentProfile; this._register(userDataProfilesService.onDidChangeProfiles(() => { -- cgit v1.2.3 From aba83292959ac69db22cf2e7b3ceb32de2b766eb Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Jul 2022 10:44:54 -0700 Subject: Add tests, improve name --- .../terminal/common/terminalEnvironment.ts | 2 +- .../test/common/terminalEnvironment.test.ts | 32 ++++++++++++++++++++++ .../contrib/terminal/browser/terminalInstance.ts | 4 +-- 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 src/vs/platform/terminal/test/common/terminalEnvironment.test.ts (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminalEnvironment.ts b/src/vs/platform/terminal/common/terminalEnvironment.ts index eb2ff9d432a..4a6799454f4 100644 --- a/src/vs/platform/terminal/common/terminalEnvironment.ts +++ b/src/vs/platform/terminal/common/terminalEnvironment.ts @@ -17,7 +17,7 @@ export function escapeNonWindowsPath(path: string): string { * Collapses the user's home directory into `~` if it exists within the path, this gives a shorter * path that is more suitable within the context of a terminal. */ -export function getTildePath(path: string | undefined, userHome: string | undefined, separator: string): string { +export function collapseTildePath(path: string | undefined, userHome: string | undefined, separator: string): string { if (!path) { return ''; } diff --git a/src/vs/platform/terminal/test/common/terminalEnvironment.test.ts b/src/vs/platform/terminal/test/common/terminalEnvironment.test.ts new file mode 100644 index 00000000000..80a717f28ee --- /dev/null +++ b/src/vs/platform/terminal/test/common/terminalEnvironment.test.ts @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { strictEqual } from 'assert'; +import { collapseTildePath } from 'vs/platform/terminal/common/terminalEnvironment'; + +suite('terminalEnvironment', () => { + suite('collapseTildePath', () => { + test('should return empty string for a falsy path', () => { + strictEqual(collapseTildePath('', '/foo', '/'), ''); + strictEqual(collapseTildePath(undefined, '/foo', '/'), ''); + }); + test('should return path for a falsy user home', () => { + strictEqual(collapseTildePath('/foo', '', '/'), '/foo'); + strictEqual(collapseTildePath('/foo', undefined, '/'), '/foo'); + }); + test('should not collapse when user home isn\'t present', () => { + strictEqual(collapseTildePath('/foo', '/bar', '/'), '/foo'); + strictEqual(collapseTildePath('c:\\foo', 'C:\\bar', '\\'), 'C:\\foo'); + }); + test('should collapse with Windows separators', () => { + strictEqual(collapseTildePath('/foo/bar', '/foo', '/'), '~/bar'); + strictEqual(collapseTildePath('/foo/bar/baz', '/foo', '/'), '~/bar/baz'); + }); + test('should collapse with Posix separators', () => { + strictEqual(collapseTildePath('C:\\foo\\bar', 'C:\\foo', '\\'), '~\\bar'); + strictEqual(collapseTildePath('C:\\foo\\bar\\baz', 'C:\\foo', '\\'), '~\\bar\\baz'); + }); + }); +}); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 18e96129340..408e3b14ce5 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -47,7 +47,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITerminalCommand, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; import { TerminalCapabilityStoreMultiplexer } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore'; import { IProcessDataEvent, IProcessPropertyMap, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, PosixShellType, ProcessPropertyType, TerminalIcon, TerminalLocation, TerminalSettingId, TerminalShellType, TitleEventSource, WindowsShellType } from 'vs/platform/terminal/common/terminal'; -import { escapeNonWindowsPath, getTildePath } from 'vs/platform/terminal/common/terminalEnvironment'; +import { escapeNonWindowsPath, collapseTildePath } from 'vs/platform/terminal/common/terminalEnvironment'; import { activeContrastBorder, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground } from 'vs/platform/theme/common/colorRegistry'; import { IColorTheme, ICssStyleCollector, IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService'; import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; @@ -851,7 +851,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { if (label.length === 0 || commandMap.has(label)) { continue; } - let description = getTildePath(entry.cwd, this._userHome, this._processManager?.os === OperatingSystem.Windows ? '\\' : '/'); + let description = collapseTildePath(entry.cwd, this._userHome, this._processManager?.os === OperatingSystem.Windows ? '\\' : '/'); if (entry.exitCode) { // Since you cannot get the last command's exit code on pwsh, just whether it failed // or not, -1 is treated specially as simply failed -- cgit v1.2.3 From 2b0eaed1f719d5df1a2623604886567ae9064f43 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Jul 2022 10:48:05 -0700 Subject: Move test implementations into correct test names --- src/vs/platform/terminal/test/common/terminalEnvironment.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/test/common/terminalEnvironment.test.ts b/src/vs/platform/terminal/test/common/terminalEnvironment.test.ts index 80a717f28ee..9975be14fd5 100644 --- a/src/vs/platform/terminal/test/common/terminalEnvironment.test.ts +++ b/src/vs/platform/terminal/test/common/terminalEnvironment.test.ts @@ -21,12 +21,12 @@ suite('terminalEnvironment', () => { strictEqual(collapseTildePath('c:\\foo', 'C:\\bar', '\\'), 'C:\\foo'); }); test('should collapse with Windows separators', () => { - strictEqual(collapseTildePath('/foo/bar', '/foo', '/'), '~/bar'); - strictEqual(collapseTildePath('/foo/bar/baz', '/foo', '/'), '~/bar/baz'); - }); - test('should collapse with Posix separators', () => { strictEqual(collapseTildePath('C:\\foo\\bar', 'C:\\foo', '\\'), '~\\bar'); strictEqual(collapseTildePath('C:\\foo\\bar\\baz', 'C:\\foo', '\\'), '~\\bar\\baz'); }); + test('should collapse with Posix separators', () => { + strictEqual(collapseTildePath('/foo/bar', '/foo', '/'), '~/bar'); + strictEqual(collapseTildePath('/foo/bar/baz', '/foo', '/'), '~/bar/baz'); + }); }); }); -- cgit v1.2.3 From 4dd384b66ea38521885030b9476be534f23f1e26 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Jul 2022 11:14:42 -0700 Subject: Add collapse tilde tests, fix edge cases --- src/vs/platform/terminal/common/terminalEnvironment.ts | 10 +++++++--- .../platform/terminal/test/common/terminalEnvironment.test.ts | 10 +++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminalEnvironment.ts b/src/vs/platform/terminal/common/terminalEnvironment.ts index 4a6799454f4..1d24a24f60d 100644 --- a/src/vs/platform/terminal/common/terminalEnvironment.ts +++ b/src/vs/platform/terminal/common/terminalEnvironment.ts @@ -24,10 +24,14 @@ export function collapseTildePath(path: string | undefined, userHome: string | u if (!userHome) { return path; } - const normalizedPath = path.replace(/\\/g, '/\//').toLowerCase(); - const normalizedUserHome = userHome.replace(/\\/g, '/\//').toLowerCase(); + // Trim the trailing separator from the end if it exists + if (userHome.match(/[\/\\]$/)) { + userHome = userHome.slice(0, userHome.length - 1); + } + const normalizedPath = path.replace(/\\/g, '/').toLowerCase(); + const normalizedUserHome = userHome.replace(/\\/g, '/').toLowerCase(); if (!normalizedPath.includes(normalizedUserHome)) { return path; } - return `~${separator}${path.slice(userHome.length)}`; + return `~${separator}${path.slice(userHome.length + 1)}`; } diff --git a/src/vs/platform/terminal/test/common/terminalEnvironment.test.ts b/src/vs/platform/terminal/test/common/terminalEnvironment.test.ts index 9975be14fd5..2c58f9ec1fd 100644 --- a/src/vs/platform/terminal/test/common/terminalEnvironment.test.ts +++ b/src/vs/platform/terminal/test/common/terminalEnvironment.test.ts @@ -18,15 +18,23 @@ suite('terminalEnvironment', () => { }); test('should not collapse when user home isn\'t present', () => { strictEqual(collapseTildePath('/foo', '/bar', '/'), '/foo'); - strictEqual(collapseTildePath('c:\\foo', 'C:\\bar', '\\'), 'C:\\foo'); + strictEqual(collapseTildePath('C:\\foo', 'C:\\bar', '\\'), 'C:\\foo'); }); test('should collapse with Windows separators', () => { strictEqual(collapseTildePath('C:\\foo\\bar', 'C:\\foo', '\\'), '~\\bar'); + strictEqual(collapseTildePath('C:\\foo\\bar', 'C:\\foo\\', '\\'), '~\\bar'); + strictEqual(collapseTildePath('C:\\foo\\bar\\baz', 'C:\\foo\\', '\\'), '~\\bar\\baz'); strictEqual(collapseTildePath('C:\\foo\\bar\\baz', 'C:\\foo', '\\'), '~\\bar\\baz'); }); + test('should collapse mixed case with Windows separators', () => { + strictEqual(collapseTildePath('c:\\foo\\bar', 'C:\\foo', '\\'), '~\\bar'); + strictEqual(collapseTildePath('C:\\foo\\bar\\baz', 'c:\\foo', '\\'), '~\\bar\\baz'); + }); test('should collapse with Posix separators', () => { strictEqual(collapseTildePath('/foo/bar', '/foo', '/'), '~/bar'); + strictEqual(collapseTildePath('/foo/bar', '/foo/', '/'), '~/bar'); strictEqual(collapseTildePath('/foo/bar/baz', '/foo', '/'), '~/bar/baz'); + strictEqual(collapseTildePath('/foo/bar/baz', '/foo/', '/'), '~/bar/baz'); }); }); }); -- cgit v1.2.3 From e6a60c37d705a25d3875f2e89c5ad551fd846cd9 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Fri, 8 Jul 2022 11:56:58 -0700 Subject: Use `idToken` for edit sessions (#154534) --- .../contrib/editSessions/browser/editSessionsWorkbenchService.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts b/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts index af25b5ee15a..24962e02c6a 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts @@ -160,7 +160,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes const existing = await this.getExistingSession(); if (existing !== undefined) { this.logService.trace(`Found existing authentication session with ID ${existingSessionId}`); - this.#authenticationInfo = { sessionId: existing.session.id, token: existing.session.accessToken, providerId: existing.session.providerId }; + this.#authenticationInfo = { sessionId: existing.session.id, token: existing.session.idToken ?? existing.session.accessToken, providerId: existing.session.providerId }; this.storeClient.setAuthToken(this.#authenticationInfo.token, this.#authenticationInfo.providerId); return true; } @@ -169,7 +169,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes // Ask the user to pick a preferred account const session = await this.getAccountPreference(); if (session !== undefined) { - this.#authenticationInfo = { sessionId: session.id, token: session.accessToken, providerId: session.providerId }; + this.#authenticationInfo = { sessionId: session.id, token: session.idToken ?? session.accessToken, providerId: session.providerId }; this.storeClient.setAuthToken(this.#authenticationInfo.token, this.#authenticationInfo.providerId); this.existingSessionId = session.id; this.logService.trace(`Saving authentication session preference for ID ${session.id}.`); -- cgit v1.2.3 From a658bc96881e9b2438d6cbd8f49d5d5a2a61a10b Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Jul 2022 12:47:49 -0700 Subject: Add inTerminalRunCommandPicker context key Fixes #154306 --- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 7 ++++++- .../workbench/contrib/terminal/browser/terminalInstanceService.ts | 3 +++ src/vs/workbench/contrib/terminal/common/terminalContextKey.ts | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index e4187f6ab3c..b8ede51f94c 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -355,6 +355,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { private readonly _terminalHasFixedWidth: IContextKey, private readonly _terminalShellTypeContextKey: IContextKey, private readonly _terminalAltBufferActiveContextKey: IContextKey, + private readonly _terminalInRunCommandPicker: IContextKey, private readonly _configHelper: TerminalConfigHelper, private _shellLaunchConfig: IShellLaunchConfig, resource: URI | undefined, @@ -1024,7 +1025,11 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } return new Promise(r => { quickPick.show(); - quickPick.onDidHide(() => r()); + this._terminalInRunCommandPicker.set(true); + quickPick.onDidHide(() => { + this._terminalInRunCommandPicker.set(false); + r(); + }); }); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts index c9da9557b27..a7732ab7c62 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts @@ -23,6 +23,7 @@ export class TerminalInstanceService extends Disposable implements ITerminalInst private _terminalHasFixedWidth: IContextKey; private _terminalShellTypeContextKey: IContextKey; private _terminalAltBufferActiveContextKey: IContextKey; + private _terminalInRunCommandPicker: IContextKey; private _configHelper: TerminalConfigHelper; private readonly _onDidCreateInstance = new Emitter(); @@ -37,6 +38,7 @@ export class TerminalInstanceService extends Disposable implements ITerminalInst this._terminalHasFixedWidth = TerminalContextKeys.terminalHasFixedWidth.bindTo(this._contextKeyService); this._terminalShellTypeContextKey = TerminalContextKeys.shellType.bindTo(this._contextKeyService); this._terminalAltBufferActiveContextKey = TerminalContextKeys.altBufferActive.bindTo(this._contextKeyService); + this._terminalInRunCommandPicker = TerminalContextKeys.inTerminalRunCommandPicker.bindTo(this._contextKeyService); this._configHelper = _instantiationService.createInstance(TerminalConfigHelper); } @@ -49,6 +51,7 @@ export class TerminalInstanceService extends Disposable implements ITerminalInst this._terminalHasFixedWidth, this._terminalShellTypeContextKey, this._terminalAltBufferActiveContextKey, + this._terminalInRunCommandPicker, this._configHelper, shellLaunchConfig, resource diff --git a/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts b/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts index 72f1792fc71..1d292d45536 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts @@ -31,6 +31,7 @@ export const enum TerminalContextKeyStrings { TabsSingularSelection = 'terminalTabsSingularSelection', SplitTerminal = 'terminalSplitTerminal', ShellType = 'terminalShellType', + InTerminalRunCommandPicker = 'inTerminalRunCommandPicker', } export namespace TerminalContextKeys { @@ -119,4 +120,7 @@ export namespace TerminalContextKeys { /** Whether the focused tab's terminal is a split terminal. */ export const splitTerminal = new RawContextKey(TerminalContextKeyStrings.SplitTerminal, false, localize('isSplitTerminalContextKey', "Whether the focused tab's terminal is a split terminal.")); + + /** Whether the terminal run command picker is currently open. */ + export const inTerminalRunCommandPicker = new RawContextKey(TerminalContextKeyStrings.InTerminalRunCommandPicker, false, localize('inTerminalRunCommandPickerContextKey', "Whether the terminal run command picker is currently open.")); } -- cgit v1.2.3 From 70bcfa0172f7f81fad74845a4c5a35e6e2c3b528 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Jul 2022 13:04:28 -0700 Subject: Fix incorrect relaunch when exit code is 0 Part of #154421 --- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index b8ede51f94c..91857de9b20 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1703,7 +1703,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { const parsedExitResult = parseExitResult(exitCodeOrError, this.shellLaunchConfig, this._processManager.processState, this._initialCwd); - if (this._usedShellIntegrationInjection && (this._processManager.processState === ProcessState.KilledDuringLaunch || this._processManager.processState === ProcessState.KilledByProcess)) { + if (this._usedShellIntegrationInjection && (this._processManager.processState === ProcessState.KilledDuringLaunch || this._processManager.processState === ProcessState.KilledByProcess) && parsedExitResult?.code !== 0) { this._relaunchWithShellIntegrationDisabled(parsedExitResult?.message); this._onExit.fire(exitCodeOrError); return; -- cgit v1.2.3 From b710cb58ece5528ee0cad367bd4a47a8af5f46fe Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Jul 2022 13:06:26 -0700 Subject: Don't relaunch shell integration terminals when killed by process The failures we care about should be covered by KilledDuringLaunch Fixes #154421 --- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 91857de9b20..c9fb84a7d0a 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1703,7 +1703,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { const parsedExitResult = parseExitResult(exitCodeOrError, this.shellLaunchConfig, this._processManager.processState, this._initialCwd); - if (this._usedShellIntegrationInjection && (this._processManager.processState === ProcessState.KilledDuringLaunch || this._processManager.processState === ProcessState.KilledByProcess) && parsedExitResult?.code !== 0) { + if (this._usedShellIntegrationInjection && this._processManager.processState === ProcessState.KilledDuringLaunch && parsedExitResult?.code !== 0) { this._relaunchWithShellIntegrationDisabled(parsedExitResult?.message); this._onExit.fire(exitCodeOrError); return; -- cgit v1.2.3 From 3972e8e8892369f57f2549152fb7c4c161dbcb23 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Jul 2022 13:50:09 -0700 Subject: Set status once, prevent preexec recursing Fixes #150241 --- .../browser/media/shellIntegration-bash.sh | 37 ++++++++++++---------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh index 88498fbfb9a..d6a41229e4a 100755 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh @@ -110,23 +110,22 @@ __vsc_precmd() { } __vsc_preexec() { - if [ "$__vsc_in_command_execution" = "0" ]; then - __vsc_initialized=1 - __vsc_in_command_execution="1" - if [[ ! "$BASH_COMMAND" =~ ^__vsc_prompt* ]]; then - __vsc_current_command=$BASH_COMMAND - else - __vsc_current_command="" - fi - __vsc_command_output_start + __vsc_initialized=1 + if [[ ! "$BASH_COMMAND" =~ ^__vsc_prompt* ]]; then + __vsc_current_command=$BASH_COMMAND + else + __vsc_current_command="" fi + __vsc_command_output_start } # Debug trapping/preexec inspired by starship (ISC) if [[ -n "${bash_preexec_imported:-}" ]]; then __vsc_preexec_only() { - __vsc_status="$?" - __vsc_preexec + if [ "$__vsc_in_command_execution" = "0" ]; then + __vsc_in_command_execution="1" + __vsc_preexec + fi } precmd_functions+=(__vsc_prompt_cmd) preexec_functions+=(__vsc_preexec_only) @@ -134,15 +133,19 @@ else __vsc_dbg_trap="$(trap -p DEBUG | cut -d' ' -f3 | tr -d \')" if [[ -z "$__vsc_dbg_trap" ]]; then __vsc_preexec_only() { - __vsc_status="$?" - __vsc_preexec + if [ "$__vsc_in_command_execution" = "0" ]; then + __vsc_in_command_execution="1" + __vsc_preexec + fi } trap '__vsc_preexec_only "$_"' DEBUG elif [[ "$__vsc_dbg_trap" != '__vsc_preexec "$_"' && "$__vsc_dbg_trap" != '__vsc_preexec_all "$_"' ]]; then __vsc_preexec_all() { - __vsc_status="$?" - builtin eval ${__vsc_dbg_trap} - __vsc_preexec + if [ "$__vsc_in_command_execution" = "0" ]; then + __vsc_in_command_execution="1" + builtin eval ${__vsc_dbg_trap} + __vsc_preexec + fi } trap '__vsc_preexec_all "$_"' DEBUG fi @@ -151,6 +154,7 @@ fi __vsc_update_prompt __vsc_prompt_cmd_original() { + __vsc_status="$?" if [[ ${IFS+set} ]]; then __vsc_original_ifs="$IFS" fi @@ -174,7 +178,6 @@ __vsc_prompt_cmd_original() { } __vsc_prompt_cmd() { - __vsc_status="$?" __vsc_precmd } -- cgit v1.2.3 From 3879c72594b54fdbe67f788c6d7c4fd61ff6abc7 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Jul 2022 13:51:40 -0700 Subject: Also set __vsc_status when there are no traps --- src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh | 1 + 1 file changed, 1 insertion(+) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh index d6a41229e4a..a2f4afa1400 100755 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh @@ -178,6 +178,7 @@ __vsc_prompt_cmd_original() { } __vsc_prompt_cmd() { + __vsc_status="$?" __vsc_precmd } -- cgit v1.2.3 From 099759c8a7605a7407b8a1fffce0bacf0a7757c8 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Jul 2022 14:23:02 -0700 Subject: Apply bracketed paste mode on text send to the terminal Fixes #153592 --- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index b8ede51f94c..25387b4b62e 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1460,9 +1460,15 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } async sendText(text: string, addNewLine: boolean): Promise { + // Apply bracketed paste sequences if the terminal has the mode enabled, this will prevent + // the text from triggering keybindings https://github.com/microsoft/vscode/issues/153592 + if (this.xterm?.raw.modes.bracketedPasteMode) { + text = `\x1b[200~${text}\x1b[201~`; + } + // Normalize line endings to 'enter' press. text = text.replace(/\r?\n/g, '\r'); - if (addNewLine && text.substr(text.length - 1) !== '\r') { + if (addNewLine && text.at(-1) !== '\r') { text += '\r'; } -- cgit v1.2.3 From 68ced4032c71d073fb5d6182f0800303eea16149 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Jul 2022 14:29:31 -0700 Subject: Don't use at() yet --- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 25387b4b62e..cb479a3366e 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1468,7 +1468,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { // Normalize line endings to 'enter' press. text = text.replace(/\r?\n/g, '\r'); - if (addNewLine && text.at(-1) !== '\r') { + if (addNewLine && text[text.length - 1] !== '\r') { text += '\r'; } -- cgit v1.2.3 From d287d59d290be69c23466e37ece1facc66682996 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 8 Jul 2022 15:09:05 -0700 Subject: testing: persist empty history filter (#154573) Fixes #150120 --- .../contrib/testing/browser/testingExplorerFilter.ts | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/testing/browser/testingExplorerFilter.ts b/src/vs/workbench/contrib/testing/browser/testingExplorerFilter.ts index 52d57770b21..e9d136fdc9f 100644 --- a/src/vs/workbench/contrib/testing/browser/testingExplorerFilter.ts +++ b/src/vs/workbench/contrib/testing/browser/testingExplorerFilter.ts @@ -35,7 +35,7 @@ const testFilterDescriptions: { [K in TestFilterTerm]: string } = { export class TestingExplorerFilter extends BaseActionViewItem { private input!: SuggestEnabledInputWithHistory; private wrapper!: HTMLDivElement; - private readonly history: StoredValue = this.instantiationService.createInstance(StoredValue, { + private readonly history: StoredValue<{ values: string[]; lastValue: string } | string[]> = this.instantiationService.createInstance(StoredValue, { key: 'testing.filterHistory2', scope: StorageScope.WORKSPACE, target: StorageTarget.USER @@ -65,9 +65,12 @@ export class TestingExplorerFilter extends BaseActionViewItem { const wrapper = this.wrapper = dom.$('.testing-filter-wrapper'); container.appendChild(wrapper); - const history = this.history.get([]); - if (history.length) { - this.state.setText(history[history.length - 1]); + let history = this.history.get({ lastValue: '', values: [] }); + if (history instanceof Array) { + history = { lastValue: '', values: history }; + } + if (history.lastValue) { + this.state.setText(history.lastValue); } const input = this.input = this._register(this.instantiationService.createInstance(ContextScopedSuggestEnabledInputWithHistory, { @@ -94,7 +97,7 @@ export class TestingExplorerFilter extends BaseActionViewItem { value: this.state.text.value, placeholderText: localize('testExplorerFilter', "Filter (e.g. text, !exclude, @tag)"), }, - history + history: history.values })); this._register(attachSuggestEnabledInputBoxStyler(input, this.themeService)); @@ -145,12 +148,7 @@ export class TestingExplorerFilter extends BaseActionViewItem { * Persists changes to the input history. */ public saveState() { - const history = this.input.getHistory(); - if (history.length) { - this.history.store(history); - } else { - this.history.delete(); - } + this.history.store({ lastValue: this.input.getValue(), values: this.input.getHistory() }); } /** -- cgit v1.2.3 From 2a4e52e3c0778c6558e3f385add9de880a12325d Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Sat, 9 Jul 2022 00:23:14 +0200 Subject: Enable profiles in web --- .../sharedProcess/sharedProcessMain.ts | 2 +- .../test/node/extensionsScannerService.test.ts | 3 +- .../test/browser/fileUserDataProvider.test.ts | 3 +- .../userDataProfile/browser/userDataProfile.ts | 50 ++++- .../userDataProfile/common/userDataProfile.ts | 249 ++++++++++++++++++++- .../electron-main/userDataProfile.ts | 160 +------------ .../electron-sandbox/userDataProfile.ts | 34 ++- .../userDataProfile/node/userDataProfile.ts | 88 +------- .../test/common/userDataProfileService.test.ts | 3 +- .../userDataSync/test/common/userDataSyncClient.ts | 6 +- src/vs/server/node/remoteExtensionHostAgentCli.ts | 6 +- src/vs/server/node/serverServices.ts | 9 +- src/vs/workbench/browser/web.main.ts | 18 +- .../userDataProfile/browser/userDataProfile.ts | 3 +- src/vs/workbench/electron-sandbox/desktop.main.ts | 2 +- .../browser/configurationEditingService.test.ts | 5 +- .../test/browser/configurationService.test.ts | 50 +++-- .../test/browser/extensionService.test.ts | 3 + .../test/browser/extensionStorageMigration.test.ts | 3 +- .../test/browser/keybindingEditing.test.ts | 3 +- .../storage/test/browser/storageService.test.ts | 3 +- .../userDataProfile/common/userDataProfile.ts | 4 +- .../test/browser/workbenchTestServices.ts | 6 +- .../test/electron-browser/workbenchTestServices.ts | 4 +- 24 files changed, 403 insertions(+), 314 deletions(-) (limited to 'src/vs') diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index 9cf505e2470..7c128863922 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -232,7 +232,7 @@ class SharedProcessMain extends Disposable { fileService.registerProvider(Schemas.vscodeUserData, userDataFileSystemProvider); // User Data Profiles - const userDataProfilesService = this._register(new UserDataProfilesNativeService(this.configuration.profiles, mainProcessService, environmentService, fileService, logService)); + const userDataProfilesService = this._register(new UserDataProfilesNativeService(this.configuration.profiles, mainProcessService, environmentService)); services.set(IUserDataProfilesService, userDataProfilesService); // Configuration diff --git a/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts b/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts index 8409d699f37..b0a7ec8ad9a 100644 --- a/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts +++ b/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts @@ -18,6 +18,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { ILogService, NullLogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; let translations: Translations = Object.create(null); @@ -72,7 +73,7 @@ suite('NativeExtensionsScanerService Test', () => { }); instantiationService.stub(IProductService, { version: '1.66.0' }); instantiationService.stub(IExtensionsProfileScannerService, new ExtensionsProfileScannerService(fileService, logService)); - instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, new UriIdentityService(fileService), logService)); await fileService.createFolder(systemExtensionsLocation); await fileService.createFolder(userExtensionsLocation); }); diff --git a/src/vs/platform/userData/test/browser/fileUserDataProvider.test.ts b/src/vs/platform/userData/test/browser/fileUserDataProvider.test.ts index f6a9b0d6993..58fd53e21ec 100644 --- a/src/vs/platform/userData/test/browser/fileUserDataProvider.test.ts +++ b/src/vs/platform/userData/test/browser/fileUserDataProvider.test.ts @@ -19,6 +19,7 @@ import { AbstractNativeEnvironmentService } from 'vs/platform/environment/common import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import product from 'vs/platform/product/common/product'; import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; const ROOT = URI.file('tests').with({ scheme: 'vscode-tests' }); @@ -52,7 +53,7 @@ suite('FileUserDataProvider', () => { await testObject.createFolder(backupWorkspaceHomeOnDisk); environmentService = new TestEnvironmentService(userDataHomeOnDisk); - userDataProfilesService = new UserDataProfilesService(environmentService, testObject, logService); + userDataProfilesService = new UserDataProfilesService(environmentService, testObject, new UriIdentityService(testObject), logService); fileUserDataProvider = new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, logService); disposables.add(fileUserDataProvider); diff --git a/src/vs/platform/userDataProfile/browser/userDataProfile.ts b/src/vs/platform/userDataProfile/browser/userDataProfile.ts index c0cc477ed01..56edfc09480 100644 --- a/src/vs/platform/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/browser/userDataProfile.ts @@ -3,20 +3,64 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { revive } from 'vs/base/common/marshalling'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; import { ILogService } from 'vs/platform/log/common/log'; -import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { IUserDataProfilesService, PROFILES_ENABLEMENT_CONFIG, StoredProfileAssociations, StoredUserDataProfile, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; export class BrowserUserDataProfilesService extends UserDataProfilesService implements IUserDataProfilesService { + protected override readonly defaultProfileShouldIncludeExtensionsResourceAlways: boolean = true; + constructor( @IEnvironmentService environmentService: IEnvironmentService, @IFileService fileService: IFileService, + @IUriIdentityService uriIdentityService: IUriIdentityService, @ILogService logService: ILogService, ) { - super(environmentService, fileService, logService); - this._profiles = [this.createDefaultUserDataProfile(true)]; + super(environmentService, fileService, uriIdentityService, logService); + super.setEnablement(window.localStorage.getItem(PROFILES_ENABLEMENT_CONFIG) === 'true'); + } + + override setEnablement(enabled: boolean): void { + super.setEnablement(enabled); + window.localStorage.setItem(PROFILES_ENABLEMENT_CONFIG, enabled ? 'true' : 'false'); + } + + protected override getStoredProfiles(): StoredUserDataProfile[] { + try { + const value = window.localStorage.getItem(UserDataProfilesService.PROFILES_KEY); + if (value) { + return revive(JSON.parse(value)); + } + } catch (error) { + /* ignore */ + this.logService.error(error); + } + return []; + } + + protected override saveStoredProfiles(storedProfiles: StoredUserDataProfile[]): void { + window.localStorage.setItem(UserDataProfilesService.PROFILES_KEY, JSON.stringify(storedProfiles)); + } + + protected override getStoredProfileAssociations(): StoredProfileAssociations { + try { + const value = window.localStorage.getItem(UserDataProfilesService.PROFILE_ASSOCIATIONS_KEY); + if (value) { + return revive(JSON.parse(value)); + } + } catch (error) { + /* ignore */ + this.logService.error(error); + } + return {}; + } + + protected override saveStoredProfileAssociations(storedProfileAssociations: StoredProfileAssociations): void { + window.localStorage.setItem(UserDataProfilesService.PROFILE_ASSOCIATIONS_KEY, JSON.stringify(storedProfileAssociations)); } } diff --git a/src/vs/platform/userDataProfile/common/userDataProfile.ts b/src/vs/platform/userDataProfile/common/userDataProfile.ts index 89a181cda49..53ab77f58ec 100644 --- a/src/vs/platform/userDataProfile/common/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/common/userDataProfile.ts @@ -14,7 +14,11 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IFileService } from 'vs/platform/files/common/files'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; -import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; +import { ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; +import { ResourceMap } from 'vs/base/common/map'; +import { IStringDictionary } from 'vs/base/common/collections'; +import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { Promises } from 'vs/base/common/async'; /** * Flags to indicate whether to use the default profile or not. @@ -66,6 +70,16 @@ export type WorkspaceIdentifier = ISingleFolderWorkspaceIdentifier | IWorkspaceI export type DidChangeProfilesEvent = { readonly added: IUserDataProfile[]; readonly removed: IUserDataProfile[]; readonly all: IUserDataProfile[] }; +export type WillCreateProfileEvent = { + profile: IUserDataProfile; + join(promise: Promise): void; +}; + +export type WillRemoveProfileEvent = { + profile: IUserDataProfile; + join(promise: Promise): void; +}; + export const IUserDataProfilesService = createDecorator('IUserDataProfilesService'); export interface IUserDataProfilesService { readonly _serviceBrand: undefined; @@ -115,34 +129,249 @@ export function toUserDataProfile(name: string, location: URI, useDefaultFlags?: }; } +export type UserDataProfilesObject = { + profiles: IUserDataProfile[]; + workspaces: ResourceMap; + emptyWindow?: IUserDataProfile; +}; + +export type StoredUserDataProfile = { + name: string; + location: URI; + useDefaultFlags?: UseDefaultProfileFlags; +}; + +export type StoredProfileAssociations = { + workspaces?: IStringDictionary; + emptyWindow?: string; +}; + export class UserDataProfilesService extends Disposable implements IUserDataProfilesService { + + protected static readonly PROFILES_KEY = 'userDataProfiles'; + protected static readonly PROFILE_ASSOCIATIONS_KEY = 'profileAssociations'; + readonly _serviceBrand: undefined; + private enabled: boolean = false; + protected readonly defaultProfileShouldIncludeExtensionsResourceAlways: boolean = false; readonly profilesHome: URI; get defaultProfile(): IUserDataProfile { return this.profiles[0]; } - protected _profiles: IUserDataProfile[] = [this.createDefaultUserDataProfile(false)]; - get profiles(): IUserDataProfile[] { return this._profiles; } + get profiles(): IUserDataProfile[] { return this.profilesObject.profiles; } protected readonly _onDidChangeProfiles = this._register(new Emitter()); readonly onDidChangeProfiles = this._onDidChangeProfiles.event; + protected readonly _onWillCreateProfile = this._register(new Emitter()); + readonly onWillCreateProfile = this._onWillCreateProfile.event; + + protected readonly _onWillRemoveProfile = this._register(new Emitter()); + readonly onWillRemoveProfile = this._onWillRemoveProfile.event; + constructor( @IEnvironmentService protected readonly environmentService: IEnvironmentService, @IFileService protected readonly fileService: IFileService, + @IUriIdentityService protected readonly uriIdentityService: IUriIdentityService, @ILogService protected readonly logService: ILogService ) { super(); this.profilesHome = joinPath(this.environmentService.userRoamingDataHome, 'profiles'); } - protected createDefaultUserDataProfile(extensions: boolean): IUserDataProfile { - const profile = toUserDataProfile(localize('defaultProfile', "Default"), this.environmentService.userRoamingDataHome); - return { ...profile, isDefault: true, extensionsResource: extensions ? profile.extensionsResource : undefined }; + setEnablement(enabled: boolean): void { + if (this.enabled !== enabled) { + this._profilesObject = undefined; + this.enabled = enabled; + } + } + + protected _profilesObject: UserDataProfilesObject | undefined; + protected get profilesObject(): UserDataProfilesObject { + if (!this._profilesObject) { + const profiles = this.enabled ? this.getStoredProfiles().map(storedProfile => toUserDataProfile(storedProfile.name, storedProfile.location, storedProfile.useDefaultFlags)) : []; + let emptyWindow: IUserDataProfile | undefined; + const workspaces = new ResourceMap(); + if (profiles.length) { + const profileAssicaitions = this.getStoredProfileAssociations(); + if (profileAssicaitions.workspaces) { + for (const [workspacePath, profilePath] of Object.entries(profileAssicaitions.workspaces)) { + const workspace = URI.parse(workspacePath); + const profileLocation = URI.parse(profilePath); + const profile = profiles.find(p => this.uriIdentityService.extUri.isEqual(p.location, profileLocation)); + if (profile) { + workspaces.set(workspace, profile); + } + } + } + if (profileAssicaitions.emptyWindow) { + const emptyWindowProfileLocation = URI.parse(profileAssicaitions.emptyWindow); + emptyWindow = profiles.find(p => this.uriIdentityService.extUri.isEqual(p.location, emptyWindowProfileLocation)); + } + } + const profile = toUserDataProfile(localize('defaultProfile', "Default"), this.environmentService.userRoamingDataHome); + profiles.unshift({ ...profile, isDefault: true, extensionsResource: this.defaultProfileShouldIncludeExtensionsResourceAlways || profiles.length > 0 ? profile.extensionsResource : undefined }); + this._profilesObject = { profiles, workspaces, emptyWindow }; + } + return this._profilesObject; + } + + getProfile(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile { + const workspace = this.getWorkspace(workspaceIdentifier); + const profile = URI.isUri(workspace) ? this.profilesObject.workspaces.get(workspace) : this.profilesObject.emptyWindow; + return profile ?? this.defaultProfile; + } + + protected getWorkspace(workspaceIdentifier: WorkspaceIdentifier): URI | EmptyWindowWorkspaceIdentifier { + if (isSingleFolderWorkspaceIdentifier(workspaceIdentifier)) { + return workspaceIdentifier.uri; + } + if (isWorkspaceIdentifier(workspaceIdentifier)) { + return workspaceIdentifier.configPath; + } + return 'empty-window'; + } + + async createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier): Promise { + if (!this.enabled) { + throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); + } + if (this.getStoredProfiles().some(p => p.name === name)) { + throw new Error(`Profile with name ${name} already exists`); + } + + const profile = toUserDataProfile(name, joinPath(this.profilesHome, hash(name).toString(16)), useDefaultFlags); + await this.fileService.createFolder(profile.location); + + const joiners: Promise[] = []; + this._onWillCreateProfile.fire({ + profile, + join(promise) { + joiners.push(promise); + } + }); + await Promises.settled(joiners); + + this.updateProfiles([profile], []); + + if (workspaceIdentifier) { + await this.setProfileForWorkspace(profile, workspaceIdentifier); + } + + return profile; + } + + async setProfileForWorkspace(profileToSet: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise { + if (!this.enabled) { + throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); + } + + const profile = this.profiles.find(p => p.id === profileToSet.id); + if (!profile) { + throw new Error(`Profile '${profileToSet.name}' does not exist`); + } + + this.updateWorkspaceAssociation(workspaceIdentifier, profile); + } + + async unsetWorkspace(workspaceIdentifier: WorkspaceIdentifier): Promise { + if (!this.enabled) { + throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); + } + this.updateWorkspaceAssociation(workspaceIdentifier); + } + + async removeProfile(profileToRemove: IUserDataProfile): Promise { + if (!this.enabled) { + throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); + } + if (profileToRemove.isDefault) { + throw new Error('Cannot remove default profile'); + } + const profile = this.profiles.find(p => p.id === profileToRemove.id); + if (!profile) { + throw new Error(`Profile '${profileToRemove.name}' does not exist`); + } + + const joiners: Promise[] = []; + this._onWillRemoveProfile.fire({ + profile, + join(promise) { + joiners.push(promise); + } + }); + await Promises.settled(joiners); + + if (profile.id === this.profilesObject.emptyWindow?.id) { + this.profilesObject.emptyWindow = undefined; + } + for (const workspace of [...this.profilesObject.workspaces.keys()]) { + if (profile.id === this.profilesObject.workspaces.get(workspace)?.id) { + this.profilesObject.workspaces.delete(workspace); + } + } + this.updateStoredProfileAssociations(); + + this.updateProfiles([], [profile]); + + try { + if (this.profiles.length === 1) { + await this.fileService.del(this.profilesHome, { recursive: true }); + } else { + await this.fileService.del(profile.location, { recursive: true }); + } + } catch (error) { + this.logService.error(error); + } + } + + private updateProfiles(added: IUserDataProfile[], removed: IUserDataProfile[]) { + const storedProfiles: StoredUserDataProfile[] = []; + for (const profile of [...this.profilesObject.profiles, ...added]) { + if (profile.isDefault) { + continue; + } + if (removed.some(p => profile.id === p.id)) { + continue; + } + storedProfiles.push({ location: profile.location, name: profile.name, useDefaultFlags: profile.useDefaultFlags }); + } + this.saveStoredProfiles(storedProfiles); + this._profilesObject = undefined; + this._onDidChangeProfiles.fire({ added, removed, all: this.profiles }); + } + + private updateWorkspaceAssociation(workspaceIdentifier: WorkspaceIdentifier, newProfile?: IUserDataProfile) { + const workspace = this.getWorkspace(workspaceIdentifier); + + // Folder or Multiroot workspace + if (URI.isUri(workspace)) { + this.profilesObject.workspaces.delete(workspace); + if (newProfile && !newProfile.isDefault) { + this.profilesObject.workspaces.set(workspace, newProfile); + } + } + // Empty Window + else { + this.profilesObject.emptyWindow = !newProfile?.isDefault ? newProfile : undefined; + } + + this.updateStoredProfileAssociations(); + } + + private updateStoredProfileAssociations() { + const workspaces: IStringDictionary = {}; + for (const [workspace, profile] of this.profilesObject.workspaces.entries()) { + workspaces[workspace.toString()] = profile.location.toString(); + } + const emptyWindow = this.profilesObject.emptyWindow?.location.toString(); + this.saveStoredProfileAssociations({ workspaces, emptyWindow }); + this._profilesObject = undefined; } - createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier): Promise { throw new Error('Not implemented'); } - setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise { throw new Error('Not implemented'); } - getProfile(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile { throw new Error('Not implemented'); } - removeProfile(profile: IUserDataProfile): Promise { throw new Error('Not implemented'); } + protected getStoredProfiles(): StoredUserDataProfile[] { return []; } + protected saveStoredProfiles(storedProfiles: StoredUserDataProfile[]): void { throw new Error('not implemented'); } + + protected getStoredProfileAssociations(): StoredProfileAssociations { return {}; } + protected saveStoredProfileAssociations(storedProfileAssociations: StoredProfileAssociations): void { throw new Error('not implemented'); } } diff --git a/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts b/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts index e52855d4867..0ac191f058a 100644 --- a/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Emitter, Event } from 'vs/base/common/event'; +import { Event } from 'vs/base/common/event'; import { URI, UriComponents } from 'vs/base/common/uri'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; @@ -11,22 +11,9 @@ import { refineServiceDecorator } from 'vs/platform/instantiation/common/instant import { ILogService } from 'vs/platform/log/common/log'; import { IStateMainService } from 'vs/platform/state/electron-main/state'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { IUserDataProfile, IUserDataProfilesService, PROFILES_ENABLEMENT_CONFIG, WorkspaceIdentifier, UseDefaultProfileFlags, toUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile'; -import { Promises } from 'vs/base/common/async'; -import { StoredProfileAssociations, StoredUserDataProfile, UserDataProfilesService } from 'vs/platform/userDataProfile/node/userDataProfile'; +import { IUserDataProfilesService, WorkspaceIdentifier, StoredUserDataProfile, StoredProfileAssociations, WillCreateProfileEvent, WillRemoveProfileEvent } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { UserDataProfilesService } from 'vs/platform/userDataProfile/node/userDataProfile'; import { IStringDictionary } from 'vs/base/common/collections'; -import { joinPath } from 'vs/base/common/resources'; -import { hash } from 'vs/base/common/hash'; - -export type WillCreateProfileEvent = { - profile: IUserDataProfile; - join(promise: Promise): void; -}; - -export type WillRemoveProfileEvent = { - profile: IUserDataProfile; - join(promise: Promise): void; -}; export const IUserDataProfilesMainService = refineServiceDecorator(IUserDataProfilesService); export interface IUserDataProfilesMainService extends IUserDataProfilesService { @@ -37,12 +24,6 @@ export interface IUserDataProfilesMainService extends IUserDataProfilesService { export class UserDataProfilesMainService extends UserDataProfilesService implements IUserDataProfilesMainService { - private readonly _onWillCreateProfile = this._register(new Emitter()); - readonly onWillCreateProfile = this._onWillCreateProfile.event; - - private readonly _onWillRemoveProfile = this._register(new Emitter()); - readonly onWillRemoveProfile = this._onWillRemoveProfile.event; - constructor( @IStateMainService private readonly stateMainService: IStateMainService, @IUriIdentityService uriIdentityService: IUriIdentityService, @@ -53,141 +34,12 @@ export class UserDataProfilesMainService extends UserDataProfilesService impleme super(stateMainService, uriIdentityService, environmentService, fileService, logService); } - override async createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier): Promise { - if (!this.enabled) { - throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); - } - if (this.getStoredProfiles().some(p => p.name === name)) { - throw new Error(`Profile with name ${name} already exists`); - } - - const profile = toUserDataProfile(name, joinPath(this.profilesHome, hash(name).toString(16)), useDefaultFlags); - await this.fileService.createFolder(profile.location); - - const joiners: Promise[] = []; - this._onWillCreateProfile.fire({ - profile, - join(promise) { - joiners.push(promise); - } - }); - await Promises.settled(joiners); - - this.updateProfiles([profile], []); - - if (workspaceIdentifier) { - await this.setProfileForWorkspace(profile, workspaceIdentifier); - } - - return profile; - } - - override async setProfileForWorkspace(profileToSet: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise { - if (!this.enabled) { - throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); - } - - const profile = this.profiles.find(p => p.id === profileToSet.id); - if (!profile) { - throw new Error(`Profile '${profileToSet.name}' does not exist`); - } - - this.updateWorkspaceAssociation(workspaceIdentifier, profile); - } - - async unsetWorkspace(workspaceIdentifier: WorkspaceIdentifier): Promise { - if (!this.enabled) { - throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); - } - this.updateWorkspaceAssociation(workspaceIdentifier); - } - - override async removeProfile(profileToRemove: IUserDataProfile): Promise { - if (!this.enabled) { - throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); - } - if (profileToRemove.isDefault) { - throw new Error('Cannot remove default profile'); - } - const profile = this.profiles.find(p => p.id === profileToRemove.id); - if (!profile) { - throw new Error(`Profile '${profileToRemove.name}' does not exist`); - } - - const joiners: Promise[] = []; - this._onWillRemoveProfile.fire({ - profile, - join(promise) { - joiners.push(promise); - } - }); - await Promises.settled(joiners); - - if (profile.id === this.profilesObject.emptyWindow?.id) { - this.profilesObject.emptyWindow = undefined; - } - for (const workspace of [...this.profilesObject.workspaces.keys()]) { - if (profile.id === this.profilesObject.workspaces.get(workspace)?.id) { - this.profilesObject.workspaces.delete(workspace); - } - } - this.saveStoredProfileAssociations(); - - this.updateProfiles([], [profile]); - - try { - if (this.profiles.length === 1) { - await this.fileService.del(this.profilesHome, { recursive: true }); - } else { - await this.fileService.del(profile.location, { recursive: true }); - } - } catch (error) { - this.logService.error(error); - } - } - - private updateProfiles(added: IUserDataProfile[], removed: IUserDataProfile[]) { - const storedProfiles: StoredUserDataProfile[] = []; - for (const profile of [...this.profilesObject.profiles, ...added]) { - if (profile.isDefault) { - continue; - } - if (removed.some(p => profile.id === p.id)) { - continue; - } - storedProfiles.push({ location: profile.location, name: profile.name, useDefaultFlags: profile.useDefaultFlags }); - } + protected override saveStoredProfiles(storedProfiles: StoredUserDataProfile[]): void { this.stateMainService.setItem(UserDataProfilesMainService.PROFILES_KEY, storedProfiles); - this._profilesObject = undefined; - this._onDidChangeProfiles.fire({ added, removed, all: this.profiles }); - } - - private updateWorkspaceAssociation(workspaceIdentifier: WorkspaceIdentifier, newProfile?: IUserDataProfile) { - const workspace = this.getWorkspace(workspaceIdentifier); - - // Folder or Multiroot workspace - if (URI.isUri(workspace)) { - this.profilesObject.workspaces.delete(workspace); - if (newProfile && !newProfile.isDefault) { - this.profilesObject.workspaces.set(workspace, newProfile); - } - } - // Empty Window - else { - this.profilesObject.emptyWindow = !newProfile?.isDefault ? newProfile : undefined; - } - - this.saveStoredProfileAssociations(); } - private saveStoredProfileAssociations() { - const workspaces: IStringDictionary = {}; - for (const [workspace, profile] of this.profilesObject.workspaces.entries()) { - workspaces[workspace.toString()] = profile.location.toString(); - } - const emptyWindow = this.profilesObject.emptyWindow?.location.toString(); - this.stateMainService.setItem(UserDataProfilesMainService.PROFILE_ASSOCIATIONS_KEY, { workspaces, emptyWindow }); - this._profilesObject = undefined; + protected override saveStoredProfileAssociations(storedProfileAssociations: StoredProfileAssociations): void { + this.stateMainService.setItem(UserDataProfilesMainService.PROFILE_ASSOCIATIONS_KEY, storedProfileAssociations); } protected override getStoredProfileAssociations(): StoredProfileAssociations { diff --git a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts index 57e02b114e1..085e035b676 100644 --- a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts @@ -3,28 +3,40 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { Emitter } from 'vs/base/common/event'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { joinPath } from 'vs/base/common/resources'; import { UriDto } from 'vs/base/common/types'; +import { URI } from 'vs/base/common/uri'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IFileService } from 'vs/platform/files/common/files'; import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/services'; -import { ILogService } from 'vs/platform/log/common/log'; -import { DidChangeProfilesEvent, IUserDataProfile, IUserDataProfilesService, reviveProfile, UseDefaultProfileFlags, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { DidChangeProfilesEvent, IUserDataProfile, IUserDataProfilesService, reviveProfile, UseDefaultProfileFlags, WorkspaceIdentifier } from 'vs/platform/userDataProfile/common/userDataProfile'; import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; -export class UserDataProfilesNativeService extends UserDataProfilesService implements IUserDataProfilesService { +export class UserDataProfilesNativeService extends Disposable implements IUserDataProfilesService { + + readonly _serviceBrand: undefined; private readonly channel: IChannel; + readonly profilesHome: URI; + + get defaultProfile(): IUserDataProfile { return this.profiles[0]; } + private _profiles: IUserDataProfile[] = []; + get profiles(): IUserDataProfile[] { return this._profiles; } + + private readonly _onDidChangeProfiles = this._register(new Emitter()); + readonly onDidChangeProfiles = this._onDidChangeProfiles.event; + constructor( profiles: UriDto[], @IMainProcessService mainProcessService: IMainProcessService, @IEnvironmentService environmentService: IEnvironmentService, - @IFileService fileService: IFileService, - @ILogService logService: ILogService, ) { - super(environmentService, fileService, logService); + super(); this.channel = mainProcessService.getChannel('userDataProfiles'); + this.profilesHome = joinPath(environmentService.userRoamingDataHome, 'profiles'); this._profiles = profiles.map(profile => reviveProfile(profile, this.profilesHome.scheme)); this._register(this.channel.listen('onDidChangeProfiles')(e => { const added = e.added.map(profile => reviveProfile(profile, this.profilesHome.scheme)); @@ -34,17 +46,19 @@ export class UserDataProfilesNativeService extends UserDataProfilesService imple })); } - override async createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): Promise { + async createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): Promise { const result = await this.channel.call>('createProfile', [name, useDefaultFlags, workspaceIdentifier]); return reviveProfile(result, this.profilesHome.scheme); } - override async setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): Promise { + async setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): Promise { await this.channel.call>('setProfileForWorkspace', [profile, workspaceIdentifier]); } - override removeProfile(profile: IUserDataProfile): Promise { + removeProfile(profile: IUserDataProfile): Promise { return this.channel.call('removeProfile', [profile]); } + + getProfile(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile { throw new Error('Not implemented'); } } diff --git a/src/vs/platform/userDataProfile/node/userDataProfile.ts b/src/vs/platform/userDataProfile/node/userDataProfile.ts index 34428dd9689..1405ca08e76 100644 --- a/src/vs/platform/userDataProfile/node/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/node/userDataProfile.ts @@ -3,110 +3,32 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IStringDictionary } from 'vs/base/common/collections'; -import { ResourceMap } from 'vs/base/common/map'; import { revive } from 'vs/base/common/marshalling'; import { UriDto } from 'vs/base/common/types'; -import { URI } from 'vs/base/common/uri'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; import { ILogService } from 'vs/platform/log/common/log'; import { IStateService } from 'vs/platform/state/node/state'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { UseDefaultProfileFlags, IUserDataProfile, IUserDataProfilesService, UserDataProfilesService as BaseUserDataProfilesService, toUserDataProfile, WorkspaceIdentifier, EmptyWindowWorkspaceIdentifier } from 'vs/platform/userDataProfile/common/userDataProfile'; -import { isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; - -export type UserDataProfilesObject = { - profiles: IUserDataProfile[]; - workspaces: ResourceMap; - emptyWindow?: IUserDataProfile; -}; - -export type StoredUserDataProfile = { - name: string; - location: URI; - useDefaultFlags?: UseDefaultProfileFlags; -}; - -export type StoredProfileAssociations = { - workspaces?: IStringDictionary; - emptyWindow?: string; -}; +import { IUserDataProfilesService, UserDataProfilesService as BaseUserDataProfilesService, StoredUserDataProfile, StoredProfileAssociations } from 'vs/platform/userDataProfile/common/userDataProfile'; export class UserDataProfilesService extends BaseUserDataProfilesService implements IUserDataProfilesService { - protected static readonly PROFILES_KEY = 'userDataProfiles'; - protected static readonly PROFILE_ASSOCIATIONS_KEY = 'profileAssociations'; - - protected enabled: boolean = false; - constructor( @IStateService private readonly stateService: IStateService, - @IUriIdentityService protected readonly uriIdentityService: IUriIdentityService, + @IUriIdentityService uriIdentityService: IUriIdentityService, @IEnvironmentService environmentService: IEnvironmentService, @IFileService fileService: IFileService, @ILogService logService: ILogService, ) { - super(environmentService, fileService, logService); - } - - setEnablement(enabled: boolean): void { - this._profilesObject = undefined; - this.enabled = enabled; - } - - protected _profilesObject: UserDataProfilesObject | undefined; - protected get profilesObject(): UserDataProfilesObject { - if (!this._profilesObject) { - const profiles = this.enabled ? this.getStoredProfiles().map(storedProfile => toUserDataProfile(storedProfile.name, storedProfile.location, storedProfile.useDefaultFlags)) : []; - let emptyWindow: IUserDataProfile | undefined; - const workspaces = new ResourceMap(); - if (profiles.length) { - const profileAssicaitions = this.getStoredProfileAssociations(); - if (profileAssicaitions.workspaces) { - for (const [workspacePath, profilePath] of Object.entries(profileAssicaitions.workspaces)) { - const workspace = URI.parse(workspacePath); - const profileLocation = URI.parse(profilePath); - const profile = profiles.find(p => this.uriIdentityService.extUri.isEqual(p.location, profileLocation)); - if (profile) { - workspaces.set(workspace, profile); - } - } - } - if (profileAssicaitions.emptyWindow) { - const emptyWindowProfileLocation = URI.parse(profileAssicaitions.emptyWindow); - emptyWindow = profiles.find(p => this.uriIdentityService.extUri.isEqual(p.location, emptyWindowProfileLocation)); - } - } - profiles.unshift(this.createDefaultUserDataProfile(profiles.length > 0)); - this._profilesObject = { profiles, workspaces, emptyWindow }; - } - return this._profilesObject; - } - - override get profiles(): IUserDataProfile[] { return this.profilesObject.profiles; } - - override getProfile(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile { - const workspace = this.getWorkspace(workspaceIdentifier); - const profile = URI.isUri(workspace) ? this.profilesObject.workspaces.get(workspace) : this.profilesObject.emptyWindow; - return profile ?? this.defaultProfile; - } - - protected getWorkspace(workspaceIdentifier: WorkspaceIdentifier): URI | EmptyWindowWorkspaceIdentifier { - if (isSingleFolderWorkspaceIdentifier(workspaceIdentifier)) { - return workspaceIdentifier.uri; - } - if (isWorkspaceIdentifier(workspaceIdentifier)) { - return workspaceIdentifier.configPath; - } - return 'empty-window'; + super(environmentService, fileService, uriIdentityService, logService); } - protected getStoredProfiles(): StoredUserDataProfile[] { + protected override getStoredProfiles(): StoredUserDataProfile[] { return revive(this.stateService.getItem[]>(UserDataProfilesService.PROFILES_KEY, [])); } - protected getStoredProfileAssociations(): StoredProfileAssociations { + protected override getStoredProfileAssociations(): StoredProfileAssociations { return revive(this.stateService.getItem>(UserDataProfilesService.PROFILE_ASSOCIATIONS_KEY, {})); } diff --git a/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts b/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts index 549c686644c..662a70fe033 100644 --- a/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts +++ b/src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts @@ -14,6 +14,7 @@ import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFil import { AbstractNativeEnvironmentService } from 'vs/platform/environment/common/environmentService'; import product from 'vs/platform/product/common/product'; import { UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; const ROOT = URI.file('tests').with({ scheme: 'vscode-tests' }); @@ -37,7 +38,7 @@ suite('UserDataProfileService (Common)', () => { disposables.add(fileService.registerProvider(ROOT.scheme, fileSystemProvider)); environmentService = new TestEnvironmentService(joinPath(ROOT, 'User')); - testObject = new UserDataProfilesService(environmentService, fileService, logService); + testObject = new UserDataProfilesService(environmentService, fileService, new UriIdentityService(fileService), logService); }); teardown(() => disposables.clear()); diff --git a/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts b/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts index 645181d8a3c..2252b873b35 100644 --- a/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts +++ b/src/vs/platform/userDataSync/test/common/userDataSyncClient.ts @@ -83,14 +83,16 @@ export class UserDataSyncClient extends Disposable { fileService.registerProvider(Schemas.inMemory, new InMemoryFileSystemProvider()); this.instantiationService.stub(IFileService, fileService); - const userDataProfilesService = this.instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + const uriIdentityService = this.instantiationService.createInstance(UriIdentityService); + this.instantiationService.stub(IUriIdentityService, uriIdentityService); + + const userDataProfilesService = this.instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); this.instantiationService.stub(IStorageService, this._register(new InMemoryStorageService())); const configurationService = this._register(new ConfigurationService(userDataProfilesService.defaultProfile.settingsResource, fileService, new NullPolicyService(), logService)); await configurationService.initialize(); this.instantiationService.stub(IConfigurationService, configurationService); - this.instantiationService.stub(IUriIdentityService, this.instantiationService.createInstance(UriIdentityService)); this.instantiationService.stub(IRequestService, this.testServer); diff --git a/src/vs/server/node/remoteExtensionHostAgentCli.ts b/src/vs/server/node/remoteExtensionHostAgentCli.ts index 653748724e0..52647624f79 100644 --- a/src/vs/server/node/remoteExtensionHostAgentCli.ts +++ b/src/vs/server/node/remoteExtensionHostAgentCli.ts @@ -93,8 +93,11 @@ class CliMain extends Disposable { services.set(IFileService, fileService); fileService.registerProvider(Schemas.file, this._register(new DiskFileSystemProvider(logService))); + const uriIdentityService = new UriIdentityService(fileService); + services.set(IUriIdentityService, uriIdentityService); + // User Data Profiles - const userDataProfilesService = this._register(new UserDataProfilesService(environmentService, fileService, logService)); + const userDataProfilesService = this._register(new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); services.set(IUserDataProfilesService, userDataProfilesService); // Configuration @@ -102,7 +105,6 @@ class CliMain extends Disposable { await configurationService.initialize(); services.set(IConfigurationService, configurationService); - services.set(IUriIdentityService, new UriIdentityService(fileService)); services.set(IRequestService, new SyncDescriptor(RequestService)); services.set(IDownloadService, new SyncDescriptor(DownloadService)); services.set(ITelemetryService, NullTelemetryService); diff --git a/src/vs/server/node/serverServices.ts b/src/vs/server/node/serverServices.ts index c20bd776c55..ab5f5cb7d57 100644 --- a/src/vs/server/node/serverServices.ts +++ b/src/vs/server/node/serverServices.ts @@ -110,8 +110,12 @@ export async function setupServerServices(connectionToken: ServerConnectionToken services.set(IFileService, fileService); fileService.registerProvider(Schemas.file, disposables.add(new DiskFileSystemProvider(logService))); + // URI Identity + const uriIdentityService = new UriIdentityService(fileService); + services.set(IUriIdentityService, uriIdentityService); + // User Data Profiles - const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); + const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService); services.set(IUserDataProfilesService, userDataProfilesService); // Configuration @@ -122,9 +126,6 @@ export async function setupServerServices(connectionToken: ServerConnectionToken const extensionHostStatusService = new ExtensionHostStatusService(); services.set(IExtensionHostStatusService, extensionHostStatusService); - // URI Identity - services.set(IUriIdentityService, new UriIdentityService(fileService)); - // Request services.set(IRequestService, new SyncDescriptor(RequestService)); diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 6dd97deb256..d0791572ccf 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -22,7 +22,7 @@ import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteA import { IWorkbenchFileService } from 'vs/workbench/services/files/common/files'; import { FileService } from 'vs/platform/files/common/fileService'; import { Schemas, connectionTokenCookieName } from 'vs/base/common/network'; -import { IAnyWorkspaceIdentifier, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IAnyWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { onUnexpectedError } from 'vs/base/common/errors'; import { setFullscreen } from 'vs/base/browser/browser'; @@ -73,7 +73,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IProgressService } from 'vs/platform/progress/common/progress'; import { DelayedLogChannel } from 'vs/workbench/services/output/common/delayedLogChannel'; import { dirname, joinPath } from 'vs/base/common/resources'; -import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUserDataProfilesService, PROFILES_ENABLEMENT_CONFIG } from 'vs/platform/userDataProfile/common/userDataProfile'; import { NullPolicyService } from 'vs/platform/policy/common/policy'; import { IRemoteExplorerService, TunnelSource } from 'vs/workbench/services/remote/common/remoteExplorerService'; import { DisposableTunnel } from 'vs/platform/tunnel/common/tunnel'; @@ -260,17 +260,16 @@ export class BrowserMain extends Disposable { serviceCollection.set(IWorkbenchFileService, fileService); await this.registerFileSystemProviders(environmentService, fileService, remoteAgentService, logService, logsPath); - // User Data Profiles - const userDataProfilesService = new BrowserUserDataProfilesService(environmentService, fileService, logService); - serviceCollection.set(IUserDataProfilesService, userDataProfilesService); - - const userDataProfileService = new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService); - serviceCollection.set(IUserDataProfileService, userDataProfileService); - // URI Identity const uriIdentityService = new UriIdentityService(fileService); serviceCollection.set(IUriIdentityService, uriIdentityService); + // User Data Profiles + const userDataProfilesService = new BrowserUserDataProfilesService(environmentService, fileService, uriIdentityService, logService); + serviceCollection.set(IUserDataProfilesService, userDataProfilesService); + const userDataProfileService = new UserDataProfileService(userDataProfilesService.getProfile(isWorkspaceIdentifier(payload) || isSingleFolderWorkspaceIdentifier(payload) ? payload : 'empty-window'), userDataProfilesService); + serviceCollection.set(IUserDataProfileService, userDataProfileService); + // Long running services (workspace, config, storage) const [configurationService, storageService] = await Promise.all([ this.createWorkspaceService(payload, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, logService).then(service => { @@ -293,6 +292,7 @@ export class BrowserMain extends Disposable { }) ]); + userDataProfilesService.setEnablement(!!configurationService.getValue(PROFILES_ENABLEMENT_CONFIG)); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts index 44aa262be18..d86d86f4cf8 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts @@ -6,7 +6,6 @@ import { Codicon } from 'vs/base/common/codicons'; import { Event } from 'vs/base/common/event'; import { Disposable, DisposableStore, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; -import { isWeb } from 'vs/base/common/platform'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { localize } from 'vs/nls'; import { Action2, ISubmenuItem, MenuId, MenuRegistry, registerAction2 } from 'vs/platform/actions/common/actions'; @@ -53,7 +52,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements } private registerConfiguration(): void { - if (!isWeb && this.productService.quality !== 'stable') { + if (this.productService.quality !== 'stable') { Registry.as(ConfigurationExtensions.Configuration).registerConfiguration({ ...workbenchConfigurationNodeBase, 'properties': { diff --git a/src/vs/workbench/electron-sandbox/desktop.main.ts b/src/vs/workbench/electron-sandbox/desktop.main.ts index f5878699fdf..4986c87d42a 100644 --- a/src/vs/workbench/electron-sandbox/desktop.main.ts +++ b/src/vs/workbench/electron-sandbox/desktop.main.ts @@ -239,7 +239,7 @@ export class DesktopMain extends Disposable { serviceCollection.set(IUriIdentityService, uriIdentityService); // User Data Profiles - const userDataProfilesService = new UserDataProfilesNativeService(this.configuration.profiles.all, mainProcessService, environmentService, fileService, logService); + const userDataProfilesService = new UserDataProfilesNativeService(this.configuration.profiles.all, mainProcessService, environmentService); serviceCollection.set(IUserDataProfilesService, userDataProfilesService); const userDataProfileService = new UserDataProfileService(reviveProfile(this.configuration.profiles.current, userDataProfilesService.profilesHome.scheme), userDataProfilesService); serviceCollection.set(IUserDataProfileService, userDataProfileService); diff --git a/src/vs/workbench/services/configuration/test/browser/configurationEditingService.test.ts b/src/vs/workbench/services/configuration/test/browser/configurationEditingService.test.ts index 6412bd0e4c3..867ff2532bf 100644 --- a/src/vs/workbench/services/configuration/test/browser/configurationEditingService.test.ts +++ b/src/vs/workbench/services/configuration/test/browser/configurationEditingService.test.ts @@ -110,13 +110,14 @@ suite('ConfigurationEditingService', () => { environmentService = TestEnvironmentService; environmentService.policyFile = joinPath(workspaceFolder, 'policies.json'); instantiationService.stub(IEnvironmentService, environmentService); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); userDataProfileService = new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService); const remoteAgentService = disposables.add(instantiationService.createInstance(RemoteAgentService, null)); disposables.add(fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, logService)))); instantiationService.stub(IFileService, fileService); instantiationService.stub(IRemoteAgentService, remoteAgentService); - workspaceService = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new FilePolicyService(environmentService.policyFile, fileService, logService))); + workspaceService = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new FilePolicyService(environmentService.policyFile, fileService, logService))); await workspaceService.initialize({ id: hash(workspaceFolder.toString()).toString(16), uri: workspaceFolder diff --git a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts index 41573109ed5..fb05bed96f1 100644 --- a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts @@ -86,8 +86,9 @@ suite('WorkspaceContextService - Folder', () => { const environmentService = TestEnvironmentService; fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); - testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService); + testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), uriIdentityService, new NullLogService(), new NullPolicyService())); await (testObject).initialize(convertToWorkspacePayload(folder)); }); @@ -127,8 +128,9 @@ suite('WorkspaceContextService - Folder', () => { const environmentService = TestEnvironmentService; fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); - const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService); + const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), uriIdentityService, new NullLogService(), new NullPolicyService())); await (testObject).initialize(convertToWorkspacePayload(folder)); const actual = testObject.getWorkspaceFolder(joinPath(folder, 'a')); @@ -148,8 +150,9 @@ suite('WorkspaceContextService - Folder', () => { const environmentService = TestEnvironmentService; fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); - const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService); + const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), uriIdentityService, new NullLogService(), new NullPolicyService())); await (testObject).initialize(convertToWorkspacePayload(folder)); @@ -196,8 +199,9 @@ suite('WorkspaceContextService - Workspace', () => { const remoteAgentService = disposables.add(instantiationService.createInstance(RemoteAgentService, null)); instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); - testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); + testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new NullPolicyService())); instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IConfigurationService, testObject); @@ -255,8 +259,9 @@ suite('WorkspaceContextService - Workspace Editing', () => { const remoteAgentService = instantiationService.createInstance(RemoteAgentService, null); instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); - testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); + testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService), userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new NullPolicyService())); instantiationService.stub(IFileService, fileService); instantiationService.stub(IWorkspaceContextService, testObject); @@ -499,9 +504,10 @@ suite('WorkspaceService - Initialization', () => { const remoteAgentService = instantiationService.createInstance(RemoteAgentService, null); instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); - testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new NullPolicyService())); instantiationService.stub(IFileService, fileService); instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IConfigurationService, testObject); @@ -759,9 +765,10 @@ suite('WorkspaceConfigurationService - Folder', () => { const remoteAgentService = instantiationService.createInstance(RemoteAgentService, null); instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); - workspaceService = testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new FilePolicyService(environmentService.policyFile, fileService, logService))); + workspaceService = testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new FilePolicyService(environmentService.policyFile, fileService, logService))); instantiationService.stub(IFileService, fileService); instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IConfigurationService, testObject); @@ -1425,9 +1432,10 @@ suite('WorkspaceConfigurationService - Profiles', () => { const remoteAgentService = instantiationService.createInstance(RemoteAgentService, null); instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(toUserDataProfile('custom', joinPath(environmentService.userRoamingDataHome, 'profiles', 'temp')), userDataProfilesService)); - workspaceService = testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new FilePolicyService(environmentService.policyFile, fileService, logService))); + workspaceService = testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new FilePolicyService(environmentService.policyFile, fileService, logService))); instantiationService.stub(IFileService, fileService); instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IConfigurationService, testObject); @@ -1613,9 +1621,10 @@ suite('WorkspaceConfigurationService-Multiroot', () => { const remoteAgentService = instantiationService.createInstance(RemoteAgentService, null); instantiationService.stub(IRemoteAgentService, remoteAgentService); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); - const workspaceService = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const workspaceService = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new NullPolicyService())); instantiationService.stub(IFileService, fileService); instantiationService.stub(IWorkspaceContextService, workspaceService); @@ -2276,9 +2285,10 @@ suite('WorkspaceConfigurationService - Remote Folder', () => { const remoteAgentService = instantiationService.stub(IRemoteAgentService, >{ getEnvironment: () => remoteEnvironmentPromise }); fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); const configurationCache: IConfigurationCache = { read: () => Promise.resolve(''), write: () => Promise.resolve(), remove: () => Promise.resolve(), needsCaching: () => false }; - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, logService)); + const uriIdentityService = new UriIdentityService(fileService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService)); userDataProfileService = instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); - testObject = disposables.add(new WorkspaceService({ configurationCache, remoteAuthority }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + testObject = disposables.add(new WorkspaceService({ configurationCache, remoteAuthority }, environmentService, userDataProfileService, userDataProfilesService, fileService, remoteAgentService, uriIdentityService, new NullLogService(), new NullPolicyService())); instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IConfigurationService, testObject); instantiationService.stub(IEnvironmentService, environmentService); diff --git a/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts b/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts index 74a3cac60bb..eaa0069f098 100644 --- a/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts +++ b/src/vs/workbench/services/extensions/test/browser/extensionService.test.ts @@ -36,6 +36,8 @@ import { IExtensionHostManager } from 'vs/workbench/services/extensions/common/e import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; suite('BrowserExtensionService', () => { test('pickRunningLocation', () => { @@ -181,6 +183,7 @@ suite('ExtensionService', () => { [IWorkspaceTrustEnablementService, WorkspaceTrustEnablementService], [IUserDataProfilesService, UserDataProfilesService], [IUserDataProfileService, UserDataProfileService], + [IUriIdentityService, UriIdentityService], ]); extService = instantiationService.get(IExtensionService); }); diff --git a/src/vs/workbench/services/extensions/test/browser/extensionStorageMigration.test.ts b/src/vs/workbench/services/extensions/test/browser/extensionStorageMigration.test.ts index d6843185c30..a02b86def5c 100644 --- a/src/vs/workbench/services/extensions/test/browser/extensionStorageMigration.test.ts +++ b/src/vs/workbench/services/extensions/test/browser/extensionStorageMigration.test.ts @@ -22,6 +22,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; suite('ExtensionStorageMigration', () => { @@ -38,7 +39,7 @@ suite('ExtensionStorageMigration', () => { fileService.registerProvider(ROOT.scheme, disposables.add(new InMemoryFileSystemProvider())); instantiationService.stub(IFileService, fileService); const environmentService = instantiationService.stub(IEnvironmentService, >{ userRoamingDataHome: ROOT, workspaceStorageHome }); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, new NullLogService())); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, new UriIdentityService(fileService), new NullLogService())); instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); instantiationService.stub(IExtensionStorageService, instantiationService.createInstance(ExtensionStorageService)); diff --git a/src/vs/workbench/services/keybinding/test/browser/keybindingEditing.test.ts b/src/vs/workbench/services/keybinding/test/browser/keybindingEditing.test.ts index a20bd496d4b..40e00516362 100644 --- a/src/vs/workbench/services/keybinding/test/browser/keybindingEditing.test.ts +++ b/src/vs/workbench/services/keybinding/test/browser/keybindingEditing.test.ts @@ -31,6 +31,7 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; interface Modifiers { metaKey?: boolean; @@ -66,7 +67,7 @@ suite('KeybindingsEditing', () => { const configService = new TestConfigurationService(); configService.setUserConfiguration('files', { 'eol': '\n' }); - const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, logService); + const userDataProfilesService = new UserDataProfilesService(environmentService, fileService, new UriIdentityService(fileService), logService); userDataProfileService = new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService); instantiationService = workbenchInstantiationService({ diff --git a/src/vs/workbench/services/storage/test/browser/storageService.test.ts b/src/vs/workbench/services/storage/test/browser/storageService.test.ts index 4205c92d7a8..8491d3f9301 100644 --- a/src/vs/workbench/services/storage/test/browser/storageService.test.ts +++ b/src/vs/workbench/services/storage/test/browser/storageService.test.ts @@ -16,6 +16,7 @@ import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFil import { NullLogService } from 'vs/platform/log/common/log'; import { StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { createSuite } from 'vs/platform/storage/test/common/storageService.test'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; import { IUserDataProfile, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { BrowserStorageService, IndexedDBStorageDatabase } from 'vs/workbench/services/storage/browser/storageService'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; @@ -46,7 +47,7 @@ async function createStorageService(): Promise<[DisposableStore, BrowserStorageS extensionsResource: joinPath(inMemoryExtraProfileRoot, 'extensionsResource') }; - const storageService = disposables.add(new BrowserStorageService({ id: 'workspace-storage-test' }, new UserDataProfileService(inMemoryExtraProfile, new UserDataProfilesService(TestEnvironmentService, fileService, logService)), logService)); + const storageService = disposables.add(new BrowserStorageService({ id: 'workspace-storage-test' }, new UserDataProfileService(inMemoryExtraProfile, new UserDataProfilesService(TestEnvironmentService, fileService, new UriIdentityService(fileService), logService)), logService)); await storageService.initialize(); diff --git a/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts b/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts index bed76364445..6e09fd1d153 100644 --- a/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts +++ b/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts @@ -10,7 +10,7 @@ import { MenuId } from 'vs/platform/actions/common/actions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IUserDataProfile, PROFILES_ENABLEMENT_CONFIG, UseDefaultProfileFlags } from 'vs/platform/userDataProfile/common/userDataProfile'; import { ContextKeyDefinedExpr, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { IsWebContext, ProductQualityContext } from 'vs/platform/contextkey/common/contextkeys'; +import { ProductQualityContext } from 'vs/platform/contextkey/common/contextkeys'; export interface DidChangeUserDataProfileEvent { readonly preserveData: boolean; @@ -73,4 +73,4 @@ export const PROFILES_TTILE = { value: localize('settings profiles', "Settings P export const PROFILES_CATEGORY = PROFILES_TTILE.value; export const PROFILE_EXTENSION = 'code-profile'; export const PROFILE_FILTER = [{ name: localize('profile', "Settings Profile"), extensions: [PROFILE_EXTENSION] }]; -export const PROFILES_ENABLEMENT_CONTEXT = ContextKeyExpr.and(ProductQualityContext.notEqualsTo('stable'), IsWebContext.negate(), ContextKeyDefinedExpr.create(`config.${PROFILES_ENABLEMENT_CONFIG}`)); +export const PROFILES_ENABLEMENT_CONTEXT = ContextKeyExpr.and(ProductQualityContext.notEqualsTo('stable'), ContextKeyDefinedExpr.create(`config.${PROFILES_ENABLEMENT_CONFIG}`)); diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index 763878dc76d..9b0dc8d9c43 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -286,9 +286,10 @@ export function workbenchInstantiationService( instantiationService.stub(IModelService, disposables.add(instantiationService.createInstance(ModelService))); const fileService = overrides?.fileService ? overrides.fileService(instantiationService) : new TestFileService(); instantiationService.stub(IFileService, fileService); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, new NullLogService())); + const uriIdentityService = new UriIdentityService(fileService); + instantiationService.stub(IUriIdentityService, uriIdentityService); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(environmentService, fileService, uriIdentityService, new NullLogService())); instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); - instantiationService.stub(IUriIdentityService, new UriIdentityService(fileService)); instantiationService.stub(IWorkingCopyBackupService, new TestWorkingCopyBackupService()); instantiationService.stub(ITelemetryService, NullTelemetryService); instantiationService.stub(INotificationService, new TestNotificationService()); @@ -2003,6 +2004,7 @@ export class TestWorkbenchExtensionManagementService implements IWorkbenchExtens export class TestWebExtensionsScannerService implements IWebExtensionsScannerService { _serviceBrand: undefined; + onDidChangeProfileExtensions = Event.None; async scanSystemExtensions(): Promise { return []; } async scanUserExtensions(): Promise { return []; } async scanExtensionsUnderDevelopment(): Promise { return []; } diff --git a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts index 1880f3377d6..3a35d0f4018 100644 --- a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts @@ -53,6 +53,7 @@ import { FileService } from 'vs/platform/files/common/fileService'; import { joinPath } from 'vs/base/common/resources'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; const args = parseArgs(process.argv, OPTIONS); @@ -289,7 +290,8 @@ export function workbenchInstantiationService(disposables = new DisposableStore( instantiationService.stub(INativeEnvironmentService, TestEnvironmentService); instantiationService.stub(IWorkbenchEnvironmentService, TestEnvironmentService); instantiationService.stub(INativeWorkbenchEnvironmentService, TestEnvironmentService); - const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(TestEnvironmentService, new FileService(new NullLogService()), new NullLogService())); + const fileService = new FileService(new NullLogService()); + const userDataProfilesService = instantiationService.stub(IUserDataProfilesService, new UserDataProfilesService(TestEnvironmentService, fileService, new UriIdentityService(fileService), new NullLogService())); instantiationService.stub(IUserDataProfileService, new UserDataProfileService(userDataProfilesService.defaultProfile, userDataProfilesService)); return instantiationService; -- cgit v1.2.3 From 1b6ce581ebfbbfb4572a4433f6450c78d2e1a052 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Fri, 8 Jul 2022 16:53:36 -0700 Subject: Debt - Add execution id to edit session request headers (#154575) Add execution id to edit session request headers --- .../platform/userDataSync/common/userDataSync.ts | 2 +- .../common/userDataSyncStoreService.ts | 4 +-- .../browser/editSessions.contribution.ts | 32 ++++++++++------------ .../browser/editSessionsWorkbenchService.ts | 10 ++++--- .../editSessions/test/browser/editSessions.test.ts | 4 +-- 5 files changed, 26 insertions(+), 26 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/userDataSync/common/userDataSync.ts b/src/vs/platform/userDataSync/common/userDataSync.ts index ec0a973bf60..6973141914f 100644 --- a/src/vs/platform/userDataSync/common/userDataSync.ts +++ b/src/vs/platform/userDataSync/common/userDataSync.ts @@ -184,7 +184,7 @@ export interface IUserDataSyncStoreClient { delete(resource: ServerResource, ref: string | null): Promise; getAllRefs(resource: ServerResource): Promise; - resolveContent(resource: ServerResource, ref: string): Promise; + resolveContent(resource: ServerResource, ref: string, headers?: IHeaders): Promise; } export const IUserDataSyncStoreService = createDecorator('IUserDataSyncStoreService'); diff --git a/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts b/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts index 427babbd4f6..2b7bd79e2b8 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts @@ -244,13 +244,13 @@ export class UserDataSyncStoreClient extends Disposable implements IUserDataSync return result.map(({ url, created }) => ({ ref: relativePath(uri, uri.with({ path: url }))!, created: created * 1000 /* Server returns in seconds */ })); } - async resolveContent(resource: ServerResource, ref: string): Promise { + async resolveContent(resource: ServerResource, ref: string, headers: IHeaders = {}): Promise { if (!this.userDataSyncStoreUrl) { throw new Error('No settings sync store url configured.'); } const url = joinPath(this.userDataSyncStoreUrl, 'resource', resource, ref).toString(); - const headers: IHeaders = {}; + headers = { ...headers }; headers['Cache-Control'] = 'no-cache'; const context = await this.request(url, { type: 'GET', headers }, [], CancellationToken.None); diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts index deb0cb486bc..12f620df779 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts @@ -85,7 +85,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo super(); if (this.environmentService.editSessionId !== undefined) { - void this.applyEditSession(this.environmentService.editSessionId).finally(() => this.environmentService.editSessionId = undefined); + void this.resumeEditSession(this.environmentService.editSessionId).finally(() => this.environmentService.editSessionId = undefined); } this.configurationService.onDidChangeConfiguration((e) => { @@ -132,7 +132,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo this.registerContinueEditSessionAction(); - this.registerApplyLatestEditSessionAction(); + this.registerResumeLatestEditSessionAction(); this.registerStoreLatestEditSessionAction(); this.registerContinueInLocalFolderAction(); @@ -171,9 +171,9 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo })); } - private registerApplyLatestEditSessionAction(): void { + private registerResumeLatestEditSessionAction(): void { const that = this; - this._register(registerAction2(class ApplyLatestEditSessionAction extends Action2 { + this._register(registerAction2(class ResumeLatestEditSessionAction extends Action2 { constructor() { super({ id: 'workbench.experimental.editSessions.actions.resumeLatest', @@ -186,8 +186,8 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo async run(accessor: ServicesAccessor): Promise { await that.progressService.withProgress({ location: ProgressLocation.Notification, - title: localize('applying edit session', 'Applying edit session...') - }, async () => await that.applyEditSession()); + title: localize('resuming edit session', 'Resuming edit session...') + }, async () => await that.resumeEditSession()); } })); } @@ -213,26 +213,24 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo })); } - async applyEditSession(ref?: string): Promise { - if (ref !== undefined) { - this.logService.info(`Applying edit session with ref ${ref}.`); - } + async resumeEditSession(ref?: string): Promise { + this.logService.info(ref !== undefined ? `Resuming edit session with ref ${ref}...` : 'Resuming edit session...'); const data = await this.editSessionsWorkbenchService.read(ref); if (!data) { if (ref === undefined) { - this.notificationService.info(localize('no edit session', 'There are no edit sessions to apply.')); + this.notificationService.info(localize('no edit session', 'There are no edit sessions to resume.')); } else { - this.notificationService.warn(localize('no edit session content for ref', 'Could not apply edit session contents for ID {0}.', ref)); + this.notificationService.warn(localize('no edit session content for ref', 'Could not resume edit session contents for ID {0}.', ref)); } - this.logService.info(`Aborting applying edit session as no edit session content is available to be applied from ref ${ref}.`); + this.logService.info(`Aborting resuming edit session as no edit session content is available to be applied from ref ${ref}.`); return; } const editSession = data.editSession; ref = data.ref; if (editSession.version > EditSessionSchemaVersion) { - this.notificationService.error(localize('client too old', "Please upgrade to a newer version of {0} to apply this edit session.", this.productService.nameLong)); + this.notificationService.error(localize('client too old', "Please upgrade to a newer version of {0} to resume this edit session.", this.productService.nameLong)); return; } @@ -266,7 +264,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo if (hasLocalUncommittedChanges) { // TODO@joyceerhl Provide the option to diff files which would be overwritten by edit session contents const result = await this.dialogService.confirm({ - message: localize('apply edit session warning', 'Applying your edit session may overwrite your existing uncommitted changes. Do you want to proceed?'), + message: localize('resume edit session warning', 'Resuming your edit session may overwrite your existing uncommitted changes. Do you want to proceed?'), type: 'warning', title: EDIT_SESSION_SYNC_CATEGORY.value }); @@ -287,8 +285,8 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo await this.editSessionsWorkbenchService.delete(ref); this.logService.info(`Deleted edit session with ref ${ref}.`); } catch (ex) { - this.logService.error('Failed to apply edit session, reason: ', (ex as Error).toString()); - this.notificationService.error(localize('apply failed', "Failed to apply your edit session.")); + this.logService.error('Failed to resume edit session, reason: ', (ex as Error).toString()); + this.notificationService.error(localize('resume failed', "Failed to resume your edit session.")); } } diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts b/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts index 24962e02c6a..615f7b0f669 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts @@ -14,11 +14,12 @@ import { IProductService } from 'vs/platform/product/common/productService'; import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { IRequestService } from 'vs/platform/request/common/request'; import { IStorageService, IStorageValueChangeEvent, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; -import { IAuthenticationProvider } from 'vs/platform/userDataSync/common/userDataSync'; +import { createSyncHeaders, IAuthenticationProvider } from 'vs/platform/userDataSync/common/userDataSync'; import { UserDataSyncStoreClient } from 'vs/platform/userDataSync/common/userDataSyncStoreService'; import { AuthenticationSession, AuthenticationSessionsChangeEvent, IAuthenticationService } from 'vs/workbench/services/authentication/common/authentication'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { EDIT_SESSIONS_SIGNED_IN, EditSession, EDIT_SESSION_SYNC_CATEGORY, IEditSessionsWorkbenchService, EDIT_SESSIONS_SIGNED_IN_KEY, IEditSessionsLogService } from 'vs/workbench/contrib/editSessions/common/editSessions'; +import { generateUuid } from 'vs/base/common/uuid'; type ExistingSession = IQuickPickItem & { session: AuthenticationSession & { providerId: string } }; type AuthenticationProviderOption = IQuickPickItem & { provider: IAuthenticationProvider }; @@ -73,7 +74,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes throw new Error('Please sign in to store your edit session.'); } - return this.storeClient!.write('editSessions', JSON.stringify(editSession), null); + return this.storeClient!.write('editSessions', JSON.stringify(editSession), null, createSyncHeaders(generateUuid())); } /** @@ -89,11 +90,12 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes } let content: string | undefined | null; + const headers = createSyncHeaders(generateUuid()); try { if (ref !== undefined) { - content = await this.storeClient?.resolveContent('editSessions', ref); + content = await this.storeClient?.resolveContent('editSessions', ref, headers); } else { - const result = await this.storeClient?.read('editSessions', null); + const result = await this.storeClient?.read('editSessions', null, headers); content = result?.content; ref = result?.ref; } diff --git a/src/vs/workbench/contrib/editSessions/test/browser/editSessions.test.ts b/src/vs/workbench/contrib/editSessions/test/browser/editSessions.test.ts index b7caca6f077..07917f285e5 100644 --- a/src/vs/workbench/contrib/editSessions/test/browser/editSessions.test.ts +++ b/src/vs/workbench/contrib/editSessions/test/browser/editSessions.test.ts @@ -112,8 +112,8 @@ suite('Edit session sync', () => { // Create root folder await fileService.createFolder(folderUri); - // Apply edit session - await editSessionsContribution.applyEditSession(); + // Resume edit session + await editSessionsContribution.resumeEditSession(); // Verify edit session was correctly applied assert.equal((await fileService.readFile(fileUri)).value.toString(), fileContents); -- cgit v1.2.3 From d7f814a238ade71303ac2b237e4d676a592b5f06 Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Fri, 8 Jul 2022 20:29:50 -0400 Subject: Add keybindings for search editor file filters (#153954) * Add keybindings for search editor file filters * Review cleanup --- .../browser/searchEditor.contribution.ts | 40 ++++++++++++++++++++++ .../contrib/searchEditor/browser/searchEditor.ts | 14 ++++++++ 2 files changed, 54 insertions(+) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts index ed23a5f2632..a75b4184bd2 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.contribution.ts @@ -41,6 +41,8 @@ import { Disposable } from 'vs/base/common/lifecycle'; const OpenInEditorCommandId = 'search.action.openInEditor'; const OpenNewEditorToSideCommandId = 'search.action.openNewEditorToSide'; const FocusQueryEditorWidgetCommandId = 'search.action.focusQueryEditorWidget'; +const FocusQueryEditorFilesToIncludeCommandId = 'search.action.focusFilesToInclude'; +const FocusQueryEditorFilesToExcludeCommandId = 'search.action.focusFilesToExclude'; const ToggleSearchEditorCaseSensitiveCommandId = 'toggleSearchEditorCaseSensitive'; const ToggleSearchEditorWholeWordCommandId = 'toggleSearchEditorWholeWord'; @@ -374,6 +376,44 @@ registerAction2(class extends Action2 { } }); +registerAction2(class extends Action2 { + constructor() { + super({ + id: FocusQueryEditorFilesToIncludeCommandId, + title: { value: localize('search.action.focusFilesToInclude', "Focus Search Editor Files to Include"), original: 'Focus Search Editor Files to Include' }, + category, + f1: true, + precondition: SearchEditorConstants.InSearchEditor, + }); + } + async run(accessor: ServicesAccessor) { + const editorService = accessor.get(IEditorService); + const input = editorService.activeEditor; + if (input instanceof SearchEditorInput) { + (editorService.activeEditorPane as SearchEditor).focusFilesToIncludeInput(); + } + } +}); + +registerAction2(class extends Action2 { + constructor() { + super({ + id: FocusQueryEditorFilesToExcludeCommandId, + title: { value: localize('search.action.focusFilesToExclude', "Focus Search Editor Files to Exclude"), original: 'Focus Search Editor Files to Exclude' }, + category, + f1: true, + precondition: SearchEditorConstants.InSearchEditor, + }); + } + async run(accessor: ServicesAccessor) { + const editorService = accessor.get(IEditorService); + const input = editorService.activeEditor; + if (input instanceof SearchEditorInput) { + (editorService.activeEditorPane as SearchEditor).focusFilesToExcludeInput(); + } + } +}); + registerAction2(class extends Action2 { constructor() { super({ diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts index 380f8dbcc8f..54be4156b6e 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts @@ -275,6 +275,20 @@ export class SearchEditor extends AbstractTextCodeEditor this.queryEditorWidget.searchInput.focus(); } + focusFilesToIncludeInput() { + if (!this.showingIncludesExcludes) { + this.toggleIncludesExcludes(true); + } + this.inputPatternIncludes.focus(); + } + + focusFilesToExcludeInput() { + if (!this.showingIncludesExcludes) { + this.toggleIncludesExcludes(true); + } + this.inputPatternExcludes.focus(); + } + focusNextInput() { if (this.queryEditorWidget.searchInputHasFocus()) { if (this.showingIncludesExcludes) { -- cgit v1.2.3 From 042e505d3230c3b7dcd7bb0ecdfbff8452fd19fb Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Sat, 9 Jul 2022 17:02:18 -0700 Subject: Allow deleting all edit sessions when signing out (#154579) --- .../browser/editSessionsWorkbenchService.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts b/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts index 615f7b0f669..b63b550ab35 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts @@ -19,6 +19,7 @@ import { UserDataSyncStoreClient } from 'vs/platform/userDataSync/common/userDat import { AuthenticationSession, AuthenticationSessionsChangeEvent, IAuthenticationService } from 'vs/workbench/services/authentication/common/authentication'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { EDIT_SESSIONS_SIGNED_IN, EditSession, EDIT_SESSION_SYNC_CATEGORY, IEditSessionsWorkbenchService, EDIT_SESSIONS_SIGNED_IN_KEY, IEditSessionsLogService } from 'vs/workbench/contrib/editSessions/common/editSessions'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { generateUuid } from 'vs/base/common/uuid'; type ExistingSession = IQuickPickItem & { session: AuthenticationSession & { providerId: string } }; @@ -48,6 +49,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes @IProductService private readonly productService: IProductService, @IContextKeyService private readonly contextKeyService: IContextKeyService, @IRequestService private readonly requestService: IRequestService, + @IDialogService private readonly dialogService: IDialogService, ) { super(); @@ -352,8 +354,19 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes }); } - run() { - that.clearAuthenticationPreference(); + async run() { + const result = await that.dialogService.confirm({ + type: 'info', + message: localize('sign out of edit sessions clear data prompt', 'Do you want to sign out of edit sessions?'), + checkbox: { label: localize('delete all edit sessions', 'Delete all stored edit sessions from the cloud.') }, + primaryButton: localize('clear data confirm', 'Yes'), + }); + if (result.confirmed) { + if (result.checkboxChecked) { + that.storeClient?.delete('editSessions', null); + } + that.clearAuthenticationPreference(); + } } })); } -- cgit v1.2.3 From 068fd7ffbccc99b26bfb051605251a55d19347cf Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Sun, 10 Jul 2022 17:10:58 +0200 Subject: Problems view table - Fix code column rendering issue (#154518) Fix code column rendering issue --- src/vs/workbench/contrib/markers/browser/markersTable.ts | 9 +++++---- src/vs/workbench/contrib/markers/browser/media/markers.css | 11 ++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/markers/browser/markersTable.ts b/src/vs/workbench/contrib/markers/browser/markersTable.ts index a4938d08d58..4d39773daed 100644 --- a/src/vs/workbench/contrib/markers/browser/markersTable.ts +++ b/src/vs/workbench/contrib/markers/browser/markersTable.ts @@ -135,15 +135,17 @@ class MarkerCodeColumnRenderer implements ITableRenderer .monaco-table-td > .code.code-link > .code-label { +.markers-panel .markers-table-container .monaco-table .monaco-list-row .monaco-table-tr > .monaco-table-td > .code > .code-label, +.markers-panel .markers-table-container .monaco-table .monaco-list-row .monaco-table-tr > .monaco-table-td > .code > .monaco-link { display: none; } -.markers-panel .markers-table-container .monaco-table .monaco-list-row .monaco-table-tr > .monaco-table-td > .code.code-link > .monaco-link { +.markers-panel .markers-table-container .monaco-table .monaco-list-row .monaco-table-tr > .monaco-table-td > .code.code-label > .code-label { display: inline; - text-decoration: underline; } -.markers-panel .markers-table-container .monaco-table .monaco-list-row .monaco-table-tr > .monaco-table-td > .code > .monaco-link { - display: none; +.markers-panel .markers-table-container .monaco-table .monaco-list-row .monaco-table-tr > .monaco-table-td > .code.code-link > .monaco-link { + display: inline; + text-decoration: underline; } .markers-panel .markers-table-container .monaco-table .monaco-list-row .monaco-table-tr > .monaco-table-td > .file > .file-position { -- cgit v1.2.3 From 2a745e6552dac8324e995b8c73e0c3041f2b1f1f Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Sun, 10 Jul 2022 20:56:29 +0200 Subject: update icon for settings profiles (#154712) --- src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts index 44aa262be18..ce8de12db1f 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts @@ -15,6 +15,7 @@ import { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from ' import { IProductService } from 'vs/platform/product/common/productService'; import { Registry } from 'vs/platform/registry/common/platform'; import { registerColor } from 'vs/platform/theme/common/colorRegistry'; +import { registerIcon } from 'vs/platform/theme/common/iconRegistry'; import { themeColorFromId } from 'vs/platform/theme/common/themeService'; import { IUserDataProfile, IUserDataProfilesService, PROFILES_ENABLEMENT_CONFIG } from 'vs/platform/userDataProfile/common/userDataProfile'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; @@ -25,6 +26,8 @@ import { IUserDataProfileManagementService, IUserDataProfileService, ManageProfi const CONTEXT_CURRENT_PROFILE = new RawContextKey('currentUserDataProfile', ''); +export const userDataProfilesIcon = registerIcon('settingsProfiles-icon', Codicon.settings, localize('settingsProfilesIcon', 'Icon for Settings Profiles.')); + export class UserDataProfilesWorkbenchContribution extends Disposable implements IWorkbenchContribution { private readonly currentProfileContext: IContextKey; @@ -138,7 +141,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements name: PROFILES_CATEGORY, command: 'workbench.profiles.actions.switchProfile', ariaLabel: localize('currentProfile', "Current Settings Profile is {0}", this.userDataProfileService.currentProfile.name), - text: `$(${Codicon.multipleWindows.id}) ${this.userDataProfileService.currentProfile.name!}`, + text: `$(${userDataProfilesIcon.id}) ${this.userDataProfileService.currentProfile.name!}`, tooltip: localize('profileTooltip', "{0}: {1}", PROFILES_CATEGORY, this.userDataProfileService.currentProfile.name), color: themeColorFromId(STATUS_BAR_SETTINGS_PROFILE_FOREGROUND), backgroundColor: themeColorFromId(STATUS_BAR_SETTINGS_PROFILE_BACKGROUND) -- cgit v1.2.3 From e69176aafd282090e18f558c2b2ac9b3d5b606f5 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Sun, 10 Jul 2022 20:56:54 +0200 Subject: Fix #154180 (#154713) --- src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts index ce8de12db1f..d5c7082d236 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts @@ -118,7 +118,6 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements id: `workbench.profiles.actions.profileEntry.${profile.id}`, title: profile.name, toggled: ContextKeyExpr.equals(CONTEXT_CURRENT_PROFILE.key, profile.id), - precondition: ContextKeyExpr.notEquals(CONTEXT_CURRENT_PROFILE.key, profile.id), menu: [ { id: ManageProfilesSubMenu, @@ -129,7 +128,9 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements }); } async run(accessor: ServicesAccessor) { - return that.userDataProfileManagementService.switchProfile(profile); + if (that.userDataProfileService.currentProfile.id !== profile.id) { + return that.userDataProfileManagementService.switchProfile(profile); + } } }); } -- cgit v1.2.3 From 5bb939a1a92c8c02fc0770755c40a3076439ec00 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 10 Jul 2022 16:04:29 -0700 Subject: Enable more pwsh keybindings via shell integration Part of #45705 --- .../terminal/browser/media/shellIntegration.ps1 | 16 +++++++++++++ .../terminal/browser/terminal.contribution.ts | 28 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 index aceb31ab780..5d7d4436094 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 @@ -72,3 +72,19 @@ if (Get-Module -Name PSReadLine) { # Set IsWindows property [Console]::Write("`e]633;P;IsWindows=$($IsWindows)`a") + +# Set always on key handlers which map to default VS Code keybindings +function Set-MappedKeyHandler { + param ([string[]] $Chord, [string[]]$Sequence) + $Handler = $(Get-PSReadLineKeyHandler -Chord $Chord) + if ($Handler) { + Set-PSReadLineKeyHandler -Chord $Sequence -Function $Handler.Function + } +} +function Set-MappedKeyHandlers { + Set-MappedKeyHandler -Chord Ctrl+Spacebar -Sequence 'F12,a' + Set-MappedKeyHandler -Chord Alt+Spacebar -Sequence 'F12,b' + Set-MappedKeyHandler -Chord Shift+Enter -Sequence 'F12,c' + Set-MappedKeyHandler -Chord Shift+End -Sequence 'F12,d' +} +Set-MappedKeyHandlers diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts index d01b958ae13..8c86caa36af 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -177,6 +177,34 @@ if (isWindows) { }); } +// TODO: This only works when shell integration is enabled - create shell integration enabled for active terminal context key +// Map certain keybindings in pwsh to unused keys which get handled by PSReadLine handlers in the +// shell integration script. This allows keystrokes that cannot be sent via VT sequences to work. +// See https://github.com/microsoft/terminal/issues/879#issuecomment-497775007 +registerSendSequenceKeybinding('\x1b[24~a', { // F12,a -> ctrl+space + when: ContextKeyExpr.and(TerminalContextKeys.focus, ContextKeyExpr.equals(TerminalContextKeyStrings.ShellType, WindowsShellType.PowerShell), CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), + primary: KeyMod.CtrlCmd | KeyCode.Space, + mac: { primary: KeyMod.WinCtrl | KeyCode.Space } +}); +registerSendSequenceKeybinding('\x1b[24~b', { // F12,b -> alt+space + when: ContextKeyExpr.and(TerminalContextKeys.focus, ContextKeyExpr.equals(TerminalContextKeyStrings.ShellType, WindowsShellType.PowerShell), CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), + primary: KeyMod.Alt | KeyCode.Space +}); +registerSendSequenceKeybinding('\x1b[24~c', { // F12,c -> shift+enter + when: ContextKeyExpr.and(TerminalContextKeys.focus, ContextKeyExpr.equals(TerminalContextKeyStrings.ShellType, WindowsShellType.PowerShell), CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), + primary: KeyMod.Shift | KeyCode.Enter +}); +registerSendSequenceKeybinding('\x1b[24~d', { // F12,d -> shift+end - \x1b[1;2F is supposed to work but it doesn't + when: ContextKeyExpr.and(TerminalContextKeys.focus, ContextKeyExpr.equals(TerminalContextKeyStrings.ShellType, WindowsShellType.PowerShell)), + mac: { primary: KeyMod.Shift | KeyMod.CtrlCmd | KeyCode.RightArrow } +}); + +// Always on pwsh keybindings +registerSendSequenceKeybinding('\x1b[1;2H', { // Shift+home + when: ContextKeyExpr.and(TerminalContextKeys.focus, ContextKeyExpr.equals(TerminalContextKeyStrings.ShellType, WindowsShellType.PowerShell)), + mac: { primary: KeyMod.Shift | KeyMod.CtrlCmd | KeyCode.LeftArrow } +}); + // send ctrl+c to the iPad when the terminal is focused and ctrl+c is pressed to kill the process (work around for #114009) if (isIOS) { registerSendSequenceKeybinding(String.fromCharCode('C'.charCodeAt(0) - CTRL_LETTER_OFFSET), { // ctrl+c -- cgit v1.2.3 From be10e638bc24b01c973fb4bfd6c29f92bcb83a6d Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 10 Jul 2022 16:17:50 -0700 Subject: Ensure shell integration is enables for custom keys Fixes #45705 --- src/vs/platform/terminal/common/terminal.ts | 15 +++++++++++- .../terminal/common/xterm/shellIntegrationAddon.ts | 22 ++++++++++++++++- .../terminal/browser/terminal.contribution.ts | 16 ++++++------- .../contrib/terminal/browser/terminalInstance.ts | 28 +++++++++++++++++++--- .../terminal/browser/terminalInstanceService.ts | 3 +++ .../contrib/terminal/common/terminalContextKey.ts | 4 ++++ 6 files changed, 75 insertions(+), 13 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 5ce915d4946..9ce16b79222 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -785,6 +785,19 @@ export type ITerminalProfileObject = ITerminalExecutable | ITerminalProfileSourc export type ITerminalProfileType = ITerminalProfile | IExtensionTerminalProfile; export interface IShellIntegration { - capabilities: ITerminalCapabilityStore; + readonly capabilities: ITerminalCapabilityStore; + readonly status: ShellIntegrationStatus; + + readonly onDidChangeStatus: Event; + deserialize(serialized: ISerializedCommandDetectionCapability): void; } + +export const enum ShellIntegrationStatus { + /** No shell integration sequences have been encountered. */ + Off, + /** Final term shell integration sequences have been encountered. */ + FinalTerm, + /** VS Code shell integration sequences have been encountered. Supercedes FinalTerm. */ + VSCode +} diff --git a/src/vs/platform/terminal/common/xterm/shellIntegrationAddon.ts b/src/vs/platform/terminal/common/xterm/shellIntegrationAddon.ts index 7a07b5b1b83..46c1390f4df 100644 --- a/src/vs/platform/terminal/common/xterm/shellIntegrationAddon.ts +++ b/src/vs/platform/terminal/common/xterm/shellIntegrationAddon.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IShellIntegration } from 'vs/platform/terminal/common/terminal'; +import { IShellIntegration, ShellIntegrationStatus } from 'vs/platform/terminal/common/terminal'; import { Disposable, dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { TerminalCapabilityStore } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore'; import { CommandDetectionCapability } from 'vs/platform/terminal/common/capabilities/commandDetectionCapability'; @@ -16,6 +16,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import type { ITerminalAddon, Terminal } from 'xterm-headless'; import { ISerializedCommandDetectionCapability } from 'vs/platform/terminal/common/terminalProcess'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { Emitter } from 'vs/base/common/event'; /** * Shell integration is a feature that enhances the terminal's understanding of what's happening @@ -137,6 +138,12 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati private _hasUpdatedTelemetry: boolean = false; private _activationTimeout: any; private _commonProtocolDisposables: IDisposable[] = []; + private _status: ShellIntegrationStatus = ShellIntegrationStatus.Off; + + get status(): ShellIntegrationStatus { return this._status; } + + private readonly _onDidChangeStatus = new Emitter(); + readonly onDidChangeStatus = this._onDidChangeStatus.event; constructor( private readonly _disableTelemetry: boolean | undefined, @@ -167,6 +174,15 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati } private _handleFinalTermSequence(data: string): boolean { + const didHandle = this._doHandleFinalTermSequence(data); + if (this._status === ShellIntegrationStatus.Off) { + this._status = ShellIntegrationStatus.FinalTerm; + this._onDidChangeStatus.fire(this._status); + } + return didHandle; + } + + private _doHandleFinalTermSequence(data: string): boolean { if (!this._terminal) { return false; } @@ -204,6 +220,10 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati this._hasUpdatedTelemetry = true; this._clearActivationTimeout(); } + if (this._status !== ShellIntegrationStatus.VSCode) { + this._status = ShellIntegrationStatus.VSCode; + this._onDidChangeStatus.fire(this._status); + } return didHandle; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts index 8c86caa36af..60277418746 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -181,21 +181,21 @@ if (isWindows) { // Map certain keybindings in pwsh to unused keys which get handled by PSReadLine handlers in the // shell integration script. This allows keystrokes that cannot be sent via VT sequences to work. // See https://github.com/microsoft/terminal/issues/879#issuecomment-497775007 -registerSendSequenceKeybinding('\x1b[24~a', { // F12,a -> ctrl+space - when: ContextKeyExpr.and(TerminalContextKeys.focus, ContextKeyExpr.equals(TerminalContextKeyStrings.ShellType, WindowsShellType.PowerShell), CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), +registerSendSequenceKeybinding('\x1b[24~a', { // F12,a -> ctrl+space (MenuComplete) + when: ContextKeyExpr.and(TerminalContextKeys.focus, ContextKeyExpr.equals(TerminalContextKeyStrings.ShellType, WindowsShellType.PowerShell), TerminalContextKeys.terminalShellIntegrationEnabled, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), primary: KeyMod.CtrlCmd | KeyCode.Space, mac: { primary: KeyMod.WinCtrl | KeyCode.Space } }); -registerSendSequenceKeybinding('\x1b[24~b', { // F12,b -> alt+space - when: ContextKeyExpr.and(TerminalContextKeys.focus, ContextKeyExpr.equals(TerminalContextKeyStrings.ShellType, WindowsShellType.PowerShell), CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), +registerSendSequenceKeybinding('\x1b[24~b', { // F12,b -> alt+space (SetMark) + when: ContextKeyExpr.and(TerminalContextKeys.focus, ContextKeyExpr.equals(TerminalContextKeyStrings.ShellType, WindowsShellType.PowerShell), TerminalContextKeys.terminalShellIntegrationEnabled, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), primary: KeyMod.Alt | KeyCode.Space }); -registerSendSequenceKeybinding('\x1b[24~c', { // F12,c -> shift+enter - when: ContextKeyExpr.and(TerminalContextKeys.focus, ContextKeyExpr.equals(TerminalContextKeyStrings.ShellType, WindowsShellType.PowerShell), CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), +registerSendSequenceKeybinding('\x1b[24~c', { // F12,c -> shift+enter (AddLine) + when: ContextKeyExpr.and(TerminalContextKeys.focus, ContextKeyExpr.equals(TerminalContextKeyStrings.ShellType, WindowsShellType.PowerShell), TerminalContextKeys.terminalShellIntegrationEnabled, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), primary: KeyMod.Shift | KeyCode.Enter }); -registerSendSequenceKeybinding('\x1b[24~d', { // F12,d -> shift+end - \x1b[1;2F is supposed to work but it doesn't - when: ContextKeyExpr.and(TerminalContextKeys.focus, ContextKeyExpr.equals(TerminalContextKeyStrings.ShellType, WindowsShellType.PowerShell)), +registerSendSequenceKeybinding('\x1b[24~d', { // F12,d -> shift+end (SelectLine) - HACK: \x1b[1;2F is supposed to work but it doesn't + when: ContextKeyExpr.and(TerminalContextKeys.focus, ContextKeyExpr.equals(TerminalContextKeyStrings.ShellType, WindowsShellType.PowerShell), TerminalContextKeys.terminalShellIntegrationEnabled, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), mac: { primary: KeyMod.Shift | KeyMod.CtrlCmd | KeyCode.RightArrow } }); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index b791e1e8472..0c8ca3f7859 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -46,7 +46,7 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITerminalCommand, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; import { TerminalCapabilityStoreMultiplexer } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore'; -import { IProcessDataEvent, IProcessPropertyMap, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, PosixShellType, ProcessPropertyType, TerminalIcon, TerminalLocation, TerminalSettingId, TerminalShellType, TitleEventSource, WindowsShellType } from 'vs/platform/terminal/common/terminal'; +import { IProcessDataEvent, IProcessPropertyMap, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, PosixShellType, ProcessPropertyType, ShellIntegrationStatus, TerminalIcon, TerminalLocation, TerminalSettingId, TerminalShellType, TitleEventSource, WindowsShellType } from 'vs/platform/terminal/common/terminal'; import { escapeNonWindowsPath, collapseTildePath } from 'vs/platform/terminal/common/terminalEnvironment'; import { activeContrastBorder, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground } from 'vs/platform/theme/common/colorRegistry'; import { IColorTheme, ICssStyleCollector, IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService'; @@ -356,6 +356,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { private readonly _terminalShellTypeContextKey: IContextKey, private readonly _terminalAltBufferActiveContextKey: IContextKey, private readonly _terminalInRunCommandPicker: IContextKey, + private readonly _terminalShellIntegrationEnabledContextKey: IContextKey, private readonly _configHelper: TerminalConfigHelper, private _shellLaunchConfig: IShellLaunchConfig, resource: URI | undefined, @@ -1083,6 +1084,13 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { const screenElement = xterm.attachToElement(xtermElement); xterm.onDidChangeFindResults((results) => this._onDidChangeFindResults.fire(results)); + xterm.shellIntegration.onDidChangeStatus(() => { + if (this.hasFocus) { + this._setShellIntegrationContextKey(); + } else { + this._terminalShellIntegrationEnabledContextKey.reset(); + } + }); if (!xterm.raw.element || !xterm.raw.textarea) { throw new Error('xterm elements not set after open'); @@ -1216,16 +1224,25 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { private _setFocus(focused?: boolean): void { if (focused) { this._terminalFocusContextKey.set(true); + this._setShellIntegrationContextKey(); this._onDidFocus.fire(this); } else { - this._terminalFocusContextKey.reset(); + this.resetFocusContextKey(); this._onDidBlur.fire(this); this._refreshSelectionContextKey(); } } + private _setShellIntegrationContextKey(): void { + console.log('set', this.xterm?.shellIntegration.status === ShellIntegrationStatus.VSCode); + if (this.xterm) { + this._terminalShellIntegrationEnabledContextKey.set(this.xterm.shellIntegration.status === ShellIntegrationStatus.VSCode); + } + } + resetFocusContextKey(): void { this._terminalFocusContextKey.reset(); + this._terminalShellIntegrationEnabledContextKey.reset(); } private _initDragAndDrop(container: HTMLElement) { @@ -1301,6 +1318,11 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } const terminalFocused = !isFocused && (document.activeElement === this.xterm.raw.textarea || document.activeElement === this.xterm.raw.element); this._terminalFocusContextKey.set(terminalFocused); + if (terminalFocused) { + this._setShellIntegrationContextKey(); + } else { + this._terminalShellIntegrationEnabledContextKey.reset(); + } } private _refreshAltBufferContextKey() { @@ -1381,7 +1403,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { // as 'blur' event in xterm.raw.textarea is not triggered on xterm.dispose() // See https://github.com/microsoft/vscode/issues/138358 if (isFirefox) { - this._terminalFocusContextKey.reset(); + this.resetFocusContextKey(); this._terminalHasTextContextKey.reset(); this._onDidBlur.fire(this); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts index a7732ab7c62..a9feaab7aa1 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts @@ -24,6 +24,7 @@ export class TerminalInstanceService extends Disposable implements ITerminalInst private _terminalShellTypeContextKey: IContextKey; private _terminalAltBufferActiveContextKey: IContextKey; private _terminalInRunCommandPicker: IContextKey; + private _terminalShellIntegrationEnabled: IContextKey; private _configHelper: TerminalConfigHelper; private readonly _onDidCreateInstance = new Emitter(); @@ -39,6 +40,7 @@ export class TerminalInstanceService extends Disposable implements ITerminalInst this._terminalShellTypeContextKey = TerminalContextKeys.shellType.bindTo(this._contextKeyService); this._terminalAltBufferActiveContextKey = TerminalContextKeys.altBufferActive.bindTo(this._contextKeyService); this._terminalInRunCommandPicker = TerminalContextKeys.inTerminalRunCommandPicker.bindTo(this._contextKeyService); + this._terminalShellIntegrationEnabled = TerminalContextKeys.terminalShellIntegrationEnabled.bindTo(this._contextKeyService); this._configHelper = _instantiationService.createInstance(TerminalConfigHelper); } @@ -52,6 +54,7 @@ export class TerminalInstanceService extends Disposable implements ITerminalInst this._terminalShellTypeContextKey, this._terminalAltBufferActiveContextKey, this._terminalInRunCommandPicker, + this._terminalShellIntegrationEnabled, this._configHelper, shellLaunchConfig, resource diff --git a/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts b/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts index 1d292d45536..b97b332ea27 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalContextKey.ts @@ -32,6 +32,7 @@ export const enum TerminalContextKeyStrings { SplitTerminal = 'terminalSplitTerminal', ShellType = 'terminalShellType', InTerminalRunCommandPicker = 'inTerminalRunCommandPicker', + TerminalShellIntegrationEnabled = 'terminalShellIntegrationEnabled' } export namespace TerminalContextKeys { @@ -123,4 +124,7 @@ export namespace TerminalContextKeys { /** Whether the terminal run command picker is currently open. */ export const inTerminalRunCommandPicker = new RawContextKey(TerminalContextKeyStrings.InTerminalRunCommandPicker, false, localize('inTerminalRunCommandPickerContextKey', "Whether the terminal run command picker is currently open.")); + + /** Whether shell integration is enabled in the active terminal. This only considers full VS Code shell integration. */ + export const terminalShellIntegrationEnabled = new RawContextKey(TerminalContextKeyStrings.TerminalShellIntegrationEnabled, false, localize('terminalShellIntegrationEnabled', "Whether shell integration is enabled in the active terminal")); } -- cgit v1.2.3 From e9fc1fb99fa8e8f34cd0ddec9547ded57a685923 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 11 Jul 2022 10:34:38 +0200 Subject: ignore syncing settings profile enablement setting (#154771) --- src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts index 13f2e154c6d..0c2b7990a49 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts @@ -63,7 +63,8 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements 'type': 'boolean', 'default': false, 'description': localize('workbench.experimental.settingsProfiles.enabled', "Controls whether to enable the Settings Profiles preview feature."), - scope: ConfigurationScope.APPLICATION + scope: ConfigurationScope.APPLICATION, + ignoreSync: true } } }); -- cgit v1.2.3 From c31f2d0f9999221101fcd96c1f2d6668fe696148 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 11 Jul 2022 10:52:16 +0200 Subject: ignore settings sync for `window.experimental.useSandbox` (#154773) --- src/vs/workbench/electron-sandbox/desktop.contribution.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/electron-sandbox/desktop.contribution.ts b/src/vs/workbench/electron-sandbox/desktop.contribution.ts index 9e045e9638c..f105e0ce308 100644 --- a/src/vs/workbench/electron-sandbox/desktop.contribution.ts +++ b/src/vs/workbench/electron-sandbox/desktop.contribution.ts @@ -241,7 +241,8 @@ import { ModifierKeyEmitter } from 'vs/base/browser/dom'; 'window.experimental.useSandbox': { type: 'boolean', description: localize('experimentalUseSandbox', "Experimental: When enabled, the window will have sandbox mode enabled via Electron API."), - default: false + default: false, + ignoreSync: true }, } }); -- cgit v1.2.3 From f4f0ab3c189798a6a1d400742450571963de1278 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 11 Jul 2022 11:08:14 +0200 Subject: TypeError: Cannot read properties of null (reading 'uri') (#154775) Fixes #154764 --- src/vs/workbench/contrib/comments/browser/commentReply.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/comments/browser/commentReply.ts b/src/vs/workbench/contrib/comments/browser/commentReply.ts index 8fe2a07420e..68eda2e6e39 100644 --- a/src/vs/workbench/contrib/comments/browser/commentReply.ts +++ b/src/vs/workbench/contrib/comments/browser/commentReply.ts @@ -218,8 +218,8 @@ export class CommentReply extends Disposable { this._commentThreadDisposables.push(this._commentThread.onDidChangeInput(input => { const thread = this._commentThread; - - if (thread.input && thread.input.uri !== commentEditor.getModel()!.uri) { + const model = commentEditor.getModel(); + if (thread.input && model && (thread.input.uri !== model.uri)) { return; } if (!input) { -- cgit v1.2.3 From 402d94a0bebc8ddba6b66a87607e54b6ca000ecc Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Mon, 11 Jul 2022 14:14:06 +0200 Subject: Commit Action Button - Fix separator when button is disabled (#154781) * Fix separator when button is disabled * Pull request feedback --- src/vs/base/browser/ui/button/button.css | 8 ++++++++ src/vs/base/browser/ui/button/button.ts | 2 ++ 2 files changed, 10 insertions(+) (limited to 'src/vs') diff --git a/src/vs/base/browser/ui/button/button.css b/src/vs/base/browser/ui/button/button.css index 66e61c3c398..6c9a07a30c2 100644 --- a/src/vs/base/browser/ui/button/button.css +++ b/src/vs/base/browser/ui/button/button.css @@ -38,10 +38,18 @@ cursor: pointer; } +.monaco-button-dropdown.disabled { + cursor: default; +} + .monaco-button-dropdown > .monaco-button:focus { outline-offset: -1px !important; } +.monaco-button-dropdown.disabled .monaco-button-dropdown-separator { + opacity: 0.4; +} + .monaco-button-dropdown .monaco-button-dropdown-separator { padding: 4px 0; } diff --git a/src/vs/base/browser/ui/button/button.ts b/src/vs/base/browser/ui/button/button.ts index 4ae8b9d6239..63833653b7c 100644 --- a/src/vs/base/browser/ui/button/button.ts +++ b/src/vs/base/browser/ui/button/button.ts @@ -299,6 +299,8 @@ export class ButtonWithDropdown extends Disposable implements IButton { set enabled(enabled: boolean) { this.button.enabled = enabled; this.dropdownButton.enabled = enabled; + + this.element.classList.toggle('disabled', !enabled); } get enabled(): boolean { -- cgit v1.2.3 From 9457eb4f14d78916fcce55437b51a3e0bc1d467c Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 11 Jul 2022 14:14:23 +0200 Subject: add `array#removeFastWithoutKeepingOrder` --- src/vs/base/common/arrays.ts | 12 ++++++++++++ src/vs/base/test/common/arrays.test.ts | 13 +++++++++++++ 2 files changed, 25 insertions(+) (limited to 'src/vs') diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index b567c8fe977..d543fdd8f83 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -46,6 +46,18 @@ export function equals(one: ReadonlyArray | undefined, other: ReadonlyArra return true; } +/** + * Remove the element at `index` by replacing it with the last element. This is faster than `splice` + * but changes the order of the array + */ +export function removeFastWithoutKeepingOrder(array: T[], index: number) { + const last = array.length - 1; + if (index < last) { + array[index] = array[last]; + } + array.pop(); +} + /** * Performs a binary search algorithm over a sorted array. * diff --git a/src/vs/base/test/common/arrays.test.ts b/src/vs/base/test/common/arrays.test.ts index 4519661b5c9..23e2b720421 100644 --- a/src/vs/base/test/common/arrays.test.ts +++ b/src/vs/base/test/common/arrays.test.ts @@ -6,6 +6,19 @@ import * as assert from 'assert'; import * as arrays from 'vs/base/common/arrays'; suite('Arrays', () => { + + test('removeFastWithoutKeepingOrder', () => { + const array = [1, 4, 5, 7, 55, 59, 60, 61, 64, 69]; + arrays.removeFastWithoutKeepingOrder(array, 1); + assert.deepStrictEqual(array, [1, 69, 5, 7, 55, 59, 60, 61, 64]); + + arrays.removeFastWithoutKeepingOrder(array, 0); + assert.deepStrictEqual(array, [64, 69, 5, 7, 55, 59, 60, 61]); + + arrays.removeFastWithoutKeepingOrder(array, 7); + assert.deepStrictEqual(array, [64, 69, 5, 7, 55, 59, 60]); + }); + test('findFirst', () => { const array = [1, 4, 5, 7, 55, 59, 60, 61, 64, 69]; -- cgit v1.2.3 From 21147b8c9827809b5dc7db1236b0ff8ccf6c1cd2 Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 11 Jul 2022 14:19:15 +0200 Subject: make `MenuId#id` a string and a strict identifier --- .../platform/actions/browser/menuEntryActionViewItem.ts | 16 ++++++++++++++-- src/vs/platform/actions/common/actions.ts | 15 +++++++++------ src/vs/workbench/browser/actions.ts | 2 +- .../extensions/browser/extensions.contribution.ts | 2 +- .../services/actions/common/menusExtensionPoint.ts | 2 +- 5 files changed, 26 insertions(+), 11 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts index 8572310e90c..f2e093420db 100644 --- a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts +++ b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts @@ -141,7 +141,8 @@ export class MenuEntryActionViewItem extends ActionViewItem { @IKeybindingService protected readonly _keybindingService: IKeybindingService, @INotificationService protected _notificationService: INotificationService, @IContextKeyService protected _contextKeyService: IContextKeyService, - @IThemeService protected _themeService: IThemeService + @IThemeService protected _themeService: IThemeService, + @IContextMenuService protected _contextMenuService: IContextMenuService ) { super(undefined, action, { icon: !!(action.class || action.item.icon), label: !action.class && !action.item.icon, draggable: options?.draggable, keybinding: options?.keybinding, hoverDelegate: options?.hoverDelegate }); this._altKey = ModifierKeyEmitter.getInstance(); @@ -202,6 +203,17 @@ export class MenuEntryActionViewItem extends ActionViewItem { mouseOver = true; updateAltState(); })); + + + this._register(addDisposableListener(container, 'contextmenu', event => { + event.preventDefault(); + event.stopPropagation(); + + this._contextMenuService.showContextMenu({ + getAnchor: () => container, + getActions: () => this._menuItemAction.hideActions.asList() + }); + }, true)); } override updateLabel(): void { @@ -356,7 +368,7 @@ export class DropdownWithDefaultActionViewItem extends BaseActionViewItem { ) { super(null, submenuAction); this._options = options; - this._storageKey = `${submenuAction.item.submenu._debugName}_lastActionId`; + this._storageKey = `${submenuAction.item.submenu.id}_lastActionId`; // determine default action let defaultAction: IAction | undefined; diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index d1cd1197cce..a840260130c 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -45,7 +45,7 @@ export function isISubmenuItem(item: IMenuItem | ISubmenuItem): item is ISubmenu export class MenuId { - private static _idPool = 0; + private static readonly _idPool = new Set(); static readonly CommandPalette = new MenuId('CommandPalette'); static readonly DebugBreakpointsContext = new MenuId('DebugBreakpointsContext'); @@ -162,12 +162,15 @@ export class MenuId { static readonly NewFile = new MenuId('NewFile'); static readonly MergeToolbar = new MenuId('MergeToolbar'); - readonly id: number; - readonly _debugName: string; - constructor(debugName: string) { - this.id = MenuId._idPool++; - this._debugName = debugName; + readonly id: string; + + constructor(identifier: string) { + if (MenuId._idPool.has(identifier)) { + throw new Error(`Duplicate menu identifier ${identifier}`); + } + MenuId._idPool.add(identifier); + this.id = identifier; } } diff --git a/src/vs/workbench/browser/actions.ts b/src/vs/workbench/browser/actions.ts index 53eaf674196..02cf731caac 100644 --- a/src/vs/workbench/browser/actions.ts +++ b/src/vs/workbench/browser/actions.ts @@ -48,7 +48,7 @@ class MenuActions extends Disposable { this._onDidChange.fire(); } - private updateSubmenus(actions: readonly IAction[], submenus: { [id: number]: IMenu }): IDisposable { + private updateSubmenus(actions: readonly IAction[], submenus: Record): IDisposable { const disposables = new DisposableStore(); for (const action of actions) { diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index b3c51e8a568..271fe4a1ec5 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -446,7 +446,7 @@ async function runAction(action: IAction): Promise { } interface IExtensionActionOptions extends IAction2Options { - menuTitles?: { [id: number]: string }; + menuTitles?: { [id: string]: string }; run(accessor: ServicesAccessor, ...args: any[]): Promise; } diff --git a/src/vs/workbench/services/actions/common/menusExtensionPoint.ts b/src/vs/workbench/services/actions/common/menusExtensionPoint.ts index 3d0d3b0206d..04a83f56357 100644 --- a/src/vs/workbench/services/actions/common/menusExtensionPoint.ts +++ b/src/vs/workbench/services/actions/common/menusExtensionPoint.ts @@ -729,7 +729,7 @@ submenusExtensionPoint.setHandler(extensions => { const _apiMenusByKey = new Map(Iterable.map(Iterable.from(apiMenus), menu => ([menu.key, menu]))); const _menuRegistrations = new DisposableStore(); -const _submenuMenuItems = new Map>(); +const _submenuMenuItems = new Map>(); const menusExtensionPoint = ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: (schema.IUserFriendlyMenuItem | schema.IUserFriendlySubmenuItem)[] }>({ extensionPoint: 'menus', -- cgit v1.2.3 From 0dca5e1dcfc92dcdf8f349ff7f03f67a31f86939 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 11 Jul 2022 14:30:25 +0200 Subject: sandbox - move tests to `node` layer (#154779) --- .../electron-browser/keyboardMapperTestUtils.ts | 77 - .../test/electron-browser/linux_de_ch.js | 491 ------ .../test/electron-browser/linux_de_ch.txt | 529 ------ .../test/electron-browser/linux_en_uk.js | 1046 ------------ .../test/electron-browser/linux_en_uk.txt | 517 ------ .../test/electron-browser/linux_en_us.js | 497 ------ .../test/electron-browser/linux_en_us.txt | 507 ------ .../keybinding/test/electron-browser/linux_ru.js | 1046 ------------ .../keybinding/test/electron-browser/linux_ru.txt | 523 ------ .../macLinuxFallbackKeyboardMapper.test.ts | 352 ---- .../macLinuxKeyboardMapper.test.ts | 1730 -------------------- .../keybinding/test/electron-browser/mac_de_ch.js | 1188 -------------- .../keybinding/test/electron-browser/mac_de_ch.txt | 529 ------ .../keybinding/test/electron-browser/mac_en_us.js | 1188 -------------- .../keybinding/test/electron-browser/mac_en_us.txt | 507 ------ .../test/electron-browser/mac_zh_hant.js | 1188 -------------- .../test/electron-browser/mac_zh_hant.txt | 507 ------ .../test/electron-browser/mac_zh_hant2.js | 1188 -------------- .../test/electron-browser/mac_zh_hant2.txt | 507 ------ .../keybinding/test/electron-browser/win_de_ch.js | 1093 ------------- .../keybinding/test/electron-browser/win_de_ch.txt | 284 ---- .../keybinding/test/electron-browser/win_en_us.js | 1093 ------------- .../keybinding/test/electron-browser/win_en_us.txt | 284 ---- .../test/electron-browser/win_por_ptb.js | 1093 ------------- .../test/electron-browser/win_por_ptb.txt | 284 ---- .../keybinding/test/electron-browser/win_ru.js | 1093 ------------- .../keybinding/test/electron-browser/win_ru.txt | 284 ---- .../electron-browser/windowsKeyboardMapper.test.ts | 658 -------- .../test/node/keyboardMapperTestUtils.ts | 77 + .../services/keybinding/test/node/linux_de_ch.js | 491 ++++++ .../services/keybinding/test/node/linux_de_ch.txt | 529 ++++++ .../services/keybinding/test/node/linux_en_uk.js | 1046 ++++++++++++ .../services/keybinding/test/node/linux_en_uk.txt | 517 ++++++ .../services/keybinding/test/node/linux_en_us.js | 497 ++++++ .../services/keybinding/test/node/linux_en_us.txt | 507 ++++++ .../services/keybinding/test/node/linux_ru.js | 1046 ++++++++++++ .../services/keybinding/test/node/linux_ru.txt | 523 ++++++ .../node/macLinuxFallbackKeyboardMapper.test.ts | 352 ++++ .../test/node/macLinuxKeyboardMapper.test.ts | 1730 ++++++++++++++++++++ .../services/keybinding/test/node/mac_de_ch.js | 1188 ++++++++++++++ .../services/keybinding/test/node/mac_de_ch.txt | 529 ++++++ .../services/keybinding/test/node/mac_en_us.js | 1188 ++++++++++++++ .../services/keybinding/test/node/mac_en_us.txt | 507 ++++++ .../services/keybinding/test/node/mac_zh_hant.js | 1188 ++++++++++++++ .../services/keybinding/test/node/mac_zh_hant.txt | 507 ++++++ .../services/keybinding/test/node/mac_zh_hant2.js | 1188 ++++++++++++++ .../services/keybinding/test/node/mac_zh_hant2.txt | 507 ++++++ .../services/keybinding/test/node/win_de_ch.js | 1093 +++++++++++++ .../services/keybinding/test/node/win_de_ch.txt | 284 ++++ .../services/keybinding/test/node/win_en_us.js | 1093 +++++++++++++ .../services/keybinding/test/node/win_en_us.txt | 284 ++++ .../services/keybinding/test/node/win_por_ptb.js | 1093 +++++++++++++ .../services/keybinding/test/node/win_por_ptb.txt | 284 ++++ .../services/keybinding/test/node/win_ru.js | 1093 +++++++++++++ .../services/keybinding/test/node/win_ru.txt | 284 ++++ .../test/node/windowsKeyboardMapper.test.ts | 658 ++++++++ 56 files changed, 20283 insertions(+), 20283 deletions(-) delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/keyboardMapperTestUtils.ts delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/linux_de_ch.js delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/linux_de_ch.txt delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/linux_en_uk.js delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/linux_en_uk.txt delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/linux_en_us.js delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/linux_en_us.txt delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/linux_ru.js delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/linux_ru.txt delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/macLinuxFallbackKeyboardMapper.test.ts delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/macLinuxKeyboardMapper.test.ts delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/mac_de_ch.js delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/mac_de_ch.txt delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/mac_en_us.js delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/mac_en_us.txt delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant.js delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant.txt delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant2.js delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant2.txt delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/win_de_ch.js delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/win_de_ch.txt delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/win_en_us.js delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/win_en_us.txt delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/win_por_ptb.js delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/win_por_ptb.txt delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/win_ru.js delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/win_ru.txt delete mode 100644 src/vs/workbench/services/keybinding/test/electron-browser/windowsKeyboardMapper.test.ts create mode 100644 src/vs/workbench/services/keybinding/test/node/keyboardMapperTestUtils.ts create mode 100644 src/vs/workbench/services/keybinding/test/node/linux_de_ch.js create mode 100644 src/vs/workbench/services/keybinding/test/node/linux_de_ch.txt create mode 100644 src/vs/workbench/services/keybinding/test/node/linux_en_uk.js create mode 100644 src/vs/workbench/services/keybinding/test/node/linux_en_uk.txt create mode 100644 src/vs/workbench/services/keybinding/test/node/linux_en_us.js create mode 100644 src/vs/workbench/services/keybinding/test/node/linux_en_us.txt create mode 100644 src/vs/workbench/services/keybinding/test/node/linux_ru.js create mode 100644 src/vs/workbench/services/keybinding/test/node/linux_ru.txt create mode 100644 src/vs/workbench/services/keybinding/test/node/macLinuxFallbackKeyboardMapper.test.ts create mode 100644 src/vs/workbench/services/keybinding/test/node/macLinuxKeyboardMapper.test.ts create mode 100644 src/vs/workbench/services/keybinding/test/node/mac_de_ch.js create mode 100644 src/vs/workbench/services/keybinding/test/node/mac_de_ch.txt create mode 100644 src/vs/workbench/services/keybinding/test/node/mac_en_us.js create mode 100644 src/vs/workbench/services/keybinding/test/node/mac_en_us.txt create mode 100644 src/vs/workbench/services/keybinding/test/node/mac_zh_hant.js create mode 100644 src/vs/workbench/services/keybinding/test/node/mac_zh_hant.txt create mode 100644 src/vs/workbench/services/keybinding/test/node/mac_zh_hant2.js create mode 100644 src/vs/workbench/services/keybinding/test/node/mac_zh_hant2.txt create mode 100644 src/vs/workbench/services/keybinding/test/node/win_de_ch.js create mode 100644 src/vs/workbench/services/keybinding/test/node/win_de_ch.txt create mode 100644 src/vs/workbench/services/keybinding/test/node/win_en_us.js create mode 100644 src/vs/workbench/services/keybinding/test/node/win_en_us.txt create mode 100644 src/vs/workbench/services/keybinding/test/node/win_por_ptb.js create mode 100644 src/vs/workbench/services/keybinding/test/node/win_por_ptb.txt create mode 100644 src/vs/workbench/services/keybinding/test/node/win_ru.js create mode 100644 src/vs/workbench/services/keybinding/test/node/win_ru.txt create mode 100644 src/vs/workbench/services/keybinding/test/node/windowsKeyboardMapper.test.ts (limited to 'src/vs') diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/keyboardMapperTestUtils.ts b/src/vs/workbench/services/keybinding/test/electron-browser/keyboardMapperTestUtils.ts deleted file mode 100644 index 5d3f52834c2..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/keyboardMapperTestUtils.ts +++ /dev/null @@ -1,77 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as assert from 'assert'; -import * as path from 'vs/base/common/path'; -import { getPathFromAmdModule } from 'vs/base/test/node/testUtils'; -import { Keybinding, KeybindingModifier, ResolvedKeybinding, SimpleKeybinding, ScanCodeBinding } from 'vs/base/common/keybindings'; -import { Promises } from 'vs/base/node/pfs'; -import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; -import { IKeyboardMapper } from 'vs/platform/keyboardLayout/common/keyboardMapper'; - -export interface IResolvedKeybinding { - label: string | null; - ariaLabel: string | null; - electronAccelerator: string | null; - userSettingsLabel: string | null; - isWYSIWYG: boolean; - isChord: boolean; - dispatchParts: (string | null)[]; - singleModifierDispatchParts: (KeybindingModifier | null)[]; -} - -function toIResolvedKeybinding(kb: ResolvedKeybinding): IResolvedKeybinding { - return { - label: kb.getLabel(), - ariaLabel: kb.getAriaLabel(), - electronAccelerator: kb.getElectronAccelerator(), - userSettingsLabel: kb.getUserSettingsLabel(), - isWYSIWYG: kb.isWYSIWYG(), - isChord: kb.isChord(), - dispatchParts: kb.getDispatchParts(), - singleModifierDispatchParts: kb.getSingleModifierDispatchParts() - }; -} - -export function assertResolveKeybinding(mapper: IKeyboardMapper, keybinding: Keybinding | null, expected: IResolvedKeybinding[]): void { - const actual: IResolvedKeybinding[] = mapper.resolveKeybinding(keybinding!).map(toIResolvedKeybinding); - assert.deepStrictEqual(actual, expected); -} - -export function assertResolveKeyboardEvent(mapper: IKeyboardMapper, keyboardEvent: IKeyboardEvent, expected: IResolvedKeybinding): void { - const actual = toIResolvedKeybinding(mapper.resolveKeyboardEvent(keyboardEvent)); - assert.deepStrictEqual(actual, expected); -} - -export function assertResolveUserBinding(mapper: IKeyboardMapper, parts: (SimpleKeybinding | ScanCodeBinding)[], expected: IResolvedKeybinding[]): void { - const actual: IResolvedKeybinding[] = mapper.resolveUserBinding(parts).map(toIResolvedKeybinding); - assert.deepStrictEqual(actual, expected); -} - -export function readRawMapping(file: string): Promise { - return Promises.readFile(getPathFromAmdModule(require, `vs/workbench/services/keybinding/test/electron-browser/${file}.js`)).then((buff) => { - const contents = buff.toString(); - const func = new Function('define', contents); - let rawMappings: T | null = null; - func(function (value: T) { - rawMappings = value; - }); - return rawMappings!; - }); -} - -export function assertMapping(writeFileIfDifferent: boolean, mapper: IKeyboardMapper, file: string): Promise { - const filePath = path.normalize(getPathFromAmdModule(require, `vs/workbench/services/keybinding/test/electron-browser/${file}`)); - - return Promises.readFile(filePath).then((buff) => { - const expected = buff.toString().replace(/\r\n/g, '\n'); - const actual = mapper.dumpDebugInfo().replace(/\r\n/g, '\n'); - if (actual !== expected && writeFileIfDifferent) { - const destPath = filePath.replace(/[\/\\]out[\/\\]vs[\/\\]workbench/, '/src/vs/workbench'); - Promises.writeFile(destPath, actual); - } - assert.deepStrictEqual(actual, expected); - }); -} diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/linux_de_ch.js b/src/vs/workbench/services/keybinding/test/electron-browser/linux_de_ch.js deleted file mode 100644 index 3374e83f679..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/linux_de_ch.js +++ /dev/null @@ -1,491 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -define({ - Sleep: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - WakeUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - KeyA: { - value: 'a', - withShift: 'A', - withAltGr: 'æ', - withShiftAltGr: 'Æ' - }, - KeyB: { - value: 'b', - withShift: 'B', - withAltGr: '”', - withShiftAltGr: '’' - }, - KeyC: { - value: 'c', - withShift: 'C', - withAltGr: '¢', - withShiftAltGr: '©' - }, - KeyD: { - value: 'd', - withShift: 'D', - withAltGr: 'ð', - withShiftAltGr: 'Ð' - }, - KeyE: { - value: 'e', - withShift: 'E', - withAltGr: '€', - withShiftAltGr: 'E' - }, - KeyF: { - value: 'f', - withShift: 'F', - withAltGr: 'đ', - withShiftAltGr: 'ª' - }, - KeyG: { - value: 'g', - withShift: 'G', - withAltGr: 'ŋ', - withShiftAltGr: 'Ŋ' - }, - KeyH: { - value: 'h', - withShift: 'H', - withAltGr: 'ħ', - withShiftAltGr: 'Ħ' - }, - KeyI: { - value: 'i', - withShift: 'I', - withAltGr: '→', - withShiftAltGr: 'ı' - }, - KeyJ: { - value: 'j', - withShift: 'J', - withAltGr: '̉', - withShiftAltGr: '̛' - }, - KeyK: { - value: 'k', - withShift: 'K', - withAltGr: 'ĸ', - withShiftAltGr: '&' - }, - KeyL: { - value: 'l', - withShift: 'L', - withAltGr: 'ł', - withShiftAltGr: 'Ł' - }, - KeyM: { - value: 'm', - withShift: 'M', - withAltGr: 'µ', - withShiftAltGr: 'º' - }, - KeyN: { - value: 'n', - withShift: 'N', - withAltGr: 'n', - withShiftAltGr: 'N' - }, - KeyO: { - value: 'o', - withShift: 'O', - withAltGr: 'œ', - withShiftAltGr: 'Œ' - }, - KeyP: { - value: 'p', - withShift: 'P', - withAltGr: 'þ', - withShiftAltGr: 'Þ' - }, - KeyQ: { - value: 'q', - withShift: 'Q', - withAltGr: '@', - withShiftAltGr: 'Ω' - }, - KeyR: { - value: 'r', - withShift: 'R', - withAltGr: '¶', - withShiftAltGr: '®' - }, - KeyS: { - value: 's', - withShift: 'S', - withAltGr: 'ß', - withShiftAltGr: '§' - }, - KeyT: { - value: 't', - withShift: 'T', - withAltGr: 'ŧ', - withShiftAltGr: 'Ŧ' - }, - KeyU: { - value: 'u', - withShift: 'U', - withAltGr: '↓', - withShiftAltGr: '↑' - }, - KeyV: { - value: 'v', - withShift: 'V', - withAltGr: '“', - withShiftAltGr: '‘' - }, - KeyW: { - value: 'w', - withShift: 'W', - withAltGr: 'ł', - withShiftAltGr: 'Ł' - }, - KeyX: { - value: 'x', - withShift: 'X', - withAltGr: '»', - withShiftAltGr: '>' - }, - KeyY: { - value: 'z', - withShift: 'Z', - withAltGr: '←', - withShiftAltGr: '¥' - }, - KeyZ: { - value: 'y', - withShift: 'Y', - withAltGr: '«', - withShiftAltGr: '<' - }, - Digit1: { - value: '1', - withShift: '+', - withAltGr: '|', - withShiftAltGr: '¡' - }, - Digit2: { - value: '2', - withShift: '"', - withAltGr: '@', - withShiftAltGr: '⅛' - }, - Digit3: { - value: '3', - withShift: '*', - withAltGr: '#', - withShiftAltGr: '£' - }, - Digit4: { - value: '4', - withShift: 'ç', - withAltGr: '¼', - withShiftAltGr: '$' - }, - Digit5: { - value: '5', - withShift: '%', - withAltGr: '½', - withShiftAltGr: '⅜' - }, - Digit6: { - value: '6', - withShift: '&', - withAltGr: '¬', - withShiftAltGr: '⅝' - }, - Digit7: { - value: '7', - withShift: '/', - withAltGr: '|', - withShiftAltGr: '⅞' - }, - Digit8: { - value: '8', - withShift: '(', - withAltGr: '¢', - withShiftAltGr: '™' - }, - Digit9: { - value: '9', - withShift: ')', - withAltGr: ']', - withShiftAltGr: '±' - }, - Digit0: { - value: '0', - withShift: '=', - withAltGr: '}', - withShiftAltGr: '°' - }, - Enter: { - value: '\r', - withShift: '\r', - withAltGr: '\r', - withShiftAltGr: '\r' - }, - Escape: { - value: '\u001b', - withShift: '\u001b', - withAltGr: '\u001b', - withShiftAltGr: '\u001b' - }, - Backspace: { - value: '\b', - withShift: '\b', - withAltGr: '\b', - withShiftAltGr: '\b' - }, - Tab: { - value: '\t', - withShift: '', - withAltGr: '\t', - withShiftAltGr: '' - }, - Space: { - value: ' ', - withShift: ' ', - withAltGr: ' ', - withShiftAltGr: ' ' - }, - Minus: { - value: '\'', - withShift: '?', - withAltGr: '́', - withShiftAltGr: '¿' - }, - Equal: { - value: '̂', - withShift: '̀', - withAltGr: '̃', - withShiftAltGr: '̨' - }, - BracketLeft: { - value: 'ü', - withShift: 'è', - withAltGr: '[', - withShiftAltGr: '̊' - }, - BracketRight: { - value: '̈', - withShift: '!', - withAltGr: ']', - withShiftAltGr: '̄' - }, - Backslash: { - value: '$', - withShift: '£', - withAltGr: '}', - withShiftAltGr: '̆' - }, - Semicolon: { - value: 'ö', - withShift: 'é', - withAltGr: '́', - withShiftAltGr: '̋' - }, - Quote: { - value: 'ä', - withShift: 'à', - withAltGr: '{', - withShiftAltGr: '̌' - }, - Backquote: { - value: '§', - withShift: '°', - withAltGr: '¬', - withShiftAltGr: '¬' - }, - Comma: { - value: ',', - withShift: ';', - withAltGr: '─', - withShiftAltGr: '×' - }, - Period: { - value: '.', - withShift: ':', - withAltGr: '·', - withShiftAltGr: '÷' - }, - Slash: { - value: '-', - withShift: '_', - withAltGr: '̣', - withShiftAltGr: '̇' - }, - CapsLock: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F1: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F2: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F3: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F4: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F5: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F6: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F7: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F8: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F9: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F10: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F11: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F12: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - PrintScreen: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ScrollLock: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Pause: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Insert: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Home: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - PageUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Delete: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - End: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - PageDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ArrowRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ArrowLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ArrowDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ArrowUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - NumLock: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - NumpadDivide: { - value: '/', - withShift: '/', - withAltGr: '/', - withShiftAltGr: '/' - }, - NumpadMultiply: { - value: '*', - withShift: '*', - withAltGr: '*', - withShiftAltGr: '*' - }, - NumpadSubtract: { - value: '-', - withShift: '-', - withAltGr: '-', - withShiftAltGr: '-' - }, - NumpadAdd: { - value: '+', - withShift: '+', - withAltGr: '+', - withShiftAltGr: '+' - }, - NumpadEnter: { - value: '\r', - withShift: '\r', - withAltGr: '\r', - withShiftAltGr: '\r' - }, - Numpad1: { value: '', withShift: '1', withAltGr: '', withShiftAltGr: '1' }, - Numpad2: { value: '', withShift: '2', withAltGr: '', withShiftAltGr: '2' }, - Numpad3: { value: '', withShift: '3', withAltGr: '', withShiftAltGr: '3' }, - Numpad4: { value: '', withShift: '4', withAltGr: '', withShiftAltGr: '4' }, - Numpad5: { value: '', withShift: '5', withAltGr: '', withShiftAltGr: '5' }, - Numpad6: { value: '', withShift: '6', withAltGr: '', withShiftAltGr: '6' }, - Numpad7: { value: '', withShift: '7', withAltGr: '', withShiftAltGr: '7' }, - Numpad8: { value: '', withShift: '8', withAltGr: '', withShiftAltGr: '8' }, - Numpad9: { value: '', withShift: '9', withAltGr: '', withShiftAltGr: '9' }, - Numpad0: { value: '', withShift: '0', withAltGr: '', withShiftAltGr: '0' }, - NumpadDecimal: { value: '', withShift: '.', withAltGr: '', withShiftAltGr: '.' }, - IntlBackslash: { - value: '<', - withShift: '>', - withAltGr: '\\', - withShiftAltGr: '¦' - }, - ContextMenu: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Power: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - NumpadEqual: { - value: '=', - withShift: '=', - withAltGr: '=', - withShiftAltGr: '=' - }, - F13: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F14: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F15: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F16: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F17: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F18: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F19: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F20: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F21: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F22: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F23: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F24: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Open: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Help: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Select: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Again: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Undo: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Cut: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Copy: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Paste: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Find: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - AudioVolumeMute: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - AudioVolumeUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - AudioVolumeDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - NumpadComma: { - value: '.', - withShift: '.', - withAltGr: '.', - withShiftAltGr: '.' - }, - IntlRo: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - KanaMode: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - IntlYen: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Convert: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - NonConvert: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Lang1: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Lang2: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Lang3: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Lang4: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Lang5: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - NumpadParenLeft: { - value: '(', - withShift: '(', - withAltGr: '(', - withShiftAltGr: '(' - }, - NumpadParenRight: { - value: ')', - withShift: ')', - withAltGr: ')', - withShiftAltGr: ')' - }, - ControlLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ShiftLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - AltLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MetaLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ControlRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ShiftRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - AltRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MetaRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrightnessUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrightnessDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaPlay: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaRecord: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaFastForward: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaRewind: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaTrackNext: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaTrackPrevious: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaStop: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Eject: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaPlayPause: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaSelect: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - LaunchMail: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - LaunchApp2: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - LaunchApp1: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - SelectTask: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - LaunchScreenSaver: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrowserSearch: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrowserHome: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrowserBack: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrowserForward: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrowserStop: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrowserRefresh: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrowserFavorites: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MailReply: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MailForward: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MailSend: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' } -}); diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/linux_de_ch.txt b/src/vs/workbench/services/keybinding/test/electron-browser/linux_de_ch.txt deleted file mode 100644 index aaf9263ec26..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/linux_de_ch.txt +++ /dev/null @@ -1,529 +0,0 @@ -isUSStandard: false ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyA | a | A | | A | a | A | [KeyA] | | -| Ctrl+KeyA | a | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | -| Shift+KeyA | A | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | -| Ctrl+Shift+KeyA | A | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | -| Alt+KeyA | a | Alt+A | | Alt+A | alt+a | Alt+A | alt+[KeyA] | | -| Ctrl+Alt+KeyA | æ | Ctrl+Alt+A | | Ctrl+Alt+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | -| Shift+Alt+KeyA | A | Shift+Alt+A | | Shift+Alt+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | -| Ctrl+Shift+Alt+KeyA | Æ | Ctrl+Shift+Alt+A | | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyB | b | B | | B | b | B | [KeyB] | | -| Ctrl+KeyB | b | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | -| Shift+KeyB | B | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | -| Ctrl+Shift+KeyB | B | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | -| Alt+KeyB | b | Alt+B | | Alt+B | alt+b | Alt+B | alt+[KeyB] | | -| Ctrl+Alt+KeyB | ” | Ctrl+Alt+B | | Ctrl+Alt+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | -| Shift+Alt+KeyB | B | Shift+Alt+B | | Shift+Alt+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | -| Ctrl+Shift+Alt+KeyB | ’ | Ctrl+Shift+Alt+B | | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyC | c | C | | C | c | C | [KeyC] | | -| Ctrl+KeyC | c | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | -| Shift+KeyC | C | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | -| Ctrl+Shift+KeyC | C | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | -| Alt+KeyC | c | Alt+C | | Alt+C | alt+c | Alt+C | alt+[KeyC] | | -| Ctrl+Alt+KeyC | ¢ | Ctrl+Alt+C | | Ctrl+Alt+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | -| Shift+Alt+KeyC | C | Shift+Alt+C | | Shift+Alt+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | -| Ctrl+Shift+Alt+KeyC | © | Ctrl+Shift+Alt+C | | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyD | d | D | | D | d | D | [KeyD] | | -| Ctrl+KeyD | d | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | -| Shift+KeyD | D | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | -| Ctrl+Shift+KeyD | D | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | -| Alt+KeyD | d | Alt+D | | Alt+D | alt+d | Alt+D | alt+[KeyD] | | -| Ctrl+Alt+KeyD | ð | Ctrl+Alt+D | | Ctrl+Alt+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | -| Shift+Alt+KeyD | D | Shift+Alt+D | | Shift+Alt+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | -| Ctrl+Shift+Alt+KeyD | Ð | Ctrl+Shift+Alt+D | | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyE | e | E | | E | e | E | [KeyE] | | -| Ctrl+KeyE | e | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | -| Shift+KeyE | E | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | -| Ctrl+Shift+KeyE | E | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | -| Alt+KeyE | e | Alt+E | | Alt+E | alt+e | Alt+E | alt+[KeyE] | | -| Ctrl+Alt+KeyE | € | Ctrl+Alt+E | | Ctrl+Alt+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | -| Shift+Alt+KeyE | E | Shift+Alt+E | | Shift+Alt+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | -| Ctrl+Shift+Alt+KeyE | E | Ctrl+Shift+Alt+E | | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyF | f | F | | F | f | F | [KeyF] | | -| Ctrl+KeyF | f | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | -| Shift+KeyF | F | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | -| Ctrl+Shift+KeyF | F | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | -| Alt+KeyF | f | Alt+F | | Alt+F | alt+f | Alt+F | alt+[KeyF] | | -| Ctrl+Alt+KeyF | đ | Ctrl+Alt+F | | Ctrl+Alt+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | -| Shift+Alt+KeyF | F | Shift+Alt+F | | Shift+Alt+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | -| Ctrl+Shift+Alt+KeyF | ª | Ctrl+Shift+Alt+F | | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyG | g | G | | G | g | G | [KeyG] | | -| Ctrl+KeyG | g | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | -| Shift+KeyG | G | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | -| Ctrl+Shift+KeyG | G | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | -| Alt+KeyG | g | Alt+G | | Alt+G | alt+g | Alt+G | alt+[KeyG] | | -| Ctrl+Alt+KeyG | ŋ | Ctrl+Alt+G | | Ctrl+Alt+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | -| Shift+Alt+KeyG | G | Shift+Alt+G | | Shift+Alt+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | -| Ctrl+Shift+Alt+KeyG | Ŋ | Ctrl+Shift+Alt+G | | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyH | h | H | | H | h | H | [KeyH] | | -| Ctrl+KeyH | h | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | -| Shift+KeyH | H | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | -| Ctrl+Shift+KeyH | H | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | -| Alt+KeyH | h | Alt+H | | Alt+H | alt+h | Alt+H | alt+[KeyH] | | -| Ctrl+Alt+KeyH | ħ | Ctrl+Alt+H | | Ctrl+Alt+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | -| Shift+Alt+KeyH | H | Shift+Alt+H | | Shift+Alt+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | -| Ctrl+Shift+Alt+KeyH | Ħ | Ctrl+Shift+Alt+H | | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyI | i | I | | I | i | I | [KeyI] | | -| Ctrl+KeyI | i | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | -| Shift+KeyI | I | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | -| Ctrl+Shift+KeyI | I | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | -| Alt+KeyI | i | Alt+I | | Alt+I | alt+i | Alt+I | alt+[KeyI] | | -| Ctrl+Alt+KeyI | → | Ctrl+Alt+I | | Ctrl+Alt+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | -| Shift+Alt+KeyI | I | Shift+Alt+I | | Shift+Alt+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | -| Ctrl+Shift+Alt+KeyI | ı | Ctrl+Shift+Alt+I | | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyJ | j | J | | J | j | J | [KeyJ] | | -| Ctrl+KeyJ | j | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | -| Shift+KeyJ | J | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | -| Ctrl+Shift+KeyJ | J | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | -| Alt+KeyJ | j | Alt+J | | Alt+J | alt+j | Alt+J | alt+[KeyJ] | | -| Ctrl+Alt+KeyJ | U+309 | Ctrl+Alt+J | | Ctrl+Alt+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | -| Shift+Alt+KeyJ | J | Shift+Alt+J | | Shift+Alt+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | -| Ctrl+Shift+Alt+KeyJ | U+31b | Ctrl+Shift+Alt+J | | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyK | k | K | | K | k | K | [KeyK] | | -| Ctrl+KeyK | k | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | -| Shift+KeyK | K | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | -| Ctrl+Shift+KeyK | K | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | -| Alt+KeyK | k | Alt+K | | Alt+K | alt+k | Alt+K | alt+[KeyK] | | -| Ctrl+Alt+KeyK | ĸ | Ctrl+Alt+K | | Ctrl+Alt+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | -| Shift+Alt+KeyK | K | Shift+Alt+K | | Shift+Alt+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | -| Ctrl+Shift+Alt+KeyK | & | Ctrl+Shift+Alt+K | | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyL | l | L | | L | l | L | [KeyL] | | -| Ctrl+KeyL | l | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | -| Shift+KeyL | L | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | -| Ctrl+Shift+KeyL | L | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | -| Alt+KeyL | l | Alt+L | | Alt+L | alt+l | Alt+L | alt+[KeyL] | | -| Ctrl+Alt+KeyL | ł | Ctrl+Alt+L | | Ctrl+Alt+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | -| Shift+Alt+KeyL | L | Shift+Alt+L | | Shift+Alt+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | -| Ctrl+Shift+Alt+KeyL | Ł | Ctrl+Shift+Alt+L | | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyM | m | M | | M | m | M | [KeyM] | | -| Ctrl+KeyM | m | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | -| Shift+KeyM | M | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | -| Ctrl+Shift+KeyM | M | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | -| Alt+KeyM | m | Alt+M | | Alt+M | alt+m | Alt+M | alt+[KeyM] | | -| Ctrl+Alt+KeyM | µ | Ctrl+Alt+M | | Ctrl+Alt+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | -| Shift+Alt+KeyM | M | Shift+Alt+M | | Shift+Alt+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | -| Ctrl+Shift+Alt+KeyM | º | Ctrl+Shift+Alt+M | | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyN | n | N | | N | n | N | [KeyN] | | -| Ctrl+KeyN | n | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | -| Shift+KeyN | N | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | -| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | -| Alt+KeyN | n | Alt+N | | Alt+N | alt+n | Alt+N | alt+[KeyN] | | -| Ctrl+Alt+KeyN | n | Ctrl+Alt+N | | Ctrl+Alt+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | -| Shift+Alt+KeyN | N | Shift+Alt+N | | Shift+Alt+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | -| Ctrl+Shift+Alt+KeyN | N | Ctrl+Shift+Alt+N | | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyO | o | O | | O | o | O | [KeyO] | | -| Ctrl+KeyO | o | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | -| Shift+KeyO | O | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | -| Ctrl+Shift+KeyO | O | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | -| Alt+KeyO | o | Alt+O | | Alt+O | alt+o | Alt+O | alt+[KeyO] | | -| Ctrl+Alt+KeyO | œ | Ctrl+Alt+O | | Ctrl+Alt+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | -| Shift+Alt+KeyO | O | Shift+Alt+O | | Shift+Alt+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | -| Ctrl+Shift+Alt+KeyO | Œ | Ctrl+Shift+Alt+O | | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyP | p | P | | P | p | P | [KeyP] | | -| Ctrl+KeyP | p | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | -| Shift+KeyP | P | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | -| Ctrl+Shift+KeyP | P | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | -| Alt+KeyP | p | Alt+P | | Alt+P | alt+p | Alt+P | alt+[KeyP] | | -| Ctrl+Alt+KeyP | þ | Ctrl+Alt+P | | Ctrl+Alt+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | -| Shift+Alt+KeyP | P | Shift+Alt+P | | Shift+Alt+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | -| Ctrl+Shift+Alt+KeyP | Þ | Ctrl+Shift+Alt+P | | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyQ | q | Q | | Q | q | Q | [KeyQ] | | -| Ctrl+KeyQ | q | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | -| Shift+KeyQ | Q | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | -| Ctrl+Shift+KeyQ | Q | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | -| Alt+KeyQ | q | Alt+Q | | Alt+Q | alt+q | Alt+Q | alt+[KeyQ] | | -| Ctrl+Alt+KeyQ | @ | Ctrl+Alt+Q | | Ctrl+Alt+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | -| Shift+Alt+KeyQ | Q | Shift+Alt+Q | | Shift+Alt+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | -| Ctrl+Shift+Alt+KeyQ | Ω | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyR | r | R | | R | r | R | [KeyR] | | -| Ctrl+KeyR | r | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | -| Shift+KeyR | R | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | -| Ctrl+Shift+KeyR | R | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | -| Alt+KeyR | r | Alt+R | | Alt+R | alt+r | Alt+R | alt+[KeyR] | | -| Ctrl+Alt+KeyR | ¶ | Ctrl+Alt+R | | Ctrl+Alt+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | -| Shift+Alt+KeyR | R | Shift+Alt+R | | Shift+Alt+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | -| Ctrl+Shift+Alt+KeyR | ® | Ctrl+Shift+Alt+R | | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyS | s | S | | S | s | S | [KeyS] | | -| Ctrl+KeyS | s | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | -| Shift+KeyS | S | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | -| Ctrl+Shift+KeyS | S | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | -| Alt+KeyS | s | Alt+S | | Alt+S | alt+s | Alt+S | alt+[KeyS] | | -| Ctrl+Alt+KeyS | ß | Ctrl+Alt+S | | Ctrl+Alt+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | -| Shift+Alt+KeyS | S | Shift+Alt+S | | Shift+Alt+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | -| Ctrl+Shift+Alt+KeyS | § | Ctrl+Shift+Alt+S | | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyT | t | T | | T | t | T | [KeyT] | | -| Ctrl+KeyT | t | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | -| Shift+KeyT | T | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | -| Ctrl+Shift+KeyT | T | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | -| Alt+KeyT | t | Alt+T | | Alt+T | alt+t | Alt+T | alt+[KeyT] | | -| Ctrl+Alt+KeyT | ŧ | Ctrl+Alt+T | | Ctrl+Alt+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | -| Shift+Alt+KeyT | T | Shift+Alt+T | | Shift+Alt+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | -| Ctrl+Shift+Alt+KeyT | Ŧ | Ctrl+Shift+Alt+T | | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyU | u | U | | U | u | U | [KeyU] | | -| Ctrl+KeyU | u | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | -| Shift+KeyU | U | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | -| Ctrl+Shift+KeyU | U | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | -| Alt+KeyU | u | Alt+U | | Alt+U | alt+u | Alt+U | alt+[KeyU] | | -| Ctrl+Alt+KeyU | ↓ | Ctrl+Alt+U | | Ctrl+Alt+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | -| Shift+Alt+KeyU | U | Shift+Alt+U | | Shift+Alt+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | -| Ctrl+Shift+Alt+KeyU | ↑ | Ctrl+Shift+Alt+U | | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyV | v | V | | V | v | V | [KeyV] | | -| Ctrl+KeyV | v | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | -| Shift+KeyV | V | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | -| Ctrl+Shift+KeyV | V | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | -| Alt+KeyV | v | Alt+V | | Alt+V | alt+v | Alt+V | alt+[KeyV] | | -| Ctrl+Alt+KeyV | “ | Ctrl+Alt+V | | Ctrl+Alt+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | -| Shift+Alt+KeyV | V | Shift+Alt+V | | Shift+Alt+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | -| Ctrl+Shift+Alt+KeyV | ‘ | Ctrl+Shift+Alt+V | | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyW | w | W | | W | w | W | [KeyW] | | -| Ctrl+KeyW | w | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | -| Shift+KeyW | W | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | -| Ctrl+Shift+KeyW | W | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | -| Alt+KeyW | w | Alt+W | | Alt+W | alt+w | Alt+W | alt+[KeyW] | | -| Ctrl+Alt+KeyW | ł | Ctrl+Alt+W | | Ctrl+Alt+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | -| Shift+Alt+KeyW | W | Shift+Alt+W | | Shift+Alt+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | -| Ctrl+Shift+Alt+KeyW | Ł | Ctrl+Shift+Alt+W | | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyX | x | X | | X | x | X | [KeyX] | | -| Ctrl+KeyX | x | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | -| Shift+KeyX | X | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | -| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | -| Alt+KeyX | x | Alt+X | | Alt+X | alt+x | Alt+X | alt+[KeyX] | | -| Ctrl+Alt+KeyX | » | Ctrl+Alt+X | | Ctrl+Alt+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | -| Shift+Alt+KeyX | X | Shift+Alt+X | | Shift+Alt+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | -| Ctrl+Shift+Alt+KeyX | > | Ctrl+Shift+Alt+X | | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | -| | | Shift+. | 1 | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyY | z | Z | | Z | z | Z | [KeyY] | | -| Ctrl+KeyY | z | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyY] | | -| Shift+KeyY | Z | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyY] | | -| Ctrl+Shift+KeyY | Z | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyY] | | -| Alt+KeyY | z | Alt+Z | | Alt+Z | alt+z | Alt+Z | alt+[KeyY] | | -| Ctrl+Alt+KeyY | ← | Ctrl+Alt+Z | | Ctrl+Alt+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyY] | | -| Shift+Alt+KeyY | Z | Shift+Alt+Z | | Shift+Alt+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyY] | | -| Ctrl+Shift+Alt+KeyY | ¥ | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyY] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyZ | y | Y | | Y | y | Y | [KeyZ] | | -| Ctrl+KeyZ | y | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyZ] | | -| Shift+KeyZ | Y | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyZ] | | -| Ctrl+Shift+KeyZ | Y | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyZ] | | -| Alt+KeyZ | y | Alt+Y | | Alt+Y | alt+y | Alt+Y | alt+[KeyZ] | | -| Ctrl+Alt+KeyZ | « | Ctrl+Alt+Y | | Ctrl+Alt+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyZ] | | -| Shift+Alt+KeyZ | Y | Shift+Alt+Y | | Shift+Alt+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyZ] | | -| Ctrl+Shift+Alt+KeyZ | < | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyZ] | | -| | | Shift+, | 1 | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit1 | 1 | 1 | | 1 | 1 | 1 | [Digit1] | | -| Ctrl+Digit1 | 1 | Ctrl+1 | | Ctrl+1 | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | | -| Shift+Digit1 | + | Shift+1 | | Shift+1 | shift+1 | Shift+1 | shift+[Digit1] | | -| | | Shift+= | | | | | | | -| Ctrl+Shift+Digit1 | + | Ctrl+Shift+1 | | Ctrl+Shift+1 | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | | -| | | Ctrl+Shift+= | | | | | | | -| Alt+Digit1 | 1 | Alt+1 | | Alt+1 | alt+1 | Alt+1 | alt+[Digit1] | | -| Ctrl+Alt+Digit1 | | | Ctrl+Alt+1 | | Ctrl+Alt+1 | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | | -| | | Shift+\ | 1 | | | | | | -| Shift+Alt+Digit1 | + | Shift+Alt+1 | | Shift+Alt+1 | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | | -| | | Shift+Alt+= | | | | | | | -| Ctrl+Shift+Alt+Digit1 | ¡ | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | | -| | | Ctrl+Shift+Alt+= | | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit2 | 2 | 2 | | 2 | 2 | 2 | [Digit2] | | -| Ctrl+Digit2 | 2 | Ctrl+2 | | Ctrl+2 | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | | -| Shift+Digit2 | " | Shift+2 | | Shift+2 | shift+2 | Shift+2 | shift+[Digit2] | | -| | | Shift+' | | | | | | | -| Ctrl+Shift+Digit2 | " | Ctrl+Shift+2 | | Ctrl+Shift+2 | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | | -| | | Ctrl+Shift+' | | | | | | | -| Alt+Digit2 | 2 | Alt+2 | | Alt+2 | alt+2 | Alt+2 | alt+[Digit2] | | -| Ctrl+Alt+Digit2 | @ | Ctrl+Alt+2 | | Ctrl+Alt+2 | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | | -| Shift+Alt+Digit2 | " | Shift+Alt+2 | | Shift+Alt+2 | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | | -| | | Shift+Alt+' | | | | | | | -| Ctrl+Shift+Alt+Digit2 | ⅛ | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | | -| | | Ctrl+Shift+Alt+' | | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit3 | 3 | 3 | | 3 | 3 | 3 | [Digit3] | | -| Ctrl+Digit3 | 3 | Ctrl+3 | | Ctrl+3 | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | | -| Shift+Digit3 | * | Shift+3 | | Shift+3 | shift+3 | Shift+3 | shift+[Digit3] | | -| Ctrl+Shift+Digit3 | * | Ctrl+Shift+3 | | Ctrl+Shift+3 | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | | -| Alt+Digit3 | 3 | Alt+3 | | Alt+3 | alt+3 | Alt+3 | alt+[Digit3] | | -| Ctrl+Alt+Digit3 | # | Ctrl+Alt+3 | | Ctrl+Alt+3 | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | | -| Shift+Alt+Digit3 | * | Shift+Alt+3 | | Shift+Alt+3 | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | | -| Ctrl+Shift+Alt+Digit3 | £ | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit4 | 4 | 4 | | 4 | 4 | 4 | [Digit4] | | -| Ctrl+Digit4 | 4 | Ctrl+4 | | Ctrl+4 | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | | -| Shift+Digit4 | ç | Shift+4 | | Shift+4 | shift+4 | Shift+4 | shift+[Digit4] | | -| Ctrl+Shift+Digit4 | ç | Ctrl+Shift+4 | | Ctrl+Shift+4 | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | | -| Alt+Digit4 | 4 | Alt+4 | | Alt+4 | alt+4 | Alt+4 | alt+[Digit4] | | -| Ctrl+Alt+Digit4 | ¼ | Ctrl+Alt+4 | | Ctrl+Alt+4 | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | | -| Shift+Alt+Digit4 | ç | Shift+Alt+4 | | Shift+Alt+4 | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | | -| Ctrl+Shift+Alt+Digit4 | $ | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit5 | 5 | 5 | | 5 | 5 | 5 | [Digit5] | | -| Ctrl+Digit5 | 5 | Ctrl+5 | | Ctrl+5 | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | | -| Shift+Digit5 | % | Shift+5 | | Shift+5 | shift+5 | Shift+5 | shift+[Digit5] | | -| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+5 | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | | -| Alt+Digit5 | 5 | Alt+5 | | Alt+5 | alt+5 | Alt+5 | alt+[Digit5] | | -| Ctrl+Alt+Digit5 | ½ | Ctrl+Alt+5 | | Ctrl+Alt+5 | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | | -| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Alt+5 | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | | -| Ctrl+Shift+Alt+Digit5 | ⅜ | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit6 | 6 | 6 | | 6 | 6 | 6 | [Digit6] | | -| Ctrl+Digit6 | 6 | Ctrl+6 | | Ctrl+6 | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | | -| Shift+Digit6 | & | Shift+6 | | Shift+6 | shift+6 | Shift+6 | shift+[Digit6] | | -| Ctrl+Shift+Digit6 | & | Ctrl+Shift+6 | | Ctrl+Shift+6 | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | | -| Alt+Digit6 | 6 | Alt+6 | | Alt+6 | alt+6 | Alt+6 | alt+[Digit6] | | -| Ctrl+Alt+Digit6 | ¬ | Ctrl+Alt+6 | | Ctrl+Alt+6 | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | | -| Shift+Alt+Digit6 | & | Shift+Alt+6 | | Shift+Alt+6 | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | | -| Ctrl+Shift+Alt+Digit6 | ⅝ | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit7 | 7 | 7 | | 7 | 7 | 7 | [Digit7] | | -| Ctrl+Digit7 | 7 | Ctrl+7 | | Ctrl+7 | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | | -| Shift+Digit7 | / | Shift+7 | | Shift+7 | shift+7 | Shift+7 | shift+[Digit7] | | -| | | / | | | | | | | -| Ctrl+Shift+Digit7 | / | Ctrl+Shift+7 | | Ctrl+Shift+7 | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | | -| | | Ctrl+/ | | | | | | | -| Alt+Digit7 | 7 | Alt+7 | | Alt+7 | alt+7 | Alt+7 | alt+[Digit7] | | -| Ctrl+Alt+Digit7 | | | Ctrl+Alt+7 | | Ctrl+Alt+7 | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | | -| | | Shift+\ | 2 | | | | | | -| Shift+Alt+Digit7 | / | Shift+Alt+7 | | Shift+Alt+7 | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | | -| | | Alt+/ | | | | | | | -| Ctrl+Shift+Alt+Digit7 | ⅞ | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | | -| | | Ctrl+Alt+/ | | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit8 | 8 | 8 | | 8 | 8 | 8 | [Digit8] | | -| Ctrl+Digit8 | 8 | Ctrl+8 | | Ctrl+8 | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | | -| Shift+Digit8 | ( | Shift+8 | | Shift+8 | shift+8 | Shift+8 | shift+[Digit8] | | -| Ctrl+Shift+Digit8 | ( | Ctrl+Shift+8 | | Ctrl+Shift+8 | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | | -| Alt+Digit8 | 8 | Alt+8 | | Alt+8 | alt+8 | Alt+8 | alt+[Digit8] | | -| Ctrl+Alt+Digit8 | ¢ | Ctrl+Alt+8 | | Ctrl+Alt+8 | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | | -| Shift+Alt+Digit8 | ( | Shift+Alt+8 | | Shift+Alt+8 | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | | -| Ctrl+Shift+Alt+Digit8 | ™ | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit9 | 9 | 9 | | 9 | 9 | 9 | [Digit9] | | -| Ctrl+Digit9 | 9 | Ctrl+9 | | Ctrl+9 | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | | -| Shift+Digit9 | ) | Shift+9 | | Shift+9 | shift+9 | Shift+9 | shift+[Digit9] | | -| Ctrl+Shift+Digit9 | ) | Ctrl+Shift+9 | | Ctrl+Shift+9 | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | | -| Alt+Digit9 | 9 | Alt+9 | | Alt+9 | alt+9 | Alt+9 | alt+[Digit9] | | -| Ctrl+Alt+Digit9 | ] | Ctrl+Alt+9 | | Ctrl+Alt+9 | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | | -| | | ] | 1 | | | | | | -| Shift+Alt+Digit9 | ) | Shift+Alt+9 | | Shift+Alt+9 | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | | -| Ctrl+Shift+Alt+Digit9 | ± | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit0 | 0 | 0 | | 0 | 0 | 0 | [Digit0] | | -| Ctrl+Digit0 | 0 | Ctrl+0 | | Ctrl+0 | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | | -| Shift+Digit0 | = | Shift+0 | | Shift+0 | shift+0 | Shift+0 | shift+[Digit0] | | -| | | = | | | | | | | -| Ctrl+Shift+Digit0 | = | Ctrl+Shift+0 | | Ctrl+Shift+0 | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | | -| | | Ctrl+= | | | | | | | -| Alt+Digit0 | 0 | Alt+0 | | Alt+0 | alt+0 | Alt+0 | alt+[Digit0] | | -| Ctrl+Alt+Digit0 | } | Ctrl+Alt+0 | | Ctrl+Alt+0 | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | | -| | | Shift+] | 1 | | | | | | -| Shift+Alt+Digit0 | = | Shift+Alt+0 | | Shift+Alt+0 | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | | -| | | Alt+= | | | | | | | -| Ctrl+Shift+Alt+Digit0 | ° | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | | -| | | Ctrl+Alt+= | | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Minus | ' | ' | | ' | [Minus] | null | [Minus] | NO | -| Ctrl+Minus | ' | Ctrl+' | | Ctrl+' | ctrl+[Minus] | null | ctrl+[Minus] | NO | -| Shift+Minus | ? | Shift+/ | | Shift+' | shift+[Minus] | null | shift+[Minus] | NO | -| Ctrl+Shift+Minus | ? | Ctrl+Shift+/ | | Ctrl+Shift+' | ctrl+shift+[Minus] | null | ctrl+shift+[Minus] | NO | -| Alt+Minus | ' | Alt+' | | Alt+' | alt+[Minus] | null | alt+[Minus] | NO | -| Ctrl+Alt+Minus | ´ | Ctrl+Alt+' | | Ctrl+Alt+' | ctrl+alt+[Minus] | null | ctrl+alt+[Minus] | NO | -| Shift+Alt+Minus | ? | Shift+Alt+/ | | Shift+Alt+' | shift+alt+[Minus] | null | shift+alt+[Minus] | NO | -| Ctrl+Shift+Alt+Minus | ¿ | Ctrl+Shift+Alt+/ | | Ctrl+Shift+Alt+' | ctrl+shift+alt+[Minus] | null | ctrl+shift+alt+[Minus] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Equal | ^ | | | ^ | [Equal] | null | [Equal] | NO | -| Ctrl+Equal | ^ | | | Ctrl+^ | ctrl+[Equal] | null | ctrl+[Equal] | NO | -| Shift+Equal | ` | ` | | Shift+^ | shift+[Equal] | null | shift+[Equal] | NO | -| Ctrl+Shift+Equal | ` | Ctrl+` | | Ctrl+Shift+^ | ctrl+shift+[Equal] | null | ctrl+shift+[Equal] | NO | -| Alt+Equal | ^ | | | Alt+^ | alt+[Equal] | null | alt+[Equal] | NO | -| Ctrl+Alt+Equal | ˜ | | | Ctrl+Alt+^ | ctrl+alt+[Equal] | null | ctrl+alt+[Equal] | NO | -| Shift+Alt+Equal | ` | Alt+` | | Shift+Alt+^ | shift+alt+[Equal] | null | shift+alt+[Equal] | NO | -| Ctrl+Shift+Alt+Equal | U+328 | Ctrl+Alt+` | | Ctrl+Shift+Alt+^ | ctrl+shift+alt+[Equal] | null | ctrl+shift+alt+[Equal] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketLeft | ü | | | ü | [BracketLeft] | null | [BracketLeft] | NO | -| Ctrl+BracketLeft | ü | | | Ctrl+ü | ctrl+[BracketLeft] | null | ctrl+[BracketLeft] | NO | -| Shift+BracketLeft | è | | | Shift+ü | shift+[BracketLeft] | null | shift+[BracketLeft] | NO | -| Ctrl+Shift+BracketLeft | è | | | Ctrl+Shift+ü | ctrl+shift+[BracketLeft] | null | ctrl+shift+[BracketLeft] | NO | -| Alt+BracketLeft | ü | | | Alt+ü | alt+[BracketLeft] | null | alt+[BracketLeft] | NO | -| Ctrl+Alt+BracketLeft | [ | [ | | Ctrl+Alt+ü | ctrl+alt+[BracketLeft] | null | ctrl+alt+[BracketLeft] | NO | -| Shift+Alt+BracketLeft | è | | | Shift+Alt+ü | shift+alt+[BracketLeft] | null | shift+alt+[BracketLeft] | NO | -| Ctrl+Shift+Alt+BracketLeft | ˚ | | | Ctrl+Shift+Alt+ü | ctrl+shift+alt+[BracketLeft] | null | ctrl+shift+alt+[BracketLeft] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketRight | ¨ | | | ¨ | [BracketRight] | null | [BracketRight] | NO | -| Ctrl+BracketRight | ¨ | | | Ctrl+¨ | ctrl+[BracketRight] | null | ctrl+[BracketRight] | NO | -| Shift+BracketRight | ! | | | Shift+¨ | shift+[BracketRight] | null | shift+[BracketRight] | NO | -| Ctrl+Shift+BracketRight | ! | | | Ctrl+Shift+¨ | ctrl+shift+[BracketRight] | null | ctrl+shift+[BracketRight] | NO | -| Alt+BracketRight | ¨ | | | Alt+¨ | alt+[BracketRight] | null | alt+[BracketRight] | NO | -| Ctrl+Alt+BracketRight | ] | ] | 2 | Ctrl+Alt+¨ | ctrl+alt+[BracketRight] | null | ctrl+alt+[BracketRight] | NO | -| Shift+Alt+BracketRight | ! | | | Shift+Alt+¨ | shift+alt+[BracketRight] | null | shift+alt+[BracketRight] | NO | -| Ctrl+Shift+Alt+BracketRight | ¯ | | | Ctrl+Shift+Alt+¨ | ctrl+shift+alt+[BracketRight] | null | ctrl+shift+alt+[BracketRight] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backslash | $ | | | $ | [Backslash] | null | [Backslash] | NO | -| Ctrl+Backslash | $ | | | Ctrl+$ | ctrl+[Backslash] | null | ctrl+[Backslash] | NO | -| Shift+Backslash | £ | | | Shift+$ | shift+[Backslash] | null | shift+[Backslash] | NO | -| Ctrl+Shift+Backslash | £ | | | Ctrl+Shift+$ | ctrl+shift+[Backslash] | null | ctrl+shift+[Backslash] | NO | -| Alt+Backslash | $ | | | Alt+$ | alt+[Backslash] | null | alt+[Backslash] | NO | -| Ctrl+Alt+Backslash | } | Shift+] | 2 | Ctrl+Alt+$ | ctrl+alt+[Backslash] | null | ctrl+alt+[Backslash] | NO | -| Shift+Alt+Backslash | £ | | | Shift+Alt+$ | shift+alt+[Backslash] | null | shift+alt+[Backslash] | NO | -| Ctrl+Shift+Alt+Backslash | ˘ | | | Ctrl+Shift+Alt+$ | ctrl+shift+alt+[Backslash] | null | ctrl+shift+alt+[Backslash] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlHash | --- | | | null | null | null | null | | -| Ctrl+IntlHash | --- | | | null | null | null | null | | -| Shift+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | -| Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | -| Shift+Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Semicolon | ö | | | ö | [Semicolon] | null | [Semicolon] | NO | -| Ctrl+Semicolon | ö | | | Ctrl+ö | ctrl+[Semicolon] | null | ctrl+[Semicolon] | NO | -| Shift+Semicolon | é | | | Shift+ö | shift+[Semicolon] | null | shift+[Semicolon] | NO | -| Ctrl+Shift+Semicolon | é | | | Ctrl+Shift+ö | ctrl+shift+[Semicolon] | null | ctrl+shift+[Semicolon] | NO | -| Alt+Semicolon | ö | | | Alt+ö | alt+[Semicolon] | null | alt+[Semicolon] | NO | -| Ctrl+Alt+Semicolon | ´ | | | Ctrl+Alt+ö | ctrl+alt+[Semicolon] | null | ctrl+alt+[Semicolon] | NO | -| Shift+Alt+Semicolon | é | | | Shift+Alt+ö | shift+alt+[Semicolon] | null | shift+alt+[Semicolon] | NO | -| Ctrl+Shift+Alt+Semicolon | ˝ | | | Ctrl+Shift+Alt+ö | ctrl+shift+alt+[Semicolon] | null | ctrl+shift+alt+[Semicolon] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Quote | ä | | | ä | [Quote] | null | [Quote] | NO | -| Ctrl+Quote | ä | | | Ctrl+ä | ctrl+[Quote] | null | ctrl+[Quote] | NO | -| Shift+Quote | à | | | Shift+ä | shift+[Quote] | null | shift+[Quote] | NO | -| Ctrl+Shift+Quote | à | | | Ctrl+Shift+ä | ctrl+shift+[Quote] | null | ctrl+shift+[Quote] | NO | -| Alt+Quote | ä | | | Alt+ä | alt+[Quote] | null | alt+[Quote] | NO | -| Ctrl+Alt+Quote | { | Shift+[ | | Ctrl+Alt+ä | ctrl+alt+[Quote] | null | ctrl+alt+[Quote] | NO | -| Shift+Alt+Quote | à | | | Shift+Alt+ä | shift+alt+[Quote] | null | shift+alt+[Quote] | NO | -| Ctrl+Shift+Alt+Quote | U+30c | | | Ctrl+Shift+Alt+ä | ctrl+shift+alt+[Quote] | null | ctrl+shift+alt+[Quote] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backquote | § | | | § | [Backquote] | null | [Backquote] | NO | -| Ctrl+Backquote | § | | | Ctrl+§ | ctrl+[Backquote] | null | ctrl+[Backquote] | NO | -| Shift+Backquote | ° | | | Shift+§ | shift+[Backquote] | null | shift+[Backquote] | NO | -| Ctrl+Shift+Backquote | ° | | | Ctrl+Shift+§ | ctrl+shift+[Backquote] | null | ctrl+shift+[Backquote] | NO | -| Alt+Backquote | § | | | Alt+§ | alt+[Backquote] | null | alt+[Backquote] | NO | -| Ctrl+Alt+Backquote | ¬ | | | Ctrl+Alt+§ | ctrl+alt+[Backquote] | null | ctrl+alt+[Backquote] | NO | -| Shift+Alt+Backquote | ° | | | Shift+Alt+§ | shift+alt+[Backquote] | null | shift+alt+[Backquote] | NO | -| Ctrl+Shift+Alt+Backquote | ¬ | | | Ctrl+Shift+Alt+§ | ctrl+shift+alt+[Backquote] | null | ctrl+shift+alt+[Backquote] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Comma | , | , | | , | [Comma] | null | [Comma] | NO | -| Ctrl+Comma | , | Ctrl+, | | Ctrl+, | ctrl+[Comma] | null | ctrl+[Comma] | NO | -| Shift+Comma | ; | ; | | Shift+, | shift+[Comma] | null | shift+[Comma] | NO | -| Ctrl+Shift+Comma | ; | Ctrl+; | | Ctrl+Shift+, | ctrl+shift+[Comma] | null | ctrl+shift+[Comma] | NO | -| Alt+Comma | , | Alt+, | | Alt+, | alt+[Comma] | null | alt+[Comma] | NO | -| Ctrl+Alt+Comma | ─ | Ctrl+Alt+, | | Ctrl+Alt+, | ctrl+alt+[Comma] | null | ctrl+alt+[Comma] | NO | -| Shift+Alt+Comma | ; | Alt+; | | Shift+Alt+, | shift+alt+[Comma] | null | shift+alt+[Comma] | NO | -| Ctrl+Shift+Alt+Comma | × | Ctrl+Alt+; | | Ctrl+Shift+Alt+, | ctrl+shift+alt+[Comma] | null | ctrl+shift+alt+[Comma] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Period | . | . | | . | [Period] | null | [Period] | NO | -| Ctrl+Period | . | Ctrl+. | | Ctrl+. | ctrl+[Period] | null | ctrl+[Period] | NO | -| Shift+Period | : | Shift+; | | Shift+. | shift+[Period] | null | shift+[Period] | NO | -| Ctrl+Shift+Period | : | Ctrl+Shift+; | | Ctrl+Shift+. | ctrl+shift+[Period] | null | ctrl+shift+[Period] | NO | -| Alt+Period | . | Alt+. | | Alt+. | alt+[Period] | null | alt+[Period] | NO | -| Ctrl+Alt+Period | · | Ctrl+Alt+. | | Ctrl+Alt+. | ctrl+alt+[Period] | null | ctrl+alt+[Period] | NO | -| Shift+Alt+Period | : | Shift+Alt+; | | Shift+Alt+. | shift+alt+[Period] | null | shift+alt+[Period] | NO | -| Ctrl+Shift+Alt+Period | ÷ | Ctrl+Shift+Alt+; | | Ctrl+Shift+Alt+. | ctrl+shift+alt+[Period] | null | ctrl+shift+alt+[Period] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Slash | - | - | | - | - | null | [Slash] | | -| Ctrl+Slash | - | Ctrl+- | | Ctrl+- | ctrl+- | null | ctrl+[Slash] | | -| Shift+Slash | _ | Shift+- | | Shift+- | shift+- | null | shift+[Slash] | | -| Ctrl+Shift+Slash | _ | Ctrl+Shift+- | | Ctrl+Shift+- | ctrl+shift+- | null | ctrl+shift+[Slash] | | -| Alt+Slash | - | Alt+- | | Alt+- | alt+- | null | alt+[Slash] | | -| Ctrl+Alt+Slash | U+323 | Ctrl+Alt+- | | Ctrl+Alt+- | ctrl+alt+- | null | ctrl+alt+[Slash] | | -| Shift+Alt+Slash | _ | Shift+Alt+- | | Shift+Alt+- | shift+alt+- | null | shift+alt+[Slash] | | -| Ctrl+Shift+Alt+Slash | ˙ | Ctrl+Shift+Alt+- | | Ctrl+Shift+Alt+- | ctrl+shift+alt+- | null | ctrl+shift+alt+[Slash] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | -| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | -| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | -| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | -| Alt+ArrowUp | --- | Alt+UpArrow | | Alt+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | -| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Alt+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | -| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Alt+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | -| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | -| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | -| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | -| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | -| Alt+Numpad0 | --- | Alt+NumPad0 | | Alt+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | -| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | -| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Alt+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | -| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlBackslash | < | Shift+, | 2 | < | [IntlBackslash] | null | [IntlBackslash] | NO | -| Ctrl+IntlBackslash | < | Ctrl+Shift+, | | Ctrl+< | ctrl+[IntlBackslash] | null | ctrl+[IntlBackslash] | NO | -| Shift+IntlBackslash | > | Shift+. | 2 | Shift+< | shift+[IntlBackslash] | null | shift+[IntlBackslash] | NO | -| Ctrl+Shift+IntlBackslash | > | Ctrl+Shift+. | | Ctrl+Shift+< | ctrl+shift+[IntlBackslash] | null | ctrl+shift+[IntlBackslash] | NO | -| Alt+IntlBackslash | < | Shift+Alt+, | | Alt+< | alt+[IntlBackslash] | null | alt+[IntlBackslash] | NO | -| Ctrl+Alt+IntlBackslash | \ | \ | | Ctrl+Alt+< | ctrl+alt+[IntlBackslash] | null | ctrl+alt+[IntlBackslash] | NO | -| Shift+Alt+IntlBackslash | > | Shift+Alt+. | | Shift+Alt+< | shift+alt+[IntlBackslash] | null | shift+alt+[IntlBackslash] | NO | -| Ctrl+Shift+Alt+IntlBackslash | ¦ | Ctrl+Shift+Alt+. | | Ctrl+Shift+Alt+< | ctrl+shift+alt+[IntlBackslash] | null | ctrl+shift+alt+[IntlBackslash] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | -| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | -| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | -| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | -| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | -| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | -| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | -| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | -| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | -| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | -| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | -| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | -| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | -| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | -| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/linux_en_uk.js b/src/vs/workbench/services/keybinding/test/electron-browser/linux_en_uk.js deleted file mode 100644 index 379e7355c8e..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/linux_en_uk.js +++ /dev/null @@ -1,1046 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -define({ - Sleep: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - WakeUp: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - KeyA: { - value: 'a', - withShift: 'A', - withAltGr: 'æ', - withShiftAltGr: 'Æ' - }, - KeyB: { - value: 'b', - withShift: 'B', - withAltGr: '”', - withShiftAltGr: '’' - }, - KeyC: { - value: 'c', - withShift: 'C', - withAltGr: '¢', - withShiftAltGr: '©' - }, - KeyD: { - value: 'd', - withShift: 'D', - withAltGr: 'ð', - withShiftAltGr: 'Ð' - }, - KeyE: { - value: 'e', - withShift: 'E', - withAltGr: 'e', - withShiftAltGr: 'E' - }, - KeyF: { - value: 'f', - withShift: 'F', - withAltGr: 'đ', - withShiftAltGr: 'ª' - }, - KeyG: { - value: 'g', - withShift: 'G', - withAltGr: 'ŋ', - withShiftAltGr: 'Ŋ' - }, - KeyH: { - value: 'h', - withShift: 'H', - withAltGr: 'ħ', - withShiftAltGr: 'Ħ' - }, - KeyI: { - value: 'i', - withShift: 'I', - withAltGr: '→', - withShiftAltGr: 'ı' - }, - KeyJ: { - value: 'j', - withShift: 'J', - withAltGr: '̉', - withShiftAltGr: '̛' - }, - KeyK: { - value: 'k', - withShift: 'K', - withAltGr: 'ĸ', - withShiftAltGr: '&' - }, - KeyL: { - value: 'l', - withShift: 'L', - withAltGr: 'ł', - withShiftAltGr: 'Ł' - }, - KeyM: { - value: 'm', - withShift: 'M', - withAltGr: 'µ', - withShiftAltGr: 'º' - }, - KeyN: { - value: 'n', - withShift: 'N', - withAltGr: 'n', - withShiftAltGr: 'N' - }, - KeyO: { - value: 'o', - withShift: 'O', - withAltGr: 'ø', - withShiftAltGr: 'Ø' - }, - KeyP: { - value: 'p', - withShift: 'P', - withAltGr: 'þ', - withShiftAltGr: 'Þ' - }, - KeyQ: { - value: 'q', - withShift: 'Q', - withAltGr: '@', - withShiftAltGr: 'Ω' - }, - KeyR: { - value: 'r', - withShift: 'R', - withAltGr: '¶', - withShiftAltGr: '®' - }, - KeyS: { - value: 's', - withShift: 'S', - withAltGr: 'ß', - withShiftAltGr: '§' - }, - KeyT: { - value: 't', - withShift: 'T', - withAltGr: 'ŧ', - withShiftAltGr: 'Ŧ' - }, - KeyU: { - value: 'u', - withShift: 'U', - withAltGr: '↓', - withShiftAltGr: '↑' - }, - KeyV: { - value: 'v', - withShift: 'V', - withAltGr: '“', - withShiftAltGr: '‘' - }, - KeyW: { - value: 'w', - withShift: 'W', - withAltGr: 'ł', - withShiftAltGr: 'Ł' - }, - KeyX: { - value: 'x', - withShift: 'X', - withAltGr: '»', - withShiftAltGr: '>' - }, - KeyY: { - value: 'y', - withShift: 'Y', - withAltGr: '←', - withShiftAltGr: '¥' - }, - KeyZ: { - value: 'z', - withShift: 'Z', - withAltGr: '«', - withShiftAltGr: '<' - }, - Digit1: { - value: '1', - withShift: '!', - withAltGr: '¹', - withShiftAltGr: '¡' - }, - Digit2: { - value: '2', - withShift: '"', - withAltGr: '²', - withShiftAltGr: '⅛' - }, - Digit3: { - value: '3', - withShift: '£', - withAltGr: '³', - withShiftAltGr: '£' - }, - Digit4: { - value: '4', - withShift: '$', - withAltGr: '€', - withShiftAltGr: '¼' - }, - Digit5: { - value: '5', - withShift: '%', - withAltGr: '½', - withShiftAltGr: '⅜' - }, - Digit6: { - value: '6', - withShift: '^', - withAltGr: '¾', - withShiftAltGr: '⅝' - }, - Digit7: { - value: '7', - withShift: '&', - withAltGr: '{', - withShiftAltGr: '⅞' - }, - Digit8: { - value: '8', - withShift: '*', - withAltGr: '[', - withShiftAltGr: '™' - }, - Digit9: { - value: '9', - withShift: '(', - withAltGr: ']', - withShiftAltGr: '±' - }, - Digit0: { - value: '0', - withShift: ')', - withAltGr: '}', - withShiftAltGr: '°' - }, - Enter: { - value: '\r', - withShift: '\r', - withAltGr: '\r', - withShiftAltGr: '\r' - }, - Escape: { - value: '\u001b', - withShift: '\u001b', - withAltGr: '\u001b', - withShiftAltGr: '\u001b' - }, - Backspace: { - value: '\b', - withShift: '\b', - withAltGr: '\b', - withShiftAltGr: '\b' - }, - Tab: { - value: '\t', - withShift: '', - withAltGr: '\t', - withShiftAltGr: '' - }, - Space: { - value: ' ', - withShift: ' ', - withAltGr: ' ', - withShiftAltGr: ' ' - }, - Minus: { - value: '-', - withShift: '_', - withAltGr: '\\', - withShiftAltGr: '¿' - }, - Equal: { - value: '=', - withShift: '+', - withAltGr: '̧', - withShiftAltGr: '̨' - }, - BracketLeft: { - value: '[', - withShift: '{', - withAltGr: '̈', - withShiftAltGr: '̊' - }, - BracketRight: { - value: ']', - withShift: '}', - withAltGr: '̃', - withShiftAltGr: '̄' - }, - Backslash: { - value: '#', - withShift: '~', - withAltGr: '̀', - withShiftAltGr: '̆' - }, - Semicolon: { - value: ';', - withShift: ':', - withAltGr: '́', - withShiftAltGr: '̋' - }, - Quote: { - value: '\'', - withShift: '@', - withAltGr: '̂', - withShiftAltGr: '̌' - }, - Backquote: { - value: '`', - withShift: '¬', - withAltGr: '|', - withShiftAltGr: '|' - }, - Comma: { - value: ',', - withShift: '<', - withAltGr: '─', - withShiftAltGr: '×' - }, - Period: { - value: '.', - withShift: '>', - withAltGr: '·', - withShiftAltGr: '÷' - }, - Slash: { - value: '/', - withShift: '?', - withAltGr: '̣', - withShiftAltGr: '̇' - }, - CapsLock: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F1: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F2: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F3: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F4: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F5: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F6: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F7: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F8: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F9: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F10: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F11: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F12: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PrintScreen: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ScrollLock: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Pause: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Insert: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Home: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PageUp: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Delete: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - End: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PageDown: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowRight: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowLeft: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowDown: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowUp: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumLock: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadDivide: { - value: '/', - withShift: '/', - withAltGr: '/', - withShiftAltGr: '/' - }, - NumpadMultiply: { - value: '*', - withShift: '*', - withAltGr: '*', - withShiftAltGr: '*' - }, - NumpadSubtract: { - value: '-', - withShift: '-', - withAltGr: '-', - withShiftAltGr: '-' - }, - NumpadAdd: { - value: '+', - withShift: '+', - withAltGr: '+', - withShiftAltGr: '+' - }, - NumpadEnter: { - value: '\r', - withShift: '\r', - withAltGr: '\r', - withShiftAltGr: '\r' - }, - Numpad1: { - value: '', - withShift: '1', - withAltGr: '', - withShiftAltGr: '1' - }, - Numpad2: { - value: '', - withShift: '2', - withAltGr: '', - withShiftAltGr: '2' - }, - Numpad3: { - value: '', - withShift: '3', - withAltGr: '', - withShiftAltGr: '3' - }, - Numpad4: { - value: '', - withShift: '4', - withAltGr: '', - withShiftAltGr: '4' - }, - Numpad5: { - value: '', - withShift: '5', - withAltGr: '', - withShiftAltGr: '5' - }, - Numpad6: { - value: '', - withShift: '6', - withAltGr: '', - withShiftAltGr: '6' - }, - Numpad7: { - value: '', - withShift: '7', - withAltGr: '', - withShiftAltGr: '7' - }, - Numpad8: { - value: '', - withShift: '8', - withAltGr: '', - withShiftAltGr: '8' - }, - Numpad9: { - value: '', - withShift: '9', - withAltGr: '', - withShiftAltGr: '9' - }, - Numpad0: { - value: '', - withShift: '0', - withAltGr: '', - withShiftAltGr: '0' - }, - NumpadDecimal: { - value: '', - withShift: '.', - withAltGr: '', - withShiftAltGr: '.' - }, - IntlBackslash: { - value: '\\', - withShift: '|', - withAltGr: '|', - withShiftAltGr: '¦' - }, - ContextMenu: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Power: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadEqual: { - value: '=', - withShift: '=', - withAltGr: '=', - withShiftAltGr: '=' - }, - F13: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F14: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F15: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F16: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F17: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F18: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F19: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F20: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F21: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F22: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F23: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F24: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Open: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Help: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Select: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Again: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Undo: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Cut: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Copy: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Paste: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Find: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeMute: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeUp: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeDown: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadComma: { - value: '.', - withShift: '.', - withAltGr: '.', - withShiftAltGr: '.' - }, - IntlRo: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - KanaMode: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - IntlYen: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Convert: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NonConvert: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang1: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang2: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang3: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang4: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang5: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadParenLeft: { - value: '(', - withShift: '(', - withAltGr: '(', - withShiftAltGr: '(' - }, - NumpadParenRight: { - value: ')', - withShift: ')', - withAltGr: ')', - withShiftAltGr: ')' - }, - ControlLeft: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ShiftLeft: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AltLeft: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MetaLeft: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ControlRight: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ShiftRight: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AltRight: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MetaRight: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrightnessUp: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrightnessDown: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaPlay: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaRecord: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaFastForward: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaRewind: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaTrackNext: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaTrackPrevious: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaStop: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Eject: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaPlayPause: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaSelect: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchMail: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchApp2: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchApp1: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - SelectTask: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchScreenSaver: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserSearch: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserHome: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserBack: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserForward: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserStop: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserRefresh: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserFavorites: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MailReply: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MailForward: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MailSend: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - } -}); diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/linux_en_uk.txt b/src/vs/workbench/services/keybinding/test/electron-browser/linux_en_uk.txt deleted file mode 100644 index 9d1ab7184c4..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/linux_en_uk.txt +++ /dev/null @@ -1,517 +0,0 @@ -isUSStandard: false ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyA | a | A | | A | a | A | [KeyA] | | -| Ctrl+KeyA | a | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | -| Shift+KeyA | A | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | -| Ctrl+Shift+KeyA | A | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | -| Alt+KeyA | a | Alt+A | | Alt+A | alt+a | Alt+A | alt+[KeyA] | | -| Ctrl+Alt+KeyA | æ | Ctrl+Alt+A | | Ctrl+Alt+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | -| Shift+Alt+KeyA | A | Shift+Alt+A | | Shift+Alt+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | -| Ctrl+Shift+Alt+KeyA | Æ | Ctrl+Shift+Alt+A | | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyB | b | B | | B | b | B | [KeyB] | | -| Ctrl+KeyB | b | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | -| Shift+KeyB | B | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | -| Ctrl+Shift+KeyB | B | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | -| Alt+KeyB | b | Alt+B | | Alt+B | alt+b | Alt+B | alt+[KeyB] | | -| Ctrl+Alt+KeyB | ” | Ctrl+Alt+B | | Ctrl+Alt+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | -| Shift+Alt+KeyB | B | Shift+Alt+B | | Shift+Alt+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | -| Ctrl+Shift+Alt+KeyB | ’ | Ctrl+Shift+Alt+B | | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyC | c | C | | C | c | C | [KeyC] | | -| Ctrl+KeyC | c | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | -| Shift+KeyC | C | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | -| Ctrl+Shift+KeyC | C | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | -| Alt+KeyC | c | Alt+C | | Alt+C | alt+c | Alt+C | alt+[KeyC] | | -| Ctrl+Alt+KeyC | ¢ | Ctrl+Alt+C | | Ctrl+Alt+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | -| Shift+Alt+KeyC | C | Shift+Alt+C | | Shift+Alt+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | -| Ctrl+Shift+Alt+KeyC | © | Ctrl+Shift+Alt+C | | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyD | d | D | | D | d | D | [KeyD] | | -| Ctrl+KeyD | d | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | -| Shift+KeyD | D | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | -| Ctrl+Shift+KeyD | D | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | -| Alt+KeyD | d | Alt+D | | Alt+D | alt+d | Alt+D | alt+[KeyD] | | -| Ctrl+Alt+KeyD | ð | Ctrl+Alt+D | | Ctrl+Alt+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | -| Shift+Alt+KeyD | D | Shift+Alt+D | | Shift+Alt+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | -| Ctrl+Shift+Alt+KeyD | Ð | Ctrl+Shift+Alt+D | | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyE | e | E | | E | e | E | [KeyE] | | -| Ctrl+KeyE | e | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | -| Shift+KeyE | E | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | -| Ctrl+Shift+KeyE | E | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | -| Alt+KeyE | e | Alt+E | | Alt+E | alt+e | Alt+E | alt+[KeyE] | | -| Ctrl+Alt+KeyE | e | Ctrl+Alt+E | | Ctrl+Alt+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | -| Shift+Alt+KeyE | E | Shift+Alt+E | | Shift+Alt+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | -| Ctrl+Shift+Alt+KeyE | E | Ctrl+Shift+Alt+E | | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyF | f | F | | F | f | F | [KeyF] | | -| Ctrl+KeyF | f | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | -| Shift+KeyF | F | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | -| Ctrl+Shift+KeyF | F | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | -| Alt+KeyF | f | Alt+F | | Alt+F | alt+f | Alt+F | alt+[KeyF] | | -| Ctrl+Alt+KeyF | đ | Ctrl+Alt+F | | Ctrl+Alt+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | -| Shift+Alt+KeyF | F | Shift+Alt+F | | Shift+Alt+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | -| Ctrl+Shift+Alt+KeyF | ª | Ctrl+Shift+Alt+F | | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyG | g | G | | G | g | G | [KeyG] | | -| Ctrl+KeyG | g | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | -| Shift+KeyG | G | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | -| Ctrl+Shift+KeyG | G | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | -| Alt+KeyG | g | Alt+G | | Alt+G | alt+g | Alt+G | alt+[KeyG] | | -| Ctrl+Alt+KeyG | ŋ | Ctrl+Alt+G | | Ctrl+Alt+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | -| Shift+Alt+KeyG | G | Shift+Alt+G | | Shift+Alt+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | -| Ctrl+Shift+Alt+KeyG | Ŋ | Ctrl+Shift+Alt+G | | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyH | h | H | | H | h | H | [KeyH] | | -| Ctrl+KeyH | h | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | -| Shift+KeyH | H | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | -| Ctrl+Shift+KeyH | H | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | -| Alt+KeyH | h | Alt+H | | Alt+H | alt+h | Alt+H | alt+[KeyH] | | -| Ctrl+Alt+KeyH | ħ | Ctrl+Alt+H | | Ctrl+Alt+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | -| Shift+Alt+KeyH | H | Shift+Alt+H | | Shift+Alt+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | -| Ctrl+Shift+Alt+KeyH | Ħ | Ctrl+Shift+Alt+H | | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyI | i | I | | I | i | I | [KeyI] | | -| Ctrl+KeyI | i | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | -| Shift+KeyI | I | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | -| Ctrl+Shift+KeyI | I | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | -| Alt+KeyI | i | Alt+I | | Alt+I | alt+i | Alt+I | alt+[KeyI] | | -| Ctrl+Alt+KeyI | → | Ctrl+Alt+I | | Ctrl+Alt+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | -| Shift+Alt+KeyI | I | Shift+Alt+I | | Shift+Alt+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | -| Ctrl+Shift+Alt+KeyI | ı | Ctrl+Shift+Alt+I | | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyJ | j | J | | J | j | J | [KeyJ] | | -| Ctrl+KeyJ | j | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | -| Shift+KeyJ | J | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | -| Ctrl+Shift+KeyJ | J | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | -| Alt+KeyJ | j | Alt+J | | Alt+J | alt+j | Alt+J | alt+[KeyJ] | | -| Ctrl+Alt+KeyJ | U+309 | Ctrl+Alt+J | | Ctrl+Alt+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | -| Shift+Alt+KeyJ | J | Shift+Alt+J | | Shift+Alt+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | -| Ctrl+Shift+Alt+KeyJ | U+31b | Ctrl+Shift+Alt+J | | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyK | k | K | | K | k | K | [KeyK] | | -| Ctrl+KeyK | k | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | -| Shift+KeyK | K | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | -| Ctrl+Shift+KeyK | K | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | -| Alt+KeyK | k | Alt+K | | Alt+K | alt+k | Alt+K | alt+[KeyK] | | -| Ctrl+Alt+KeyK | ĸ | Ctrl+Alt+K | | Ctrl+Alt+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | -| Shift+Alt+KeyK | K | Shift+Alt+K | | Shift+Alt+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | -| Ctrl+Shift+Alt+KeyK | & | Ctrl+Shift+Alt+K | | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyL | l | L | | L | l | L | [KeyL] | | -| Ctrl+KeyL | l | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | -| Shift+KeyL | L | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | -| Ctrl+Shift+KeyL | L | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | -| Alt+KeyL | l | Alt+L | | Alt+L | alt+l | Alt+L | alt+[KeyL] | | -| Ctrl+Alt+KeyL | ł | Ctrl+Alt+L | | Ctrl+Alt+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | -| Shift+Alt+KeyL | L | Shift+Alt+L | | Shift+Alt+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | -| Ctrl+Shift+Alt+KeyL | Ł | Ctrl+Shift+Alt+L | | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyM | m | M | | M | m | M | [KeyM] | | -| Ctrl+KeyM | m | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | -| Shift+KeyM | M | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | -| Ctrl+Shift+KeyM | M | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | -| Alt+KeyM | m | Alt+M | | Alt+M | alt+m | Alt+M | alt+[KeyM] | | -| Ctrl+Alt+KeyM | µ | Ctrl+Alt+M | | Ctrl+Alt+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | -| Shift+Alt+KeyM | M | Shift+Alt+M | | Shift+Alt+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | -| Ctrl+Shift+Alt+KeyM | º | Ctrl+Shift+Alt+M | | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyN | n | N | | N | n | N | [KeyN] | | -| Ctrl+KeyN | n | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | -| Shift+KeyN | N | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | -| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | -| Alt+KeyN | n | Alt+N | | Alt+N | alt+n | Alt+N | alt+[KeyN] | | -| Ctrl+Alt+KeyN | n | Ctrl+Alt+N | | Ctrl+Alt+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | -| Shift+Alt+KeyN | N | Shift+Alt+N | | Shift+Alt+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | -| Ctrl+Shift+Alt+KeyN | N | Ctrl+Shift+Alt+N | | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyO | o | O | | O | o | O | [KeyO] | | -| Ctrl+KeyO | o | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | -| Shift+KeyO | O | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | -| Ctrl+Shift+KeyO | O | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | -| Alt+KeyO | o | Alt+O | | Alt+O | alt+o | Alt+O | alt+[KeyO] | | -| Ctrl+Alt+KeyO | ø | Ctrl+Alt+O | | Ctrl+Alt+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | -| Shift+Alt+KeyO | O | Shift+Alt+O | | Shift+Alt+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | -| Ctrl+Shift+Alt+KeyO | Ø | Ctrl+Shift+Alt+O | | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyP | p | P | | P | p | P | [KeyP] | | -| Ctrl+KeyP | p | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | -| Shift+KeyP | P | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | -| Ctrl+Shift+KeyP | P | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | -| Alt+KeyP | p | Alt+P | | Alt+P | alt+p | Alt+P | alt+[KeyP] | | -| Ctrl+Alt+KeyP | þ | Ctrl+Alt+P | | Ctrl+Alt+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | -| Shift+Alt+KeyP | P | Shift+Alt+P | | Shift+Alt+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | -| Ctrl+Shift+Alt+KeyP | Þ | Ctrl+Shift+Alt+P | | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyQ | q | Q | | Q | q | Q | [KeyQ] | | -| Ctrl+KeyQ | q | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | -| Shift+KeyQ | Q | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | -| Ctrl+Shift+KeyQ | Q | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | -| Alt+KeyQ | q | Alt+Q | | Alt+Q | alt+q | Alt+Q | alt+[KeyQ] | | -| Ctrl+Alt+KeyQ | @ | Ctrl+Alt+Q | | Ctrl+Alt+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | -| Shift+Alt+KeyQ | Q | Shift+Alt+Q | | Shift+Alt+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | -| Ctrl+Shift+Alt+KeyQ | Ω | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyR | r | R | | R | r | R | [KeyR] | | -| Ctrl+KeyR | r | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | -| Shift+KeyR | R | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | -| Ctrl+Shift+KeyR | R | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | -| Alt+KeyR | r | Alt+R | | Alt+R | alt+r | Alt+R | alt+[KeyR] | | -| Ctrl+Alt+KeyR | ¶ | Ctrl+Alt+R | | Ctrl+Alt+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | -| Shift+Alt+KeyR | R | Shift+Alt+R | | Shift+Alt+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | -| Ctrl+Shift+Alt+KeyR | ® | Ctrl+Shift+Alt+R | | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyS | s | S | | S | s | S | [KeyS] | | -| Ctrl+KeyS | s | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | -| Shift+KeyS | S | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | -| Ctrl+Shift+KeyS | S | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | -| Alt+KeyS | s | Alt+S | | Alt+S | alt+s | Alt+S | alt+[KeyS] | | -| Ctrl+Alt+KeyS | ß | Ctrl+Alt+S | | Ctrl+Alt+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | -| Shift+Alt+KeyS | S | Shift+Alt+S | | Shift+Alt+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | -| Ctrl+Shift+Alt+KeyS | § | Ctrl+Shift+Alt+S | | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyT | t | T | | T | t | T | [KeyT] | | -| Ctrl+KeyT | t | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | -| Shift+KeyT | T | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | -| Ctrl+Shift+KeyT | T | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | -| Alt+KeyT | t | Alt+T | | Alt+T | alt+t | Alt+T | alt+[KeyT] | | -| Ctrl+Alt+KeyT | ŧ | Ctrl+Alt+T | | Ctrl+Alt+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | -| Shift+Alt+KeyT | T | Shift+Alt+T | | Shift+Alt+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | -| Ctrl+Shift+Alt+KeyT | Ŧ | Ctrl+Shift+Alt+T | | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyU | u | U | | U | u | U | [KeyU] | | -| Ctrl+KeyU | u | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | -| Shift+KeyU | U | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | -| Ctrl+Shift+KeyU | U | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | -| Alt+KeyU | u | Alt+U | | Alt+U | alt+u | Alt+U | alt+[KeyU] | | -| Ctrl+Alt+KeyU | ↓ | Ctrl+Alt+U | | Ctrl+Alt+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | -| Shift+Alt+KeyU | U | Shift+Alt+U | | Shift+Alt+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | -| Ctrl+Shift+Alt+KeyU | ↑ | Ctrl+Shift+Alt+U | | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyV | v | V | | V | v | V | [KeyV] | | -| Ctrl+KeyV | v | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | -| Shift+KeyV | V | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | -| Ctrl+Shift+KeyV | V | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | -| Alt+KeyV | v | Alt+V | | Alt+V | alt+v | Alt+V | alt+[KeyV] | | -| Ctrl+Alt+KeyV | “ | Ctrl+Alt+V | | Ctrl+Alt+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | -| Shift+Alt+KeyV | V | Shift+Alt+V | | Shift+Alt+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | -| Ctrl+Shift+Alt+KeyV | ‘ | Ctrl+Shift+Alt+V | | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyW | w | W | | W | w | W | [KeyW] | | -| Ctrl+KeyW | w | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | -| Shift+KeyW | W | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | -| Ctrl+Shift+KeyW | W | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | -| Alt+KeyW | w | Alt+W | | Alt+W | alt+w | Alt+W | alt+[KeyW] | | -| Ctrl+Alt+KeyW | ł | Ctrl+Alt+W | | Ctrl+Alt+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | -| Shift+Alt+KeyW | W | Shift+Alt+W | | Shift+Alt+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | -| Ctrl+Shift+Alt+KeyW | Ł | Ctrl+Shift+Alt+W | | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyX | x | X | | X | x | X | [KeyX] | | -| Ctrl+KeyX | x | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | -| Shift+KeyX | X | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | -| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | -| Alt+KeyX | x | Alt+X | | Alt+X | alt+x | Alt+X | alt+[KeyX] | | -| Ctrl+Alt+KeyX | » | Ctrl+Alt+X | | Ctrl+Alt+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | -| Shift+Alt+KeyX | X | Shift+Alt+X | | Shift+Alt+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | -| Ctrl+Shift+Alt+KeyX | > | Ctrl+Shift+Alt+X | | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | -| | | Shift+. | 2 | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyY | y | Y | | Y | y | Y | [KeyY] | | -| Ctrl+KeyY | y | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyY] | | -| Shift+KeyY | Y | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyY] | | -| Ctrl+Shift+KeyY | Y | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyY] | | -| Alt+KeyY | y | Alt+Y | | Alt+Y | alt+y | Alt+Y | alt+[KeyY] | | -| Ctrl+Alt+KeyY | ← | Ctrl+Alt+Y | | Ctrl+Alt+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyY] | | -| Shift+Alt+KeyY | Y | Shift+Alt+Y | | Shift+Alt+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyY] | | -| Ctrl+Shift+Alt+KeyY | ¥ | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyY] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyZ | z | Z | | Z | z | Z | [KeyZ] | | -| Ctrl+KeyZ | z | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyZ] | | -| Shift+KeyZ | Z | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyZ] | | -| Ctrl+Shift+KeyZ | Z | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyZ] | | -| Alt+KeyZ | z | Alt+Z | | Alt+Z | alt+z | Alt+Z | alt+[KeyZ] | | -| Ctrl+Alt+KeyZ | « | Ctrl+Alt+Z | | Ctrl+Alt+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyZ] | | -| Shift+Alt+KeyZ | Z | Shift+Alt+Z | | Shift+Alt+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyZ] | | -| Ctrl+Shift+Alt+KeyZ | < | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyZ] | | -| | | Shift+, | 2 | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit1 | 1 | 1 | | 1 | 1 | 1 | [Digit1] | | -| Ctrl+Digit1 | 1 | Ctrl+1 | | Ctrl+1 | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | | -| Shift+Digit1 | ! | Shift+1 | | Shift+1 | shift+1 | Shift+1 | shift+[Digit1] | | -| Ctrl+Shift+Digit1 | ! | Ctrl+Shift+1 | | Ctrl+Shift+1 | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | | -| Alt+Digit1 | 1 | Alt+1 | | Alt+1 | alt+1 | Alt+1 | alt+[Digit1] | | -| Ctrl+Alt+Digit1 | ¹ | Ctrl+Alt+1 | | Ctrl+Alt+1 | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | | -| Shift+Alt+Digit1 | ! | Shift+Alt+1 | | Shift+Alt+1 | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | | -| Ctrl+Shift+Alt+Digit1 | ¡ | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit2 | 2 | 2 | | 2 | 2 | 2 | [Digit2] | | -| Ctrl+Digit2 | 2 | Ctrl+2 | | Ctrl+2 | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | | -| Shift+Digit2 | " | Shift+2 | | Shift+2 | shift+2 | Shift+2 | shift+[Digit2] | | -| | | Shift+' | 2 | | | | | | -| Ctrl+Shift+Digit2 | " | Ctrl+Shift+2 | | Ctrl+Shift+2 | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | | -| | | Ctrl+Shift+' | 2 | | | | | | -| Alt+Digit2 | 2 | Alt+2 | | Alt+2 | alt+2 | Alt+2 | alt+[Digit2] | | -| Ctrl+Alt+Digit2 | ² | Ctrl+Alt+2 | | Ctrl+Alt+2 | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | | -| Shift+Alt+Digit2 | " | Shift+Alt+2 | | Shift+Alt+2 | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | | -| | | Shift+Alt+' | 2 | | | | | | -| Ctrl+Shift+Alt+Digit2 | ⅛ | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | | -| | | Ctrl+Shift+Alt+' | 2 | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit3 | 3 | 3 | | 3 | 3 | 3 | [Digit3] | | -| Ctrl+Digit3 | 3 | Ctrl+3 | | Ctrl+3 | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | | -| Shift+Digit3 | £ | Shift+3 | | Shift+3 | shift+3 | Shift+3 | shift+[Digit3] | | -| Ctrl+Shift+Digit3 | £ | Ctrl+Shift+3 | | Ctrl+Shift+3 | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | | -| Alt+Digit3 | 3 | Alt+3 | | Alt+3 | alt+3 | Alt+3 | alt+[Digit3] | | -| Ctrl+Alt+Digit3 | ³ | Ctrl+Alt+3 | | Ctrl+Alt+3 | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | | -| Shift+Alt+Digit3 | £ | Shift+Alt+3 | | Shift+Alt+3 | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | | -| Ctrl+Shift+Alt+Digit3 | £ | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit4 | 4 | 4 | | 4 | 4 | 4 | [Digit4] | | -| Ctrl+Digit4 | 4 | Ctrl+4 | | Ctrl+4 | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | | -| Shift+Digit4 | $ | Shift+4 | | Shift+4 | shift+4 | Shift+4 | shift+[Digit4] | | -| Ctrl+Shift+Digit4 | $ | Ctrl+Shift+4 | | Ctrl+Shift+4 | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | | -| Alt+Digit4 | 4 | Alt+4 | | Alt+4 | alt+4 | Alt+4 | alt+[Digit4] | | -| Ctrl+Alt+Digit4 | € | Ctrl+Alt+4 | | Ctrl+Alt+4 | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | | -| Shift+Alt+Digit4 | $ | Shift+Alt+4 | | Shift+Alt+4 | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | | -| Ctrl+Shift+Alt+Digit4 | ¼ | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit5 | 5 | 5 | | 5 | 5 | 5 | [Digit5] | | -| Ctrl+Digit5 | 5 | Ctrl+5 | | Ctrl+5 | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | | -| Shift+Digit5 | % | Shift+5 | | Shift+5 | shift+5 | Shift+5 | shift+[Digit5] | | -| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+5 | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | | -| Alt+Digit5 | 5 | Alt+5 | | Alt+5 | alt+5 | Alt+5 | alt+[Digit5] | | -| Ctrl+Alt+Digit5 | ½ | Ctrl+Alt+5 | | Ctrl+Alt+5 | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | | -| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Alt+5 | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | | -| Ctrl+Shift+Alt+Digit5 | ⅜ | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit6 | 6 | 6 | | 6 | 6 | 6 | [Digit6] | | -| Ctrl+Digit6 | 6 | Ctrl+6 | | Ctrl+6 | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | | -| Shift+Digit6 | ^ | Shift+6 | | Shift+6 | shift+6 | Shift+6 | shift+[Digit6] | | -| Ctrl+Shift+Digit6 | ^ | Ctrl+Shift+6 | | Ctrl+Shift+6 | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | | -| Alt+Digit6 | 6 | Alt+6 | | Alt+6 | alt+6 | Alt+6 | alt+[Digit6] | | -| Ctrl+Alt+Digit6 | ¾ | Ctrl+Alt+6 | | Ctrl+Alt+6 | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | | -| Shift+Alt+Digit6 | ^ | Shift+Alt+6 | | Shift+Alt+6 | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | | -| Ctrl+Shift+Alt+Digit6 | ⅝ | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit7 | 7 | 7 | | 7 | 7 | 7 | [Digit7] | | -| Ctrl+Digit7 | 7 | Ctrl+7 | | Ctrl+7 | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | | -| Shift+Digit7 | & | Shift+7 | | Shift+7 | shift+7 | Shift+7 | shift+[Digit7] | | -| Ctrl+Shift+Digit7 | & | Ctrl+Shift+7 | | Ctrl+Shift+7 | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | | -| Alt+Digit7 | 7 | Alt+7 | | Alt+7 | alt+7 | Alt+7 | alt+[Digit7] | | -| Ctrl+Alt+Digit7 | { | Ctrl+Alt+7 | | Ctrl+Alt+7 | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | | -| | | Shift+[ | 2 | | | | | | -| Shift+Alt+Digit7 | & | Shift+Alt+7 | | Shift+Alt+7 | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | | -| Ctrl+Shift+Alt+Digit7 | ⅞ | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit8 | 8 | 8 | | 8 | 8 | 8 | [Digit8] | | -| Ctrl+Digit8 | 8 | Ctrl+8 | | Ctrl+8 | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | | -| Shift+Digit8 | * | Shift+8 | | Shift+8 | shift+8 | Shift+8 | shift+[Digit8] | | -| Ctrl+Shift+Digit8 | * | Ctrl+Shift+8 | | Ctrl+Shift+8 | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | | -| Alt+Digit8 | 8 | Alt+8 | | Alt+8 | alt+8 | Alt+8 | alt+[Digit8] | | -| Ctrl+Alt+Digit8 | [ | Ctrl+Alt+8 | | Ctrl+Alt+8 | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | | -| | | [ | 2 | | | | | | -| Shift+Alt+Digit8 | * | Shift+Alt+8 | | Shift+Alt+8 | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | | -| Ctrl+Shift+Alt+Digit8 | ™ | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit9 | 9 | 9 | | 9 | 9 | 9 | [Digit9] | | -| Ctrl+Digit9 | 9 | Ctrl+9 | | Ctrl+9 | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | | -| Shift+Digit9 | ( | Shift+9 | | Shift+9 | shift+9 | Shift+9 | shift+[Digit9] | | -| Ctrl+Shift+Digit9 | ( | Ctrl+Shift+9 | | Ctrl+Shift+9 | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | | -| Alt+Digit9 | 9 | Alt+9 | | Alt+9 | alt+9 | Alt+9 | alt+[Digit9] | | -| Ctrl+Alt+Digit9 | ] | Ctrl+Alt+9 | | Ctrl+Alt+9 | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | | -| | | ] | 2 | | | | | | -| Shift+Alt+Digit9 | ( | Shift+Alt+9 | | Shift+Alt+9 | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | | -| Ctrl+Shift+Alt+Digit9 | ± | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit0 | 0 | 0 | | 0 | 0 | 0 | [Digit0] | | -| Ctrl+Digit0 | 0 | Ctrl+0 | | Ctrl+0 | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | | -| Shift+Digit0 | ) | Shift+0 | | Shift+0 | shift+0 | Shift+0 | shift+[Digit0] | | -| Ctrl+Shift+Digit0 | ) | Ctrl+Shift+0 | | Ctrl+Shift+0 | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | | -| Alt+Digit0 | 0 | Alt+0 | | Alt+0 | alt+0 | Alt+0 | alt+[Digit0] | | -| Ctrl+Alt+Digit0 | } | Ctrl+Alt+0 | | Ctrl+Alt+0 | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | | -| | | Shift+] | 2 | | | | | | -| Shift+Alt+Digit0 | ) | Shift+Alt+0 | | Shift+Alt+0 | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | | -| Ctrl+Shift+Alt+Digit0 | ° | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Minus | - | - | | - | - | null | [Minus] | | -| Ctrl+Minus | - | Ctrl+- | | Ctrl+- | ctrl+- | null | ctrl+[Minus] | | -| Shift+Minus | _ | Shift+- | | Shift+- | shift+- | null | shift+[Minus] | | -| Ctrl+Shift+Minus | _ | Ctrl+Shift+- | | Ctrl+Shift+- | ctrl+shift+- | null | ctrl+shift+[Minus] | | -| Alt+Minus | - | Alt+- | | Alt+- | alt+- | null | alt+[Minus] | | -| Ctrl+Alt+Minus | \ | \ | 1 | Ctrl+Alt+- | ctrl+alt+[Minus] | null | ctrl+alt+[Minus] | NO | -| Shift+Alt+Minus | _ | Shift+Alt+- | | Shift+Alt+- | shift+alt+- | null | shift+alt+[Minus] | | -| Ctrl+Shift+Alt+Minus | ¿ | Ctrl+Shift+Alt+- | | Ctrl+Shift+Alt+- | ctrl+shift+alt+- | null | ctrl+shift+alt+[Minus] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Equal | = | = | | = | = | null | [Equal] | | -| Ctrl+Equal | = | Ctrl+= | | Ctrl+= | ctrl+= | null | ctrl+[Equal] | | -| Shift+Equal | + | Shift+= | | Shift+= | shift+= | null | shift+[Equal] | | -| Ctrl+Shift+Equal | + | Ctrl+Shift+= | | Ctrl+Shift+= | ctrl+shift+= | null | ctrl+shift+[Equal] | | -| Alt+Equal | = | Alt+= | | Alt+= | alt+= | null | alt+[Equal] | | -| Ctrl+Alt+Equal | U+327 | Ctrl+Alt+= | | Ctrl+Alt+= | ctrl+alt+= | null | ctrl+alt+[Equal] | | -| Shift+Alt+Equal | + | Shift+Alt+= | | Shift+Alt+= | shift+alt+= | null | shift+alt+[Equal] | | -| Ctrl+Shift+Alt+Equal | U+328 | Ctrl+Shift+Alt+= | | Ctrl+Shift+Alt+= | ctrl+shift+alt+= | null | ctrl+shift+alt+[Equal] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketLeft | [ | [ | 1 | [ | [ | null | [BracketLeft] | | -| Ctrl+BracketLeft | [ | Ctrl+[ | | Ctrl+[ | ctrl+[ | null | ctrl+[BracketLeft] | | -| Shift+BracketLeft | { | Shift+[ | 1 | Shift+[ | shift+[ | null | shift+[BracketLeft] | | -| Ctrl+Shift+BracketLeft | { | Ctrl+Shift+[ | | Ctrl+Shift+[ | ctrl+shift+[ | null | ctrl+shift+[BracketLeft] | | -| Alt+BracketLeft | [ | Alt+[ | | Alt+[ | alt+[ | null | alt+[BracketLeft] | | -| Ctrl+Alt+BracketLeft | ¨ | Ctrl+Alt+[ | | Ctrl+Alt+[ | ctrl+alt+[ | null | ctrl+alt+[BracketLeft] | | -| Shift+Alt+BracketLeft | { | Shift+Alt+[ | | Shift+Alt+[ | shift+alt+[ | null | shift+alt+[BracketLeft] | | -| Ctrl+Shift+Alt+BracketLeft | ˚ | Ctrl+Shift+Alt+[ | | Ctrl+Shift+Alt+[ | ctrl+shift+alt+[ | null | ctrl+shift+alt+[BracketLeft] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketRight | ] | ] | 1 | ] | ] | null | [BracketRight] | | -| Ctrl+BracketRight | ] | Ctrl+] | | Ctrl+] | ctrl+] | null | ctrl+[BracketRight] | | -| Shift+BracketRight | } | Shift+] | 1 | Shift+] | shift+] | null | shift+[BracketRight] | | -| Ctrl+Shift+BracketRight | } | Ctrl+Shift+] | | Ctrl+Shift+] | ctrl+shift+] | null | ctrl+shift+[BracketRight] | | -| Alt+BracketRight | ] | Alt+] | | Alt+] | alt+] | null | alt+[BracketRight] | | -| Ctrl+Alt+BracketRight | ˜ | Ctrl+Alt+] | | Ctrl+Alt+] | ctrl+alt+] | null | ctrl+alt+[BracketRight] | | -| Shift+Alt+BracketRight | } | Shift+Alt+] | | Shift+Alt+] | shift+alt+] | null | shift+alt+[BracketRight] | | -| Ctrl+Shift+Alt+BracketRight | ¯ | Ctrl+Shift+Alt+] | | Ctrl+Shift+Alt+] | ctrl+shift+alt+] | null | ctrl+shift+alt+[BracketRight] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backslash | # | | | # | [Backslash] | null | [Backslash] | NO | -| Ctrl+Backslash | # | | | Ctrl+# | ctrl+[Backslash] | null | ctrl+[Backslash] | NO | -| Shift+Backslash | ~ | Shift+` | 2 | Shift+# | shift+[Backslash] | null | shift+[Backslash] | NO | -| Ctrl+Shift+Backslash | ~ | Ctrl+Shift+` | 2 | Ctrl+Shift+# | ctrl+shift+[Backslash] | null | ctrl+shift+[Backslash] | NO | -| Alt+Backslash | # | | | Alt+# | alt+[Backslash] | null | alt+[Backslash] | NO | -| Ctrl+Alt+Backslash | ` | ` | 2 | Ctrl+Alt+# | ctrl+alt+[Backslash] | null | ctrl+alt+[Backslash] | NO | -| Shift+Alt+Backslash | ~ | Shift+Alt+` | 2 | Shift+Alt+# | shift+alt+[Backslash] | null | shift+alt+[Backslash] | NO | -| Ctrl+Shift+Alt+Backslash | ˘ | Ctrl+Shift+Alt+` | 2 | Ctrl+Shift+Alt+# | ctrl+shift+alt+[Backslash] | null | ctrl+shift+alt+[Backslash] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlHash | --- | | | null | null | null | null | | -| Ctrl+IntlHash | --- | | | null | null | null | null | | -| Shift+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | -| Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | -| Shift+Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Semicolon | ; | ; | | ; | ; | null | [Semicolon] | | -| Ctrl+Semicolon | ; | Ctrl+; | | Ctrl+; | ctrl+; | null | ctrl+[Semicolon] | | -| Shift+Semicolon | : | Shift+; | | Shift+; | shift+; | null | shift+[Semicolon] | | -| Ctrl+Shift+Semicolon | : | Ctrl+Shift+; | | Ctrl+Shift+; | ctrl+shift+; | null | ctrl+shift+[Semicolon] | | -| Alt+Semicolon | ; | Alt+; | | Alt+; | alt+; | null | alt+[Semicolon] | | -| Ctrl+Alt+Semicolon | ´ | Ctrl+Alt+; | | Ctrl+Alt+; | ctrl+alt+; | null | ctrl+alt+[Semicolon] | | -| Shift+Alt+Semicolon | : | Shift+Alt+; | | Shift+Alt+; | shift+alt+; | null | shift+alt+[Semicolon] | | -| Ctrl+Shift+Alt+Semicolon | ˝ | Ctrl+Shift+Alt+; | | Ctrl+Shift+Alt+; | ctrl+shift+alt+; | null | ctrl+shift+alt+[Semicolon] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Quote | ' | ' | | ' | ' | ' | [Quote] | | -| Ctrl+Quote | ' | Ctrl+' | | Ctrl+' | ctrl+' | Ctrl+' | ctrl+[Quote] | | -| Shift+Quote | @ | Shift+' | 1 | Shift+' | shift+' | Shift+' | shift+[Quote] | | -| Ctrl+Shift+Quote | @ | Ctrl+Shift+' | 1 | Ctrl+Shift+' | ctrl+shift+' | Ctrl+Shift+' | ctrl+shift+[Quote] | | -| Alt+Quote | ' | Alt+' | | Alt+' | alt+' | Alt+' | alt+[Quote] | | -| Ctrl+Alt+Quote | ^ | Ctrl+Alt+' | | Ctrl+Alt+' | ctrl+alt+' | Ctrl+Alt+' | ctrl+alt+[Quote] | | -| Shift+Alt+Quote | @ | Shift+Alt+' | 1 | Shift+Alt+' | shift+alt+' | Shift+Alt+' | shift+alt+[Quote] | | -| Ctrl+Shift+Alt+Quote | U+30c | Ctrl+Shift+Alt+' | 1 | Ctrl+Shift+Alt+' | ctrl+shift+alt+' | Ctrl+Shift+Alt+' | ctrl+shift+alt+[Quote] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backquote | ` | ` | 1 | ` | ` | null | [Backquote] | | -| Ctrl+Backquote | ` | Ctrl+` | | Ctrl+` | ctrl+` | null | ctrl+[Backquote] | | -| Shift+Backquote | ¬ | Shift+` | 1 | Shift+` | shift+` | null | shift+[Backquote] | | -| Ctrl+Shift+Backquote | ¬ | Ctrl+Shift+` | 1 | Ctrl+Shift+` | ctrl+shift+` | null | ctrl+shift+[Backquote] | | -| Alt+Backquote | ` | Alt+` | | Alt+` | alt+` | null | alt+[Backquote] | | -| Ctrl+Alt+Backquote | | | Shift+\ | 1 | Ctrl+Alt+` | ctrl+alt+[Backquote] | null | ctrl+alt+[Backquote] | NO | -| Shift+Alt+Backquote | ¬ | Shift+Alt+` | 1 | Shift+Alt+` | shift+alt+` | null | shift+alt+[Backquote] | | -| Ctrl+Shift+Alt+Backquote | | | Ctrl+Shift+Alt+` | 1 | Ctrl+Shift+Alt+` | ctrl+shift+alt+` | null | ctrl+shift+alt+[Backquote] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Comma | , | , | | , | , | null | [Comma] | | -| Ctrl+Comma | , | Ctrl+, | | Ctrl+, | ctrl+, | null | ctrl+[Comma] | | -| Shift+Comma | < | Shift+, | 1 | Shift+, | shift+, | null | shift+[Comma] | | -| Ctrl+Shift+Comma | < | Ctrl+Shift+, | | Ctrl+Shift+, | ctrl+shift+, | null | ctrl+shift+[Comma] | | -| Alt+Comma | , | Alt+, | | Alt+, | alt+, | null | alt+[Comma] | | -| Ctrl+Alt+Comma | ─ | Ctrl+Alt+, | | Ctrl+Alt+, | ctrl+alt+, | null | ctrl+alt+[Comma] | | -| Shift+Alt+Comma | < | Shift+Alt+, | | Shift+Alt+, | shift+alt+, | null | shift+alt+[Comma] | | -| Ctrl+Shift+Alt+Comma | × | Ctrl+Shift+Alt+, | | Ctrl+Shift+Alt+, | ctrl+shift+alt+, | null | ctrl+shift+alt+[Comma] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Period | . | . | | . | . | null | [Period] | | -| Ctrl+Period | . | Ctrl+. | | Ctrl+. | ctrl+. | null | ctrl+[Period] | | -| Shift+Period | > | Shift+. | 1 | Shift+. | shift+. | null | shift+[Period] | | -| Ctrl+Shift+Period | > | Ctrl+Shift+. | | Ctrl+Shift+. | ctrl+shift+. | null | ctrl+shift+[Period] | | -| Alt+Period | . | Alt+. | | Alt+. | alt+. | null | alt+[Period] | | -| Ctrl+Alt+Period | · | Ctrl+Alt+. | | Ctrl+Alt+. | ctrl+alt+. | null | ctrl+alt+[Period] | | -| Shift+Alt+Period | > | Shift+Alt+. | | Shift+Alt+. | shift+alt+. | null | shift+alt+[Period] | | -| Ctrl+Shift+Alt+Period | ÷ | Ctrl+Shift+Alt+. | | Ctrl+Shift+Alt+. | ctrl+shift+alt+. | null | ctrl+shift+alt+[Period] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Slash | / | / | | / | / | null | [Slash] | | -| Ctrl+Slash | / | Ctrl+/ | | Ctrl+/ | ctrl+/ | null | ctrl+[Slash] | | -| Shift+Slash | ? | Shift+/ | | Shift+/ | shift+/ | null | shift+[Slash] | | -| Ctrl+Shift+Slash | ? | Ctrl+Shift+/ | | Ctrl+Shift+/ | ctrl+shift+/ | null | ctrl+shift+[Slash] | | -| Alt+Slash | / | Alt+/ | | Alt+/ | alt+/ | null | alt+[Slash] | | -| Ctrl+Alt+Slash | U+323 | Ctrl+Alt+/ | | Ctrl+Alt+/ | ctrl+alt+/ | null | ctrl+alt+[Slash] | | -| Shift+Alt+Slash | ? | Shift+Alt+/ | | Shift+Alt+/ | shift+alt+/ | null | shift+alt+[Slash] | | -| Ctrl+Shift+Alt+Slash | ˙ | Ctrl+Shift+Alt+/ | | Ctrl+Shift+Alt+/ | ctrl+shift+alt+/ | null | ctrl+shift+alt+[Slash] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | -| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | -| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | -| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | -| Alt+ArrowUp | --- | Alt+UpArrow | | Alt+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | -| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Alt+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | -| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Alt+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | -| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | -| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | -| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | -| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | -| Alt+Numpad0 | --- | Alt+NumPad0 | | Alt+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | -| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | -| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Alt+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | -| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlBackslash | \ | \ | 2 | \ | \ | null | [IntlBackslash] | | -| Ctrl+IntlBackslash | \ | Ctrl+\ | | Ctrl+\ | ctrl+\ | null | ctrl+[IntlBackslash] | | -| Shift+IntlBackslash | | | Shift+\ | 2 | Shift+\ | shift+\ | null | shift+[IntlBackslash] | | -| Ctrl+Shift+IntlBackslash | | | Ctrl+Shift+\ | | Ctrl+Shift+\ | ctrl+shift+\ | null | ctrl+shift+[IntlBackslash] | | -| Alt+IntlBackslash | \ | Alt+\ | | Alt+\ | alt+\ | null | alt+[IntlBackslash] | | -| Ctrl+Alt+IntlBackslash | | | Ctrl+Alt+\ | | Ctrl+Alt+\ | ctrl+alt+\ | null | ctrl+alt+[IntlBackslash] | | -| Shift+Alt+IntlBackslash | | | Shift+Alt+\ | | Shift+Alt+\ | shift+alt+\ | null | shift+alt+[IntlBackslash] | | -| Ctrl+Shift+Alt+IntlBackslash | ¦ | Ctrl+Shift+Alt+\ | | Ctrl+Shift+Alt+\ | ctrl+shift+alt+\ | null | ctrl+shift+alt+[IntlBackslash] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | -| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | -| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | -| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | -| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | -| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | -| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | -| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | -| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | -| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | -| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | -| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | -| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | -| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | -| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/linux_en_us.js b/src/vs/workbench/services/keybinding/test/electron-browser/linux_en_us.js deleted file mode 100644 index 9f6ddd3caf9..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/linux_en_us.js +++ /dev/null @@ -1,497 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -define({ - Sleep: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - WakeUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - KeyA: { - value: 'a', - withShift: 'A', - withAltGr: 'a', - withShiftAltGr: 'A' - }, - KeyB: { - value: 'b', - withShift: 'B', - withAltGr: 'b', - withShiftAltGr: 'B' - }, - KeyC: { - value: 'c', - withShift: 'C', - withAltGr: 'c', - withShiftAltGr: 'C' - }, - KeyD: { - value: 'd', - withShift: 'D', - withAltGr: 'd', - withShiftAltGr: 'D' - }, - KeyE: { - value: 'e', - withShift: 'E', - withAltGr: 'e', - withShiftAltGr: 'E' - }, - KeyF: { - value: 'f', - withShift: 'F', - withAltGr: 'f', - withShiftAltGr: 'F' - }, - KeyG: { - value: 'g', - withShift: 'G', - withAltGr: 'g', - withShiftAltGr: 'G' - }, - KeyH: { - value: 'h', - withShift: 'H', - withAltGr: 'h', - withShiftAltGr: 'H' - }, - KeyI: { - value: 'i', - withShift: 'I', - withAltGr: 'i', - withShiftAltGr: 'I' - }, - KeyJ: { - value: 'j', - withShift: 'J', - withAltGr: 'j', - withShiftAltGr: 'J' - }, - KeyK: { - value: 'k', - withShift: 'K', - withAltGr: 'k', - withShiftAltGr: 'K' - }, - KeyL: { - value: 'l', - withShift: 'L', - withAltGr: 'l', - withShiftAltGr: 'L' - }, - KeyM: { - value: 'm', - withShift: 'M', - withAltGr: 'm', - withShiftAltGr: 'M' - }, - KeyN: { - value: 'n', - withShift: 'N', - withAltGr: 'n', - withShiftAltGr: 'N' - }, - KeyO: { - value: 'o', - withShift: 'O', - withAltGr: 'o', - withShiftAltGr: 'O' - }, - KeyP: { - value: 'p', - withShift: 'P', - withAltGr: 'p', - withShiftAltGr: 'P' - }, - KeyQ: { - value: 'q', - withShift: 'Q', - withAltGr: 'q', - withShiftAltGr: 'Q' - }, - KeyR: { - value: 'r', - withShift: 'R', - withAltGr: 'r', - withShiftAltGr: 'R' - }, - KeyS: { - value: 's', - withShift: 'S', - withAltGr: 's', - withShiftAltGr: 'S' - }, - KeyT: { - value: 't', - withShift: 'T', - withAltGr: 't', - withShiftAltGr: 'T' - }, - KeyU: { - value: 'u', - withShift: 'U', - withAltGr: 'u', - withShiftAltGr: 'U' - }, - KeyV: { - value: 'v', - withShift: 'V', - withAltGr: 'v', - withShiftAltGr: 'V' - }, - KeyW: { - value: 'w', - withShift: 'W', - withAltGr: 'w', - withShiftAltGr: 'W' - }, - KeyX: { - value: 'x', - withShift: 'X', - withAltGr: 'x', - withShiftAltGr: 'X' - }, - KeyY: { - value: 'y', - withShift: 'Y', - withAltGr: 'y', - withShiftAltGr: 'Y' - }, - KeyZ: { - value: 'z', - withShift: 'Z', - withAltGr: 'z', - withShiftAltGr: 'Z' - }, - Digit1: { - value: '1', - withShift: '!', - withAltGr: '1', - withShiftAltGr: '!' - }, - Digit2: { - value: '2', - withShift: '@', - withAltGr: '2', - withShiftAltGr: '@' - }, - Digit3: { - value: '3', - withShift: '#', - withAltGr: '3', - withShiftAltGr: '#' - }, - Digit4: { - value: '4', - withShift: '$', - withAltGr: '4', - withShiftAltGr: '$' - }, - Digit5: { - value: '5', - withShift: '%', - withAltGr: '5', - withShiftAltGr: '%' - }, - Digit6: { - value: '6', - withShift: '^', - withAltGr: '6', - withShiftAltGr: '^' - }, - Digit7: { - value: '7', - withShift: '&', - withAltGr: '7', - withShiftAltGr: '&' - }, - Digit8: { - value: '8', - withShift: '*', - withAltGr: '8', - withShiftAltGr: '*' - }, - Digit9: { - value: '9', - withShift: '(', - withAltGr: '9', - withShiftAltGr: '(' - }, - Digit0: { - value: '0', - withShift: ')', - withAltGr: '0', - withShiftAltGr: ')' - }, - Enter: { - value: '\r', - withShift: '\r', - withAltGr: '\r', - withShiftAltGr: '\r' - }, - Escape: { - value: '\u001b', - withShift: '\u001b', - withAltGr: '\u001b', - withShiftAltGr: '\u001b' - }, - Backspace: { - value: '\b', - withShift: '\b', - withAltGr: '\b', - withShiftAltGr: '\b' - }, - Tab: { - value: '\t', - withShift: '', - withAltGr: '\t', - withShiftAltGr: '' - }, - Space: { - value: ' ', - withShift: ' ', - withAltGr: ' ', - withShiftAltGr: ' ' - }, - Minus: { - value: '-', - withShift: '_', - withAltGr: '-', - withShiftAltGr: '_' - }, - Equal: { - value: '=', - withShift: '+', - withAltGr: '=', - withShiftAltGr: '+' - }, - BracketLeft: { - value: '[', - withShift: '{', - withAltGr: '[', - withShiftAltGr: '{' - }, - BracketRight: { - value: ']', - withShift: '}', - withAltGr: ']', - withShiftAltGr: '}' - }, - Backslash: { - value: '\\', - withShift: '|', - withAltGr: '\\', - withShiftAltGr: '|' - }, - Semicolon: { - value: ';', - withShift: ':', - withAltGr: ';', - withShiftAltGr: ':' - }, - Quote: { - value: '\'', - withShift: '"', - withAltGr: '\'', - withShiftAltGr: '"' - }, - Backquote: { - value: '`', - withShift: '~', - withAltGr: '`', - withShiftAltGr: '~' - }, - Comma: { - value: ',', - withShift: '<', - withAltGr: ',', - withShiftAltGr: '<' - }, - Period: { - value: '.', - withShift: '>', - withAltGr: '.', - withShiftAltGr: '>' - }, - Slash: { - value: '/', - withShift: '?', - withAltGr: '/', - withShiftAltGr: '?' - }, - CapsLock: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F1: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F2: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F3: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F4: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F5: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F6: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F7: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F8: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F9: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F10: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F11: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F12: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - PrintScreen: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ScrollLock: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Pause: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Insert: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Home: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - PageUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Delete: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - End: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - PageDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ArrowRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ArrowLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ArrowDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ArrowUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - NumLock: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - NumpadDivide: { - value: '/', - withShift: '/', - withAltGr: '/', - withShiftAltGr: '/' - }, - NumpadMultiply: { - value: '*', - withShift: '*', - withAltGr: '*', - withShiftAltGr: '*' - }, - NumpadSubtract: { - value: '-', - withShift: '-', - withAltGr: '-', - withShiftAltGr: '-' - }, - NumpadAdd: { - value: '+', - withShift: '+', - withAltGr: '+', - withShiftAltGr: '+' - }, - NumpadEnter: { - value: '\r', - withShift: '\r', - withAltGr: '\r', - withShiftAltGr: '\r' - }, - Numpad1: { value: '', withShift: '1', withAltGr: '', withShiftAltGr: '1' }, - Numpad2: { value: '', withShift: '2', withAltGr: '', withShiftAltGr: '2' }, - Numpad3: { value: '', withShift: '3', withAltGr: '', withShiftAltGr: '3' }, - Numpad4: { value: '', withShift: '4', withAltGr: '', withShiftAltGr: '4' }, - Numpad5: { value: '', withShift: '5', withAltGr: '', withShiftAltGr: '5' }, - Numpad6: { value: '', withShift: '6', withAltGr: '', withShiftAltGr: '6' }, - Numpad7: { value: '', withShift: '7', withAltGr: '', withShiftAltGr: '7' }, - Numpad8: { value: '', withShift: '8', withAltGr: '', withShiftAltGr: '8' }, - Numpad9: { value: '', withShift: '9', withAltGr: '', withShiftAltGr: '9' }, - Numpad0: { value: '', withShift: '0', withAltGr: '', withShiftAltGr: '0' }, - NumpadDecimal: { value: '', withShift: '.', withAltGr: '', withShiftAltGr: '.' }, - IntlBackslash: { - value: '<', - withShift: '>', - withAltGr: '|', - withShiftAltGr: '¦' - }, - ContextMenu: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Power: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - NumpadEqual: { - value: '=', - withShift: '=', - withAltGr: '=', - withShiftAltGr: '=' - }, - F13: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F14: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F15: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F16: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F17: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F18: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F19: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F20: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F21: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F22: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F23: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - F24: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Open: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Help: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Select: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Again: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Undo: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Cut: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Copy: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Paste: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Find: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - AudioVolumeMute: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - AudioVolumeUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - AudioVolumeDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - NumpadComma: { - value: '.', - withShift: '.', - withAltGr: '.', - withShiftAltGr: '.' - }, - IntlRo: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - KanaMode: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - IntlYen: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Convert: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - NonConvert: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Lang1: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Lang2: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Lang3: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Lang4: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Lang5: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - NumpadParenLeft: { - value: '(', - withShift: '(', - withAltGr: '(', - withShiftAltGr: '(' - }, - NumpadParenRight: { - value: ')', - withShift: ')', - withAltGr: ')', - withShiftAltGr: ')' - }, - ControlLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ShiftLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - AltLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MetaLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ControlRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - ShiftRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - AltRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MetaRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrightnessUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrightnessDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaPlay: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaRecord: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaFastForward: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaRewind: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaTrackNext: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaTrackPrevious: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaStop: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - Eject: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaPlayPause: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MediaSelect: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - LaunchMail: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - LaunchApp2: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - LaunchApp1: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - SelectTask: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - LaunchScreenSaver: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrowserSearch: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrowserHome: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrowserBack: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrowserForward: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrowserStop: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrowserRefresh: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - BrowserFavorites: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MailReply: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MailForward: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, - MailSend: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' } - -}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/linux_en_us.txt b/src/vs/workbench/services/keybinding/test/electron-browser/linux_en_us.txt deleted file mode 100644 index 704e852f8d6..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/linux_en_us.txt +++ /dev/null @@ -1,507 +0,0 @@ -isUSStandard: true ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyA | a | A | | A | a | A | [KeyA] | | -| Ctrl+KeyA | a | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | -| Shift+KeyA | A | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | -| Ctrl+Shift+KeyA | A | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | -| Alt+KeyA | a | Alt+A | | Alt+A | alt+a | Alt+A | alt+[KeyA] | | -| Ctrl+Alt+KeyA | a | Ctrl+Alt+A | | Ctrl+Alt+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | -| Shift+Alt+KeyA | A | Shift+Alt+A | | Shift+Alt+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | -| Ctrl+Shift+Alt+KeyA | A | Ctrl+Shift+Alt+A | | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyB | b | B | | B | b | B | [KeyB] | | -| Ctrl+KeyB | b | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | -| Shift+KeyB | B | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | -| Ctrl+Shift+KeyB | B | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | -| Alt+KeyB | b | Alt+B | | Alt+B | alt+b | Alt+B | alt+[KeyB] | | -| Ctrl+Alt+KeyB | b | Ctrl+Alt+B | | Ctrl+Alt+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | -| Shift+Alt+KeyB | B | Shift+Alt+B | | Shift+Alt+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | -| Ctrl+Shift+Alt+KeyB | B | Ctrl+Shift+Alt+B | | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyC | c | C | | C | c | C | [KeyC] | | -| Ctrl+KeyC | c | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | -| Shift+KeyC | C | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | -| Ctrl+Shift+KeyC | C | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | -| Alt+KeyC | c | Alt+C | | Alt+C | alt+c | Alt+C | alt+[KeyC] | | -| Ctrl+Alt+KeyC | c | Ctrl+Alt+C | | Ctrl+Alt+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | -| Shift+Alt+KeyC | C | Shift+Alt+C | | Shift+Alt+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | -| Ctrl+Shift+Alt+KeyC | C | Ctrl+Shift+Alt+C | | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyD | d | D | | D | d | D | [KeyD] | | -| Ctrl+KeyD | d | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | -| Shift+KeyD | D | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | -| Ctrl+Shift+KeyD | D | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | -| Alt+KeyD | d | Alt+D | | Alt+D | alt+d | Alt+D | alt+[KeyD] | | -| Ctrl+Alt+KeyD | d | Ctrl+Alt+D | | Ctrl+Alt+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | -| Shift+Alt+KeyD | D | Shift+Alt+D | | Shift+Alt+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | -| Ctrl+Shift+Alt+KeyD | D | Ctrl+Shift+Alt+D | | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyE | e | E | | E | e | E | [KeyE] | | -| Ctrl+KeyE | e | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | -| Shift+KeyE | E | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | -| Ctrl+Shift+KeyE | E | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | -| Alt+KeyE | e | Alt+E | | Alt+E | alt+e | Alt+E | alt+[KeyE] | | -| Ctrl+Alt+KeyE | e | Ctrl+Alt+E | | Ctrl+Alt+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | -| Shift+Alt+KeyE | E | Shift+Alt+E | | Shift+Alt+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | -| Ctrl+Shift+Alt+KeyE | E | Ctrl+Shift+Alt+E | | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyF | f | F | | F | f | F | [KeyF] | | -| Ctrl+KeyF | f | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | -| Shift+KeyF | F | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | -| Ctrl+Shift+KeyF | F | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | -| Alt+KeyF | f | Alt+F | | Alt+F | alt+f | Alt+F | alt+[KeyF] | | -| Ctrl+Alt+KeyF | f | Ctrl+Alt+F | | Ctrl+Alt+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | -| Shift+Alt+KeyF | F | Shift+Alt+F | | Shift+Alt+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | -| Ctrl+Shift+Alt+KeyF | F | Ctrl+Shift+Alt+F | | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyG | g | G | | G | g | G | [KeyG] | | -| Ctrl+KeyG | g | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | -| Shift+KeyG | G | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | -| Ctrl+Shift+KeyG | G | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | -| Alt+KeyG | g | Alt+G | | Alt+G | alt+g | Alt+G | alt+[KeyG] | | -| Ctrl+Alt+KeyG | g | Ctrl+Alt+G | | Ctrl+Alt+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | -| Shift+Alt+KeyG | G | Shift+Alt+G | | Shift+Alt+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | -| Ctrl+Shift+Alt+KeyG | G | Ctrl+Shift+Alt+G | | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyH | h | H | | H | h | H | [KeyH] | | -| Ctrl+KeyH | h | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | -| Shift+KeyH | H | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | -| Ctrl+Shift+KeyH | H | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | -| Alt+KeyH | h | Alt+H | | Alt+H | alt+h | Alt+H | alt+[KeyH] | | -| Ctrl+Alt+KeyH | h | Ctrl+Alt+H | | Ctrl+Alt+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | -| Shift+Alt+KeyH | H | Shift+Alt+H | | Shift+Alt+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | -| Ctrl+Shift+Alt+KeyH | H | Ctrl+Shift+Alt+H | | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyI | i | I | | I | i | I | [KeyI] | | -| Ctrl+KeyI | i | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | -| Shift+KeyI | I | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | -| Ctrl+Shift+KeyI | I | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | -| Alt+KeyI | i | Alt+I | | Alt+I | alt+i | Alt+I | alt+[KeyI] | | -| Ctrl+Alt+KeyI | i | Ctrl+Alt+I | | Ctrl+Alt+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | -| Shift+Alt+KeyI | I | Shift+Alt+I | | Shift+Alt+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | -| Ctrl+Shift+Alt+KeyI | I | Ctrl+Shift+Alt+I | | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyJ | j | J | | J | j | J | [KeyJ] | | -| Ctrl+KeyJ | j | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | -| Shift+KeyJ | J | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | -| Ctrl+Shift+KeyJ | J | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | -| Alt+KeyJ | j | Alt+J | | Alt+J | alt+j | Alt+J | alt+[KeyJ] | | -| Ctrl+Alt+KeyJ | j | Ctrl+Alt+J | | Ctrl+Alt+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | -| Shift+Alt+KeyJ | J | Shift+Alt+J | | Shift+Alt+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | -| Ctrl+Shift+Alt+KeyJ | J | Ctrl+Shift+Alt+J | | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyK | k | K | | K | k | K | [KeyK] | | -| Ctrl+KeyK | k | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | -| Shift+KeyK | K | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | -| Ctrl+Shift+KeyK | K | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | -| Alt+KeyK | k | Alt+K | | Alt+K | alt+k | Alt+K | alt+[KeyK] | | -| Ctrl+Alt+KeyK | k | Ctrl+Alt+K | | Ctrl+Alt+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | -| Shift+Alt+KeyK | K | Shift+Alt+K | | Shift+Alt+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | -| Ctrl+Shift+Alt+KeyK | K | Ctrl+Shift+Alt+K | | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyL | l | L | | L | l | L | [KeyL] | | -| Ctrl+KeyL | l | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | -| Shift+KeyL | L | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | -| Ctrl+Shift+KeyL | L | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | -| Alt+KeyL | l | Alt+L | | Alt+L | alt+l | Alt+L | alt+[KeyL] | | -| Ctrl+Alt+KeyL | l | Ctrl+Alt+L | | Ctrl+Alt+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | -| Shift+Alt+KeyL | L | Shift+Alt+L | | Shift+Alt+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | -| Ctrl+Shift+Alt+KeyL | L | Ctrl+Shift+Alt+L | | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyM | m | M | | M | m | M | [KeyM] | | -| Ctrl+KeyM | m | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | -| Shift+KeyM | M | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | -| Ctrl+Shift+KeyM | M | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | -| Alt+KeyM | m | Alt+M | | Alt+M | alt+m | Alt+M | alt+[KeyM] | | -| Ctrl+Alt+KeyM | m | Ctrl+Alt+M | | Ctrl+Alt+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | -| Shift+Alt+KeyM | M | Shift+Alt+M | | Shift+Alt+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | -| Ctrl+Shift+Alt+KeyM | M | Ctrl+Shift+Alt+M | | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyN | n | N | | N | n | N | [KeyN] | | -| Ctrl+KeyN | n | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | -| Shift+KeyN | N | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | -| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | -| Alt+KeyN | n | Alt+N | | Alt+N | alt+n | Alt+N | alt+[KeyN] | | -| Ctrl+Alt+KeyN | n | Ctrl+Alt+N | | Ctrl+Alt+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | -| Shift+Alt+KeyN | N | Shift+Alt+N | | Shift+Alt+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | -| Ctrl+Shift+Alt+KeyN | N | Ctrl+Shift+Alt+N | | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyO | o | O | | O | o | O | [KeyO] | | -| Ctrl+KeyO | o | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | -| Shift+KeyO | O | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | -| Ctrl+Shift+KeyO | O | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | -| Alt+KeyO | o | Alt+O | | Alt+O | alt+o | Alt+O | alt+[KeyO] | | -| Ctrl+Alt+KeyO | o | Ctrl+Alt+O | | Ctrl+Alt+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | -| Shift+Alt+KeyO | O | Shift+Alt+O | | Shift+Alt+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | -| Ctrl+Shift+Alt+KeyO | O | Ctrl+Shift+Alt+O | | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyP | p | P | | P | p | P | [KeyP] | | -| Ctrl+KeyP | p | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | -| Shift+KeyP | P | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | -| Ctrl+Shift+KeyP | P | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | -| Alt+KeyP | p | Alt+P | | Alt+P | alt+p | Alt+P | alt+[KeyP] | | -| Ctrl+Alt+KeyP | p | Ctrl+Alt+P | | Ctrl+Alt+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | -| Shift+Alt+KeyP | P | Shift+Alt+P | | Shift+Alt+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | -| Ctrl+Shift+Alt+KeyP | P | Ctrl+Shift+Alt+P | | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyQ | q | Q | | Q | q | Q | [KeyQ] | | -| Ctrl+KeyQ | q | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | -| Shift+KeyQ | Q | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | -| Ctrl+Shift+KeyQ | Q | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | -| Alt+KeyQ | q | Alt+Q | | Alt+Q | alt+q | Alt+Q | alt+[KeyQ] | | -| Ctrl+Alt+KeyQ | q | Ctrl+Alt+Q | | Ctrl+Alt+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | -| Shift+Alt+KeyQ | Q | Shift+Alt+Q | | Shift+Alt+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | -| Ctrl+Shift+Alt+KeyQ | Q | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyR | r | R | | R | r | R | [KeyR] | | -| Ctrl+KeyR | r | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | -| Shift+KeyR | R | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | -| Ctrl+Shift+KeyR | R | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | -| Alt+KeyR | r | Alt+R | | Alt+R | alt+r | Alt+R | alt+[KeyR] | | -| Ctrl+Alt+KeyR | r | Ctrl+Alt+R | | Ctrl+Alt+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | -| Shift+Alt+KeyR | R | Shift+Alt+R | | Shift+Alt+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | -| Ctrl+Shift+Alt+KeyR | R | Ctrl+Shift+Alt+R | | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyS | s | S | | S | s | S | [KeyS] | | -| Ctrl+KeyS | s | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | -| Shift+KeyS | S | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | -| Ctrl+Shift+KeyS | S | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | -| Alt+KeyS | s | Alt+S | | Alt+S | alt+s | Alt+S | alt+[KeyS] | | -| Ctrl+Alt+KeyS | s | Ctrl+Alt+S | | Ctrl+Alt+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | -| Shift+Alt+KeyS | S | Shift+Alt+S | | Shift+Alt+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | -| Ctrl+Shift+Alt+KeyS | S | Ctrl+Shift+Alt+S | | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyT | t | T | | T | t | T | [KeyT] | | -| Ctrl+KeyT | t | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | -| Shift+KeyT | T | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | -| Ctrl+Shift+KeyT | T | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | -| Alt+KeyT | t | Alt+T | | Alt+T | alt+t | Alt+T | alt+[KeyT] | | -| Ctrl+Alt+KeyT | t | Ctrl+Alt+T | | Ctrl+Alt+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | -| Shift+Alt+KeyT | T | Shift+Alt+T | | Shift+Alt+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | -| Ctrl+Shift+Alt+KeyT | T | Ctrl+Shift+Alt+T | | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyU | u | U | | U | u | U | [KeyU] | | -| Ctrl+KeyU | u | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | -| Shift+KeyU | U | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | -| Ctrl+Shift+KeyU | U | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | -| Alt+KeyU | u | Alt+U | | Alt+U | alt+u | Alt+U | alt+[KeyU] | | -| Ctrl+Alt+KeyU | u | Ctrl+Alt+U | | Ctrl+Alt+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | -| Shift+Alt+KeyU | U | Shift+Alt+U | | Shift+Alt+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | -| Ctrl+Shift+Alt+KeyU | U | Ctrl+Shift+Alt+U | | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyV | v | V | | V | v | V | [KeyV] | | -| Ctrl+KeyV | v | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | -| Shift+KeyV | V | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | -| Ctrl+Shift+KeyV | V | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | -| Alt+KeyV | v | Alt+V | | Alt+V | alt+v | Alt+V | alt+[KeyV] | | -| Ctrl+Alt+KeyV | v | Ctrl+Alt+V | | Ctrl+Alt+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | -| Shift+Alt+KeyV | V | Shift+Alt+V | | Shift+Alt+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | -| Ctrl+Shift+Alt+KeyV | V | Ctrl+Shift+Alt+V | | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyW | w | W | | W | w | W | [KeyW] | | -| Ctrl+KeyW | w | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | -| Shift+KeyW | W | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | -| Ctrl+Shift+KeyW | W | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | -| Alt+KeyW | w | Alt+W | | Alt+W | alt+w | Alt+W | alt+[KeyW] | | -| Ctrl+Alt+KeyW | w | Ctrl+Alt+W | | Ctrl+Alt+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | -| Shift+Alt+KeyW | W | Shift+Alt+W | | Shift+Alt+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | -| Ctrl+Shift+Alt+KeyW | W | Ctrl+Shift+Alt+W | | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyX | x | X | | X | x | X | [KeyX] | | -| Ctrl+KeyX | x | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | -| Shift+KeyX | X | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | -| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | -| Alt+KeyX | x | Alt+X | | Alt+X | alt+x | Alt+X | alt+[KeyX] | | -| Ctrl+Alt+KeyX | x | Ctrl+Alt+X | | Ctrl+Alt+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | -| Shift+Alt+KeyX | X | Shift+Alt+X | | Shift+Alt+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | -| Ctrl+Shift+Alt+KeyX | X | Ctrl+Shift+Alt+X | | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyY | y | Y | | Y | y | Y | [KeyY] | | -| Ctrl+KeyY | y | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyY] | | -| Shift+KeyY | Y | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyY] | | -| Ctrl+Shift+KeyY | Y | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyY] | | -| Alt+KeyY | y | Alt+Y | | Alt+Y | alt+y | Alt+Y | alt+[KeyY] | | -| Ctrl+Alt+KeyY | y | Ctrl+Alt+Y | | Ctrl+Alt+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyY] | | -| Shift+Alt+KeyY | Y | Shift+Alt+Y | | Shift+Alt+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyY] | | -| Ctrl+Shift+Alt+KeyY | Y | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyY] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyZ | z | Z | | Z | z | Z | [KeyZ] | | -| Ctrl+KeyZ | z | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyZ] | | -| Shift+KeyZ | Z | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyZ] | | -| Ctrl+Shift+KeyZ | Z | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyZ] | | -| Alt+KeyZ | z | Alt+Z | | Alt+Z | alt+z | Alt+Z | alt+[KeyZ] | | -| Ctrl+Alt+KeyZ | z | Ctrl+Alt+Z | | Ctrl+Alt+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyZ] | | -| Shift+Alt+KeyZ | Z | Shift+Alt+Z | | Shift+Alt+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyZ] | | -| Ctrl+Shift+Alt+KeyZ | Z | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyZ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit1 | 1 | 1 | | 1 | 1 | 1 | [Digit1] | | -| Ctrl+Digit1 | 1 | Ctrl+1 | | Ctrl+1 | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | | -| Shift+Digit1 | ! | Shift+1 | | Shift+1 | shift+1 | Shift+1 | shift+[Digit1] | | -| Ctrl+Shift+Digit1 | ! | Ctrl+Shift+1 | | Ctrl+Shift+1 | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | | -| Alt+Digit1 | 1 | Alt+1 | | Alt+1 | alt+1 | Alt+1 | alt+[Digit1] | | -| Ctrl+Alt+Digit1 | 1 | Ctrl+Alt+1 | | Ctrl+Alt+1 | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | | -| Shift+Alt+Digit1 | ! | Shift+Alt+1 | | Shift+Alt+1 | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | | -| Ctrl+Shift+Alt+Digit1 | ! | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit2 | 2 | 2 | | 2 | 2 | 2 | [Digit2] | | -| Ctrl+Digit2 | 2 | Ctrl+2 | | Ctrl+2 | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | | -| Shift+Digit2 | @ | Shift+2 | | Shift+2 | shift+2 | Shift+2 | shift+[Digit2] | | -| Ctrl+Shift+Digit2 | @ | Ctrl+Shift+2 | | Ctrl+Shift+2 | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | | -| Alt+Digit2 | 2 | Alt+2 | | Alt+2 | alt+2 | Alt+2 | alt+[Digit2] | | -| Ctrl+Alt+Digit2 | 2 | Ctrl+Alt+2 | | Ctrl+Alt+2 | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | | -| Shift+Alt+Digit2 | @ | Shift+Alt+2 | | Shift+Alt+2 | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | | -| Ctrl+Shift+Alt+Digit2 | @ | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit3 | 3 | 3 | | 3 | 3 | 3 | [Digit3] | | -| Ctrl+Digit3 | 3 | Ctrl+3 | | Ctrl+3 | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | | -| Shift+Digit3 | # | Shift+3 | | Shift+3 | shift+3 | Shift+3 | shift+[Digit3] | | -| Ctrl+Shift+Digit3 | # | Ctrl+Shift+3 | | Ctrl+Shift+3 | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | | -| Alt+Digit3 | 3 | Alt+3 | | Alt+3 | alt+3 | Alt+3 | alt+[Digit3] | | -| Ctrl+Alt+Digit3 | 3 | Ctrl+Alt+3 | | Ctrl+Alt+3 | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | | -| Shift+Alt+Digit3 | # | Shift+Alt+3 | | Shift+Alt+3 | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | | -| Ctrl+Shift+Alt+Digit3 | # | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit4 | 4 | 4 | | 4 | 4 | 4 | [Digit4] | | -| Ctrl+Digit4 | 4 | Ctrl+4 | | Ctrl+4 | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | | -| Shift+Digit4 | $ | Shift+4 | | Shift+4 | shift+4 | Shift+4 | shift+[Digit4] | | -| Ctrl+Shift+Digit4 | $ | Ctrl+Shift+4 | | Ctrl+Shift+4 | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | | -| Alt+Digit4 | 4 | Alt+4 | | Alt+4 | alt+4 | Alt+4 | alt+[Digit4] | | -| Ctrl+Alt+Digit4 | 4 | Ctrl+Alt+4 | | Ctrl+Alt+4 | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | | -| Shift+Alt+Digit4 | $ | Shift+Alt+4 | | Shift+Alt+4 | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | | -| Ctrl+Shift+Alt+Digit4 | $ | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit5 | 5 | 5 | | 5 | 5 | 5 | [Digit5] | | -| Ctrl+Digit5 | 5 | Ctrl+5 | | Ctrl+5 | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | | -| Shift+Digit5 | % | Shift+5 | | Shift+5 | shift+5 | Shift+5 | shift+[Digit5] | | -| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+5 | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | | -| Alt+Digit5 | 5 | Alt+5 | | Alt+5 | alt+5 | Alt+5 | alt+[Digit5] | | -| Ctrl+Alt+Digit5 | 5 | Ctrl+Alt+5 | | Ctrl+Alt+5 | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | | -| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Alt+5 | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | | -| Ctrl+Shift+Alt+Digit5 | % | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit6 | 6 | 6 | | 6 | 6 | 6 | [Digit6] | | -| Ctrl+Digit6 | 6 | Ctrl+6 | | Ctrl+6 | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | | -| Shift+Digit6 | ^ | Shift+6 | | Shift+6 | shift+6 | Shift+6 | shift+[Digit6] | | -| Ctrl+Shift+Digit6 | ^ | Ctrl+Shift+6 | | Ctrl+Shift+6 | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | | -| Alt+Digit6 | 6 | Alt+6 | | Alt+6 | alt+6 | Alt+6 | alt+[Digit6] | | -| Ctrl+Alt+Digit6 | 6 | Ctrl+Alt+6 | | Ctrl+Alt+6 | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | | -| Shift+Alt+Digit6 | ^ | Shift+Alt+6 | | Shift+Alt+6 | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | | -| Ctrl+Shift+Alt+Digit6 | ^ | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit7 | 7 | 7 | | 7 | 7 | 7 | [Digit7] | | -| Ctrl+Digit7 | 7 | Ctrl+7 | | Ctrl+7 | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | | -| Shift+Digit7 | & | Shift+7 | | Shift+7 | shift+7 | Shift+7 | shift+[Digit7] | | -| Ctrl+Shift+Digit7 | & | Ctrl+Shift+7 | | Ctrl+Shift+7 | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | | -| Alt+Digit7 | 7 | Alt+7 | | Alt+7 | alt+7 | Alt+7 | alt+[Digit7] | | -| Ctrl+Alt+Digit7 | 7 | Ctrl+Alt+7 | | Ctrl+Alt+7 | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | | -| Shift+Alt+Digit7 | & | Shift+Alt+7 | | Shift+Alt+7 | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | | -| Ctrl+Shift+Alt+Digit7 | & | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit8 | 8 | 8 | | 8 | 8 | 8 | [Digit8] | | -| Ctrl+Digit8 | 8 | Ctrl+8 | | Ctrl+8 | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | | -| Shift+Digit8 | * | Shift+8 | | Shift+8 | shift+8 | Shift+8 | shift+[Digit8] | | -| Ctrl+Shift+Digit8 | * | Ctrl+Shift+8 | | Ctrl+Shift+8 | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | | -| Alt+Digit8 | 8 | Alt+8 | | Alt+8 | alt+8 | Alt+8 | alt+[Digit8] | | -| Ctrl+Alt+Digit8 | 8 | Ctrl+Alt+8 | | Ctrl+Alt+8 | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | | -| Shift+Alt+Digit8 | * | Shift+Alt+8 | | Shift+Alt+8 | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | | -| Ctrl+Shift+Alt+Digit8 | * | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit9 | 9 | 9 | | 9 | 9 | 9 | [Digit9] | | -| Ctrl+Digit9 | 9 | Ctrl+9 | | Ctrl+9 | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | | -| Shift+Digit9 | ( | Shift+9 | | Shift+9 | shift+9 | Shift+9 | shift+[Digit9] | | -| Ctrl+Shift+Digit9 | ( | Ctrl+Shift+9 | | Ctrl+Shift+9 | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | | -| Alt+Digit9 | 9 | Alt+9 | | Alt+9 | alt+9 | Alt+9 | alt+[Digit9] | | -| Ctrl+Alt+Digit9 | 9 | Ctrl+Alt+9 | | Ctrl+Alt+9 | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | | -| Shift+Alt+Digit9 | ( | Shift+Alt+9 | | Shift+Alt+9 | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | | -| Ctrl+Shift+Alt+Digit9 | ( | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit0 | 0 | 0 | | 0 | 0 | 0 | [Digit0] | | -| Ctrl+Digit0 | 0 | Ctrl+0 | | Ctrl+0 | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | | -| Shift+Digit0 | ) | Shift+0 | | Shift+0 | shift+0 | Shift+0 | shift+[Digit0] | | -| Ctrl+Shift+Digit0 | ) | Ctrl+Shift+0 | | Ctrl+Shift+0 | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | | -| Alt+Digit0 | 0 | Alt+0 | | Alt+0 | alt+0 | Alt+0 | alt+[Digit0] | | -| Ctrl+Alt+Digit0 | 0 | Ctrl+Alt+0 | | Ctrl+Alt+0 | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | | -| Shift+Alt+Digit0 | ) | Shift+Alt+0 | | Shift+Alt+0 | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | | -| Ctrl+Shift+Alt+Digit0 | ) | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Minus | - | - | | - | - | - | [Minus] | | -| Ctrl+Minus | - | Ctrl+- | | Ctrl+- | ctrl+- | Ctrl+- | ctrl+[Minus] | | -| Shift+Minus | _ | Shift+- | | Shift+- | shift+- | Shift+- | shift+[Minus] | | -| Ctrl+Shift+Minus | _ | Ctrl+Shift+- | | Ctrl+Shift+- | ctrl+shift+- | Ctrl+Shift+- | ctrl+shift+[Minus] | | -| Alt+Minus | - | Alt+- | | Alt+- | alt+- | Alt+- | alt+[Minus] | | -| Ctrl+Alt+Minus | - | Ctrl+Alt+- | | Ctrl+Alt+- | ctrl+alt+- | Ctrl+Alt+- | ctrl+alt+[Minus] | | -| Shift+Alt+Minus | _ | Shift+Alt+- | | Shift+Alt+- | shift+alt+- | Shift+Alt+- | shift+alt+[Minus] | | -| Ctrl+Shift+Alt+Minus | _ | Ctrl+Shift+Alt+- | | Ctrl+Shift+Alt+- | ctrl+shift+alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+[Minus] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Equal | = | = | | = | = | = | [Equal] | | -| Ctrl+Equal | = | Ctrl+= | | Ctrl+= | ctrl+= | Ctrl+= | ctrl+[Equal] | | -| Shift+Equal | + | Shift+= | | Shift+= | shift+= | Shift+= | shift+[Equal] | | -| Ctrl+Shift+Equal | + | Ctrl+Shift+= | | Ctrl+Shift+= | ctrl+shift+= | Ctrl+Shift+= | ctrl+shift+[Equal] | | -| Alt+Equal | = | Alt+= | | Alt+= | alt+= | Alt+= | alt+[Equal] | | -| Ctrl+Alt+Equal | = | Ctrl+Alt+= | | Ctrl+Alt+= | ctrl+alt+= | Ctrl+Alt+= | ctrl+alt+[Equal] | | -| Shift+Alt+Equal | + | Shift+Alt+= | | Shift+Alt+= | shift+alt+= | Shift+Alt+= | shift+alt+[Equal] | | -| Ctrl+Shift+Alt+Equal | + | Ctrl+Shift+Alt+= | | Ctrl+Shift+Alt+= | ctrl+shift+alt+= | Ctrl+Shift+Alt+= | ctrl+shift+alt+[Equal] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketLeft | [ | [ | | [ | [ | [ | [BracketLeft] | | -| Ctrl+BracketLeft | [ | Ctrl+[ | | Ctrl+[ | ctrl+[ | Ctrl+[ | ctrl+[BracketLeft] | | -| Shift+BracketLeft | { | Shift+[ | | Shift+[ | shift+[ | Shift+[ | shift+[BracketLeft] | | -| Ctrl+Shift+BracketLeft | { | Ctrl+Shift+[ | | Ctrl+Shift+[ | ctrl+shift+[ | Ctrl+Shift+[ | ctrl+shift+[BracketLeft] | | -| Alt+BracketLeft | [ | Alt+[ | | Alt+[ | alt+[ | Alt+[ | alt+[BracketLeft] | | -| Ctrl+Alt+BracketLeft | [ | Ctrl+Alt+[ | | Ctrl+Alt+[ | ctrl+alt+[ | Ctrl+Alt+[ | ctrl+alt+[BracketLeft] | | -| Shift+Alt+BracketLeft | { | Shift+Alt+[ | | Shift+Alt+[ | shift+alt+[ | Shift+Alt+[ | shift+alt+[BracketLeft] | | -| Ctrl+Shift+Alt+BracketLeft | { | Ctrl+Shift+Alt+[ | | Ctrl+Shift+Alt+[ | ctrl+shift+alt+[ | Ctrl+Shift+Alt+[ | ctrl+shift+alt+[BracketLeft] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketRight | ] | ] | | ] | ] | ] | [BracketRight] | | -| Ctrl+BracketRight | ] | Ctrl+] | | Ctrl+] | ctrl+] | Ctrl+] | ctrl+[BracketRight] | | -| Shift+BracketRight | } | Shift+] | | Shift+] | shift+] | Shift+] | shift+[BracketRight] | | -| Ctrl+Shift+BracketRight | } | Ctrl+Shift+] | | Ctrl+Shift+] | ctrl+shift+] | Ctrl+Shift+] | ctrl+shift+[BracketRight] | | -| Alt+BracketRight | ] | Alt+] | | Alt+] | alt+] | Alt+] | alt+[BracketRight] | | -| Ctrl+Alt+BracketRight | ] | Ctrl+Alt+] | | Ctrl+Alt+] | ctrl+alt+] | Ctrl+Alt+] | ctrl+alt+[BracketRight] | | -| Shift+Alt+BracketRight | } | Shift+Alt+] | | Shift+Alt+] | shift+alt+] | Shift+Alt+] | shift+alt+[BracketRight] | | -| Ctrl+Shift+Alt+BracketRight | } | Ctrl+Shift+Alt+] | | Ctrl+Shift+Alt+] | ctrl+shift+alt+] | Ctrl+Shift+Alt+] | ctrl+shift+alt+[BracketRight] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backslash | \ | \ | | \ | \ | \ | [Backslash] | | -| Ctrl+Backslash | \ | Ctrl+\ | | Ctrl+\ | ctrl+\ | Ctrl+\ | ctrl+[Backslash] | | -| Shift+Backslash | | | Shift+\ | 1 | Shift+\ | shift+\ | Shift+\ | shift+[Backslash] | | -| Ctrl+Shift+Backslash | | | Ctrl+Shift+\ | | Ctrl+Shift+\ | ctrl+shift+\ | Ctrl+Shift+\ | ctrl+shift+[Backslash] | | -| Alt+Backslash | \ | Alt+\ | | Alt+\ | alt+\ | Alt+\ | alt+[Backslash] | | -| Ctrl+Alt+Backslash | \ | Ctrl+Alt+\ | | Ctrl+Alt+\ | ctrl+alt+\ | Ctrl+Alt+\ | ctrl+alt+[Backslash] | | -| Shift+Alt+Backslash | | | Shift+Alt+\ | | Shift+Alt+\ | shift+alt+\ | Shift+Alt+\ | shift+alt+[Backslash] | | -| Ctrl+Shift+Alt+Backslash | | | Ctrl+Shift+Alt+\ | | Ctrl+Shift+Alt+\ | ctrl+shift+alt+\ | Ctrl+Shift+Alt+\ | ctrl+shift+alt+[Backslash] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlHash | --- | | | null | null | null | null | | -| Ctrl+IntlHash | --- | | | null | null | null | null | | -| Shift+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | -| Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | -| Shift+Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Semicolon | ; | ; | | ; | ; | ; | [Semicolon] | | -| Ctrl+Semicolon | ; | Ctrl+; | | Ctrl+; | ctrl+; | Ctrl+; | ctrl+[Semicolon] | | -| Shift+Semicolon | : | Shift+; | | Shift+; | shift+; | Shift+; | shift+[Semicolon] | | -| Ctrl+Shift+Semicolon | : | Ctrl+Shift+; | | Ctrl+Shift+; | ctrl+shift+; | Ctrl+Shift+; | ctrl+shift+[Semicolon] | | -| Alt+Semicolon | ; | Alt+; | | Alt+; | alt+; | Alt+; | alt+[Semicolon] | | -| Ctrl+Alt+Semicolon | ; | Ctrl+Alt+; | | Ctrl+Alt+; | ctrl+alt+; | Ctrl+Alt+; | ctrl+alt+[Semicolon] | | -| Shift+Alt+Semicolon | : | Shift+Alt+; | | Shift+Alt+; | shift+alt+; | Shift+Alt+; | shift+alt+[Semicolon] | | -| Ctrl+Shift+Alt+Semicolon | : | Ctrl+Shift+Alt+; | | Ctrl+Shift+Alt+; | ctrl+shift+alt+; | Ctrl+Shift+Alt+; | ctrl+shift+alt+[Semicolon] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Quote | ' | ' | | ' | ' | ' | [Quote] | | -| Ctrl+Quote | ' | Ctrl+' | | Ctrl+' | ctrl+' | Ctrl+' | ctrl+[Quote] | | -| Shift+Quote | " | Shift+' | | Shift+' | shift+' | Shift+' | shift+[Quote] | | -| Ctrl+Shift+Quote | " | Ctrl+Shift+' | | Ctrl+Shift+' | ctrl+shift+' | Ctrl+Shift+' | ctrl+shift+[Quote] | | -| Alt+Quote | ' | Alt+' | | Alt+' | alt+' | Alt+' | alt+[Quote] | | -| Ctrl+Alt+Quote | ' | Ctrl+Alt+' | | Ctrl+Alt+' | ctrl+alt+' | Ctrl+Alt+' | ctrl+alt+[Quote] | | -| Shift+Alt+Quote | " | Shift+Alt+' | | Shift+Alt+' | shift+alt+' | Shift+Alt+' | shift+alt+[Quote] | | -| Ctrl+Shift+Alt+Quote | " | Ctrl+Shift+Alt+' | | Ctrl+Shift+Alt+' | ctrl+shift+alt+' | Ctrl+Shift+Alt+' | ctrl+shift+alt+[Quote] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backquote | ` | ` | | ` | ` | ` | [Backquote] | | -| Ctrl+Backquote | ` | Ctrl+` | | Ctrl+` | ctrl+` | Ctrl+` | ctrl+[Backquote] | | -| Shift+Backquote | ~ | Shift+` | | Shift+` | shift+` | Shift+` | shift+[Backquote] | | -| Ctrl+Shift+Backquote | ~ | Ctrl+Shift+` | | Ctrl+Shift+` | ctrl+shift+` | Ctrl+Shift+` | ctrl+shift+[Backquote] | | -| Alt+Backquote | ` | Alt+` | | Alt+` | alt+` | Alt+` | alt+[Backquote] | | -| Ctrl+Alt+Backquote | ` | Ctrl+Alt+` | | Ctrl+Alt+` | ctrl+alt+` | Ctrl+Alt+` | ctrl+alt+[Backquote] | | -| Shift+Alt+Backquote | ~ | Shift+Alt+` | | Shift+Alt+` | shift+alt+` | Shift+Alt+` | shift+alt+[Backquote] | | -| Ctrl+Shift+Alt+Backquote | ~ | Ctrl+Shift+Alt+` | | Ctrl+Shift+Alt+` | ctrl+shift+alt+` | Ctrl+Shift+Alt+` | ctrl+shift+alt+[Backquote] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Comma | , | , | | , | , | , | [Comma] | | -| Ctrl+Comma | , | Ctrl+, | | Ctrl+, | ctrl+, | Ctrl+, | ctrl+[Comma] | | -| Shift+Comma | < | Shift+, | 1 | Shift+, | shift+, | Shift+, | shift+[Comma] | | -| Ctrl+Shift+Comma | < | Ctrl+Shift+, | 1 | Ctrl+Shift+, | ctrl+shift+, | Ctrl+Shift+, | ctrl+shift+[Comma] | | -| Alt+Comma | , | Alt+, | | Alt+, | alt+, | Alt+, | alt+[Comma] | | -| Ctrl+Alt+Comma | , | Ctrl+Alt+, | | Ctrl+Alt+, | ctrl+alt+, | Ctrl+Alt+, | ctrl+alt+[Comma] | | -| Shift+Alt+Comma | < | Shift+Alt+, | 1 | Shift+Alt+, | shift+alt+, | Shift+Alt+, | shift+alt+[Comma] | | -| Ctrl+Shift+Alt+Comma | < | Ctrl+Shift+Alt+, | | Ctrl+Shift+Alt+, | ctrl+shift+alt+, | Ctrl+Shift+Alt+, | ctrl+shift+alt+[Comma] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Period | . | . | | . | . | . | [Period] | | -| Ctrl+Period | . | Ctrl+. | | Ctrl+. | ctrl+. | Ctrl+. | ctrl+[Period] | | -| Shift+Period | > | Shift+. | 1 | Shift+. | shift+. | Shift+. | shift+[Period] | | -| Ctrl+Shift+Period | > | Ctrl+Shift+. | 1 | Ctrl+Shift+. | ctrl+shift+. | Ctrl+Shift+. | ctrl+shift+[Period] | | -| Alt+Period | . | Alt+. | | Alt+. | alt+. | Alt+. | alt+[Period] | | -| Ctrl+Alt+Period | . | Ctrl+Alt+. | | Ctrl+Alt+. | ctrl+alt+. | Ctrl+Alt+. | ctrl+alt+[Period] | | -| Shift+Alt+Period | > | Shift+Alt+. | 1 | Shift+Alt+. | shift+alt+. | Shift+Alt+. | shift+alt+[Period] | | -| Ctrl+Shift+Alt+Period | > | Ctrl+Shift+Alt+. | 1 | Ctrl+Shift+Alt+. | ctrl+shift+alt+. | Ctrl+Shift+Alt+. | ctrl+shift+alt+[Period] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Slash | / | / | | / | / | / | [Slash] | | -| Ctrl+Slash | / | Ctrl+/ | | Ctrl+/ | ctrl+/ | Ctrl+/ | ctrl+[Slash] | | -| Shift+Slash | ? | Shift+/ | | Shift+/ | shift+/ | Shift+/ | shift+[Slash] | | -| Ctrl+Shift+Slash | ? | Ctrl+Shift+/ | | Ctrl+Shift+/ | ctrl+shift+/ | Ctrl+Shift+/ | ctrl+shift+[Slash] | | -| Alt+Slash | / | Alt+/ | | Alt+/ | alt+/ | Alt+/ | alt+[Slash] | | -| Ctrl+Alt+Slash | / | Ctrl+Alt+/ | | Ctrl+Alt+/ | ctrl+alt+/ | Ctrl+Alt+/ | ctrl+alt+[Slash] | | -| Shift+Alt+Slash | ? | Shift+Alt+/ | | Shift+Alt+/ | shift+alt+/ | Shift+Alt+/ | shift+alt+[Slash] | | -| Ctrl+Shift+Alt+Slash | ? | Ctrl+Shift+Alt+/ | | Ctrl+Shift+Alt+/ | ctrl+shift+alt+/ | Ctrl+Shift+Alt+/ | ctrl+shift+alt+[Slash] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | -| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | -| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | -| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | -| Alt+ArrowUp | --- | Alt+UpArrow | | Alt+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | -| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Alt+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | -| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Alt+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | -| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | -| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | -| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | -| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | -| Alt+Numpad0 | --- | Alt+NumPad0 | | Alt+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | -| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | -| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Alt+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | -| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlBackslash | < | Shift+, | 2 | < | [IntlBackslash] | null | [IntlBackslash] | NO | -| Ctrl+IntlBackslash | < | Ctrl+Shift+, | 2 | Ctrl+< | ctrl+[IntlBackslash] | null | ctrl+[IntlBackslash] | NO | -| Shift+IntlBackslash | > | Shift+. | 2 | Shift+< | shift+[IntlBackslash] | null | shift+[IntlBackslash] | NO | -| Ctrl+Shift+IntlBackslash | > | Ctrl+Shift+. | 2 | Ctrl+Shift+< | ctrl+shift+[IntlBackslash] | null | ctrl+shift+[IntlBackslash] | NO | -| Alt+IntlBackslash | < | Shift+Alt+, | 2 | Alt+< | alt+[IntlBackslash] | null | alt+[IntlBackslash] | NO | -| Ctrl+Alt+IntlBackslash | | | Shift+\ | 2 | Ctrl+Alt+< | ctrl+alt+[IntlBackslash] | null | ctrl+alt+[IntlBackslash] | NO | -| Shift+Alt+IntlBackslash | > | Shift+Alt+. | 2 | Shift+Alt+< | shift+alt+[IntlBackslash] | null | shift+alt+[IntlBackslash] | NO | -| Ctrl+Shift+Alt+IntlBackslash | ¦ | Ctrl+Shift+Alt+. | 2 | Ctrl+Shift+Alt+< | ctrl+shift+alt+[IntlBackslash] | null | ctrl+shift+alt+[IntlBackslash] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | -| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | -| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | -| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | -| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | -| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | -| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | -| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | -| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | -| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | -| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | -| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | -| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | -| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | -| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/linux_ru.js b/src/vs/workbench/services/keybinding/test/electron-browser/linux_ru.js deleted file mode 100644 index 950223704b6..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/linux_ru.js +++ /dev/null @@ -1,1046 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -define({ - Sleep: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - WakeUp: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - KeyA: { - value: 'ф', - withShift: 'Ф', - withAltGr: 'ф', - withShiftAltGr: 'Ф' - }, - KeyB: { - value: 'и', - withShift: 'И', - withAltGr: 'и', - withShiftAltGr: 'И' - }, - KeyC: { - value: 'с', - withShift: 'С', - withAltGr: 'с', - withShiftAltGr: 'С' - }, - KeyD: { - value: 'в', - withShift: 'В', - withAltGr: 'в', - withShiftAltGr: 'В' - }, - KeyE: { - value: 'у', - withShift: 'У', - withAltGr: 'у', - withShiftAltGr: 'У' - }, - KeyF: { - value: 'а', - withShift: 'А', - withAltGr: 'а', - withShiftAltGr: 'А' - }, - KeyG: { - value: 'п', - withShift: 'П', - withAltGr: 'п', - withShiftAltGr: 'П' - }, - KeyH: { - value: 'р', - withShift: 'Р', - withAltGr: 'р', - withShiftAltGr: 'Р' - }, - KeyI: { - value: 'ш', - withShift: 'Ш', - withAltGr: 'ш', - withShiftAltGr: 'Ш' - }, - KeyJ: { - value: 'о', - withShift: 'О', - withAltGr: 'о', - withShiftAltGr: 'О' - }, - KeyK: { - value: 'л', - withShift: 'Л', - withAltGr: 'л', - withShiftAltGr: 'Л' - }, - KeyL: { - value: 'д', - withShift: 'Д', - withAltGr: 'д', - withShiftAltGr: 'Д' - }, - KeyM: { - value: 'ь', - withShift: 'Ь', - withAltGr: 'ь', - withShiftAltGr: 'Ь' - }, - KeyN: { - value: 'т', - withShift: 'Т', - withAltGr: 'т', - withShiftAltGr: 'Т' - }, - KeyO: { - value: 'щ', - withShift: 'Щ', - withAltGr: 'щ', - withShiftAltGr: 'Щ' - }, - KeyP: { - value: 'з', - withShift: 'З', - withAltGr: 'з', - withShiftAltGr: 'З' - }, - KeyQ: { - value: 'й', - withShift: 'Й', - withAltGr: 'й', - withShiftAltGr: 'Й' - }, - KeyR: { - value: 'к', - withShift: 'К', - withAltGr: 'к', - withShiftAltGr: 'К' - }, - KeyS: { - value: 'ы', - withShift: 'Ы', - withAltGr: 'ы', - withShiftAltGr: 'Ы' - }, - KeyT: { - value: 'е', - withShift: 'Е', - withAltGr: 'е', - withShiftAltGr: 'Е' - }, - KeyU: { - value: 'г', - withShift: 'Г', - withAltGr: 'г', - withShiftAltGr: 'Г' - }, - KeyV: { - value: 'м', - withShift: 'М', - withAltGr: 'м', - withShiftAltGr: 'М' - }, - KeyW: { - value: 'ц', - withShift: 'Ц', - withAltGr: 'ц', - withShiftAltGr: 'Ц' - }, - KeyX: { - value: 'ч', - withShift: 'Ч', - withAltGr: 'ч', - withShiftAltGr: 'Ч' - }, - KeyY: { - value: 'н', - withShift: 'Н', - withAltGr: 'н', - withShiftAltGr: 'Н' - }, - KeyZ: { - value: 'я', - withShift: 'Я', - withAltGr: 'я', - withShiftAltGr: 'Я' - }, - Digit1: { - value: '1', - withShift: '!', - withAltGr: '1', - withShiftAltGr: '!' - }, - Digit2: { - value: '2', - withShift: '"', - withAltGr: '2', - withShiftAltGr: '"' - }, - Digit3: { - value: '3', - withShift: '№', - withAltGr: '3', - withShiftAltGr: '№' - }, - Digit4: { - value: '4', - withShift: ';', - withAltGr: '4', - withShiftAltGr: ';' - }, - Digit5: { - value: '5', - withShift: '%', - withAltGr: '5', - withShiftAltGr: '%' - }, - Digit6: { - value: '6', - withShift: ':', - withAltGr: '6', - withShiftAltGr: ':' - }, - Digit7: { - value: '7', - withShift: '?', - withAltGr: '7', - withShiftAltGr: '?' - }, - Digit8: { - value: '8', - withShift: '*', - withAltGr: '8', - withShiftAltGr: '*' - }, - Digit9: { - value: '9', - withShift: '(', - withAltGr: '9', - withShiftAltGr: '(' - }, - Digit0: { - value: '0', - withShift: ')', - withAltGr: '0', - withShiftAltGr: ')' - }, - Enter: { - value: '\r', - withShift: '\r', - withAltGr: '\r', - withShiftAltGr: '\r' - }, - Escape: { - value: '\u001b', - withShift: '\u001b', - withAltGr: '\u001b', - withShiftAltGr: '\u001b' - }, - Backspace: { - value: '\b', - withShift: '\b', - withAltGr: '\b', - withShiftAltGr: '\b' - }, - Tab: { - value: '\t', - withShift: '', - withAltGr: '\t', - withShiftAltGr: '' - }, - Space: { - value: ' ', - withShift: ' ', - withAltGr: ' ', - withShiftAltGr: ' ' - }, - Minus: { - value: '-', - withShift: '_', - withAltGr: '-', - withShiftAltGr: '_' - }, - Equal: { - value: '=', - withShift: '+', - withAltGr: '=', - withShiftAltGr: '+' - }, - BracketLeft: { - value: 'х', - withShift: 'Х', - withAltGr: 'х', - withShiftAltGr: 'Х' - }, - BracketRight: { - value: 'ъ', - withShift: 'Ъ', - withAltGr: 'ъ', - withShiftAltGr: 'Ъ' - }, - Backslash: { - value: '\\', - withShift: '/', - withAltGr: '\\', - withShiftAltGr: '/' - }, - Semicolon: { - value: 'ж', - withShift: 'Ж', - withAltGr: 'ж', - withShiftAltGr: 'Ж' - }, - Quote: { - value: 'э', - withShift: 'Э', - withAltGr: 'э', - withShiftAltGr: 'Э' - }, - Backquote: { - value: 'ё', - withShift: 'Ё', - withAltGr: 'ё', - withShiftAltGr: 'Ё' - }, - Comma: { - value: 'б', - withShift: 'Б', - withAltGr: 'б', - withShiftAltGr: 'Б' - }, - Period: { - value: 'ю', - withShift: 'Ю', - withAltGr: 'ю', - withShiftAltGr: 'Ю' - }, - Slash: { - value: '.', - withShift: ',', - withAltGr: '.', - withShiftAltGr: ',' - }, - CapsLock: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F1: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F2: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F3: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F4: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F5: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F6: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F7: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F8: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F9: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F10: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F11: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F12: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PrintScreen: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ScrollLock: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Pause: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Insert: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Home: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PageUp: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Delete: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - End: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PageDown: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowRight: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowLeft: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowDown: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowUp: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumLock: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadDivide: { - value: '/', - withShift: '/', - withAltGr: '/', - withShiftAltGr: '/' - }, - NumpadMultiply: { - value: '*', - withShift: '*', - withAltGr: '*', - withShiftAltGr: '*' - }, - NumpadSubtract: { - value: '-', - withShift: '-', - withAltGr: '-', - withShiftAltGr: '-' - }, - NumpadAdd: { - value: '+', - withShift: '+', - withAltGr: '+', - withShiftAltGr: '+' - }, - NumpadEnter: { - value: '\r', - withShift: '\r', - withAltGr: '\r', - withShiftAltGr: '\r' - }, - Numpad1: { - value: '', - withShift: '1', - withAltGr: '', - withShiftAltGr: '1' - }, - Numpad2: { - value: '', - withShift: '2', - withAltGr: '', - withShiftAltGr: '2' - }, - Numpad3: { - value: '', - withShift: '3', - withAltGr: '', - withShiftAltGr: '3' - }, - Numpad4: { - value: '', - withShift: '4', - withAltGr: '', - withShiftAltGr: '4' - }, - Numpad5: { - value: '', - withShift: '5', - withAltGr: '', - withShiftAltGr: '5' - }, - Numpad6: { - value: '', - withShift: '6', - withAltGr: '', - withShiftAltGr: '6' - }, - Numpad7: { - value: '', - withShift: '7', - withAltGr: '', - withShiftAltGr: '7' - }, - Numpad8: { - value: '', - withShift: '8', - withAltGr: '', - withShiftAltGr: '8' - }, - Numpad9: { - value: '', - withShift: '9', - withAltGr: '', - withShiftAltGr: '9' - }, - Numpad0: { - value: '', - withShift: '0', - withAltGr: '', - withShiftAltGr: '0' - }, - NumpadDecimal: { - value: '', - withShift: ',', - withAltGr: '', - withShiftAltGr: ',' - }, - IntlBackslash: { - value: '/', - withShift: '|', - withAltGr: '|', - withShiftAltGr: '¦' - }, - ContextMenu: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Power: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadEqual: { - value: '=', - withShift: '=', - withAltGr: '=', - withShiftAltGr: '=' - }, - F13: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F14: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F15: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F16: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F17: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F18: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F19: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F20: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F21: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F22: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F23: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F24: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Open: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Help: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Select: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Again: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Undo: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Cut: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Copy: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Paste: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Find: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeMute: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeUp: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeDown: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadComma: { - value: '.', - withShift: '.', - withAltGr: '.', - withShiftAltGr: '.' - }, - IntlRo: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - KanaMode: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - IntlYen: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Convert: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NonConvert: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang1: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang2: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang3: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang4: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang5: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadParenLeft: { - value: '(', - withShift: '(', - withAltGr: '(', - withShiftAltGr: '(' - }, - NumpadParenRight: { - value: ')', - withShift: ')', - withAltGr: ')', - withShiftAltGr: ')' - }, - ControlLeft: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ShiftLeft: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AltLeft: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MetaLeft: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ControlRight: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ShiftRight: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AltRight: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MetaRight: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrightnessUp: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrightnessDown: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaPlay: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaRecord: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaFastForward: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaRewind: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaTrackNext: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaTrackPrevious: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaStop: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Eject: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaPlayPause: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaSelect: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchMail: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchApp2: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchApp1: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - SelectTask: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchScreenSaver: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserSearch: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserHome: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserBack: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserForward: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserStop: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserRefresh: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserFavorites: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MailReply: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MailForward: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MailSend: { - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - } -}); diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/linux_ru.txt b/src/vs/workbench/services/keybinding/test/electron-browser/linux_ru.txt deleted file mode 100644 index 389681ee995..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/linux_ru.txt +++ /dev/null @@ -1,523 +0,0 @@ -isUSStandard: false ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyA | ф | A | | A | a | A | [KeyA] | | -| Ctrl+KeyA | ф | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | -| Shift+KeyA | Ф | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | -| Ctrl+Shift+KeyA | Ф | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | -| Alt+KeyA | ф | Alt+A | | Alt+A | alt+a | Alt+A | alt+[KeyA] | | -| Ctrl+Alt+KeyA | ф | Ctrl+Alt+A | | Ctrl+Alt+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | -| Shift+Alt+KeyA | Ф | Shift+Alt+A | | Shift+Alt+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | -| Ctrl+Shift+Alt+KeyA | Ф | Ctrl+Shift+Alt+A | | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyB | и | B | | B | b | B | [KeyB] | | -| Ctrl+KeyB | и | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | -| Shift+KeyB | И | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | -| Ctrl+Shift+KeyB | И | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | -| Alt+KeyB | и | Alt+B | | Alt+B | alt+b | Alt+B | alt+[KeyB] | | -| Ctrl+Alt+KeyB | и | Ctrl+Alt+B | | Ctrl+Alt+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | -| Shift+Alt+KeyB | И | Shift+Alt+B | | Shift+Alt+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | -| Ctrl+Shift+Alt+KeyB | И | Ctrl+Shift+Alt+B | | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyC | с | C | | C | c | C | [KeyC] | | -| Ctrl+KeyC | с | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | -| Shift+KeyC | С | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | -| Ctrl+Shift+KeyC | С | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | -| Alt+KeyC | с | Alt+C | | Alt+C | alt+c | Alt+C | alt+[KeyC] | | -| Ctrl+Alt+KeyC | с | Ctrl+Alt+C | | Ctrl+Alt+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | -| Shift+Alt+KeyC | С | Shift+Alt+C | | Shift+Alt+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | -| Ctrl+Shift+Alt+KeyC | С | Ctrl+Shift+Alt+C | | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyD | в | D | | D | d | D | [KeyD] | | -| Ctrl+KeyD | в | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | -| Shift+KeyD | В | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | -| Ctrl+Shift+KeyD | В | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | -| Alt+KeyD | в | Alt+D | | Alt+D | alt+d | Alt+D | alt+[KeyD] | | -| Ctrl+Alt+KeyD | в | Ctrl+Alt+D | | Ctrl+Alt+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | -| Shift+Alt+KeyD | В | Shift+Alt+D | | Shift+Alt+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | -| Ctrl+Shift+Alt+KeyD | В | Ctrl+Shift+Alt+D | | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyE | у | E | | E | e | E | [KeyE] | | -| Ctrl+KeyE | у | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | -| Shift+KeyE | У | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | -| Ctrl+Shift+KeyE | У | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | -| Alt+KeyE | у | Alt+E | | Alt+E | alt+e | Alt+E | alt+[KeyE] | | -| Ctrl+Alt+KeyE | у | Ctrl+Alt+E | | Ctrl+Alt+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | -| Shift+Alt+KeyE | У | Shift+Alt+E | | Shift+Alt+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | -| Ctrl+Shift+Alt+KeyE | У | Ctrl+Shift+Alt+E | | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyF | а | F | | F | f | F | [KeyF] | | -| Ctrl+KeyF | а | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | -| Shift+KeyF | А | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | -| Ctrl+Shift+KeyF | А | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | -| Alt+KeyF | а | Alt+F | | Alt+F | alt+f | Alt+F | alt+[KeyF] | | -| Ctrl+Alt+KeyF | а | Ctrl+Alt+F | | Ctrl+Alt+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | -| Shift+Alt+KeyF | А | Shift+Alt+F | | Shift+Alt+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | -| Ctrl+Shift+Alt+KeyF | А | Ctrl+Shift+Alt+F | | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyG | п | G | | G | g | G | [KeyG] | | -| Ctrl+KeyG | п | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | -| Shift+KeyG | П | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | -| Ctrl+Shift+KeyG | П | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | -| Alt+KeyG | п | Alt+G | | Alt+G | alt+g | Alt+G | alt+[KeyG] | | -| Ctrl+Alt+KeyG | п | Ctrl+Alt+G | | Ctrl+Alt+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | -| Shift+Alt+KeyG | П | Shift+Alt+G | | Shift+Alt+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | -| Ctrl+Shift+Alt+KeyG | П | Ctrl+Shift+Alt+G | | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyH | р | H | | H | h | H | [KeyH] | | -| Ctrl+KeyH | р | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | -| Shift+KeyH | Р | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | -| Ctrl+Shift+KeyH | Р | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | -| Alt+KeyH | р | Alt+H | | Alt+H | alt+h | Alt+H | alt+[KeyH] | | -| Ctrl+Alt+KeyH | р | Ctrl+Alt+H | | Ctrl+Alt+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | -| Shift+Alt+KeyH | Р | Shift+Alt+H | | Shift+Alt+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | -| Ctrl+Shift+Alt+KeyH | Р | Ctrl+Shift+Alt+H | | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyI | ш | I | | I | i | I | [KeyI] | | -| Ctrl+KeyI | ш | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | -| Shift+KeyI | Ш | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | -| Ctrl+Shift+KeyI | Ш | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | -| Alt+KeyI | ш | Alt+I | | Alt+I | alt+i | Alt+I | alt+[KeyI] | | -| Ctrl+Alt+KeyI | ш | Ctrl+Alt+I | | Ctrl+Alt+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | -| Shift+Alt+KeyI | Ш | Shift+Alt+I | | Shift+Alt+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | -| Ctrl+Shift+Alt+KeyI | Ш | Ctrl+Shift+Alt+I | | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyJ | о | J | | J | j | J | [KeyJ] | | -| Ctrl+KeyJ | о | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | -| Shift+KeyJ | О | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | -| Ctrl+Shift+KeyJ | О | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | -| Alt+KeyJ | о | Alt+J | | Alt+J | alt+j | Alt+J | alt+[KeyJ] | | -| Ctrl+Alt+KeyJ | о | Ctrl+Alt+J | | Ctrl+Alt+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | -| Shift+Alt+KeyJ | О | Shift+Alt+J | | Shift+Alt+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | -| Ctrl+Shift+Alt+KeyJ | О | Ctrl+Shift+Alt+J | | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyK | л | K | | K | k | K | [KeyK] | | -| Ctrl+KeyK | л | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | -| Shift+KeyK | Л | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | -| Ctrl+Shift+KeyK | Л | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | -| Alt+KeyK | л | Alt+K | | Alt+K | alt+k | Alt+K | alt+[KeyK] | | -| Ctrl+Alt+KeyK | л | Ctrl+Alt+K | | Ctrl+Alt+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | -| Shift+Alt+KeyK | Л | Shift+Alt+K | | Shift+Alt+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | -| Ctrl+Shift+Alt+KeyK | Л | Ctrl+Shift+Alt+K | | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyL | д | L | | L | l | L | [KeyL] | | -| Ctrl+KeyL | д | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | -| Shift+KeyL | Д | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | -| Ctrl+Shift+KeyL | Д | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | -| Alt+KeyL | д | Alt+L | | Alt+L | alt+l | Alt+L | alt+[KeyL] | | -| Ctrl+Alt+KeyL | д | Ctrl+Alt+L | | Ctrl+Alt+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | -| Shift+Alt+KeyL | Д | Shift+Alt+L | | Shift+Alt+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | -| Ctrl+Shift+Alt+KeyL | Д | Ctrl+Shift+Alt+L | | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyM | ь | M | | M | m | M | [KeyM] | | -| Ctrl+KeyM | ь | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | -| Shift+KeyM | Ь | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | -| Ctrl+Shift+KeyM | Ь | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | -| Alt+KeyM | ь | Alt+M | | Alt+M | alt+m | Alt+M | alt+[KeyM] | | -| Ctrl+Alt+KeyM | ь | Ctrl+Alt+M | | Ctrl+Alt+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | -| Shift+Alt+KeyM | Ь | Shift+Alt+M | | Shift+Alt+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | -| Ctrl+Shift+Alt+KeyM | Ь | Ctrl+Shift+Alt+M | | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyN | т | N | | N | n | N | [KeyN] | | -| Ctrl+KeyN | т | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | -| Shift+KeyN | Т | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | -| Ctrl+Shift+KeyN | Т | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | -| Alt+KeyN | т | Alt+N | | Alt+N | alt+n | Alt+N | alt+[KeyN] | | -| Ctrl+Alt+KeyN | т | Ctrl+Alt+N | | Ctrl+Alt+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | -| Shift+Alt+KeyN | Т | Shift+Alt+N | | Shift+Alt+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | -| Ctrl+Shift+Alt+KeyN | Т | Ctrl+Shift+Alt+N | | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyO | щ | O | | O | o | O | [KeyO] | | -| Ctrl+KeyO | щ | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | -| Shift+KeyO | Щ | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | -| Ctrl+Shift+KeyO | Щ | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | -| Alt+KeyO | щ | Alt+O | | Alt+O | alt+o | Alt+O | alt+[KeyO] | | -| Ctrl+Alt+KeyO | щ | Ctrl+Alt+O | | Ctrl+Alt+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | -| Shift+Alt+KeyO | Щ | Shift+Alt+O | | Shift+Alt+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | -| Ctrl+Shift+Alt+KeyO | Щ | Ctrl+Shift+Alt+O | | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyP | з | P | | P | p | P | [KeyP] | | -| Ctrl+KeyP | з | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | -| Shift+KeyP | З | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | -| Ctrl+Shift+KeyP | З | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | -| Alt+KeyP | з | Alt+P | | Alt+P | alt+p | Alt+P | alt+[KeyP] | | -| Ctrl+Alt+KeyP | з | Ctrl+Alt+P | | Ctrl+Alt+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | -| Shift+Alt+KeyP | З | Shift+Alt+P | | Shift+Alt+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | -| Ctrl+Shift+Alt+KeyP | З | Ctrl+Shift+Alt+P | | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyQ | й | Q | | Q | q | Q | [KeyQ] | | -| Ctrl+KeyQ | й | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | -| Shift+KeyQ | Й | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | -| Ctrl+Shift+KeyQ | Й | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | -| Alt+KeyQ | й | Alt+Q | | Alt+Q | alt+q | Alt+Q | alt+[KeyQ] | | -| Ctrl+Alt+KeyQ | й | Ctrl+Alt+Q | | Ctrl+Alt+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | -| Shift+Alt+KeyQ | Й | Shift+Alt+Q | | Shift+Alt+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | -| Ctrl+Shift+Alt+KeyQ | Й | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyR | к | R | | R | r | R | [KeyR] | | -| Ctrl+KeyR | к | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | -| Shift+KeyR | К | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | -| Ctrl+Shift+KeyR | К | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | -| Alt+KeyR | к | Alt+R | | Alt+R | alt+r | Alt+R | alt+[KeyR] | | -| Ctrl+Alt+KeyR | к | Ctrl+Alt+R | | Ctrl+Alt+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | -| Shift+Alt+KeyR | К | Shift+Alt+R | | Shift+Alt+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | -| Ctrl+Shift+Alt+KeyR | К | Ctrl+Shift+Alt+R | | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyS | ы | S | | S | s | S | [KeyS] | | -| Ctrl+KeyS | ы | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | -| Shift+KeyS | Ы | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | -| Ctrl+Shift+KeyS | Ы | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | -| Alt+KeyS | ы | Alt+S | | Alt+S | alt+s | Alt+S | alt+[KeyS] | | -| Ctrl+Alt+KeyS | ы | Ctrl+Alt+S | | Ctrl+Alt+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | -| Shift+Alt+KeyS | Ы | Shift+Alt+S | | Shift+Alt+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | -| Ctrl+Shift+Alt+KeyS | Ы | Ctrl+Shift+Alt+S | | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyT | е | T | | T | t | T | [KeyT] | | -| Ctrl+KeyT | е | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | -| Shift+KeyT | Е | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | -| Ctrl+Shift+KeyT | Е | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | -| Alt+KeyT | е | Alt+T | | Alt+T | alt+t | Alt+T | alt+[KeyT] | | -| Ctrl+Alt+KeyT | е | Ctrl+Alt+T | | Ctrl+Alt+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | -| Shift+Alt+KeyT | Е | Shift+Alt+T | | Shift+Alt+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | -| Ctrl+Shift+Alt+KeyT | Е | Ctrl+Shift+Alt+T | | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyU | г | U | | U | u | U | [KeyU] | | -| Ctrl+KeyU | г | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | -| Shift+KeyU | Г | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | -| Ctrl+Shift+KeyU | Г | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | -| Alt+KeyU | г | Alt+U | | Alt+U | alt+u | Alt+U | alt+[KeyU] | | -| Ctrl+Alt+KeyU | г | Ctrl+Alt+U | | Ctrl+Alt+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | -| Shift+Alt+KeyU | Г | Shift+Alt+U | | Shift+Alt+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | -| Ctrl+Shift+Alt+KeyU | Г | Ctrl+Shift+Alt+U | | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyV | м | V | | V | v | V | [KeyV] | | -| Ctrl+KeyV | м | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | -| Shift+KeyV | М | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | -| Ctrl+Shift+KeyV | М | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | -| Alt+KeyV | м | Alt+V | | Alt+V | alt+v | Alt+V | alt+[KeyV] | | -| Ctrl+Alt+KeyV | м | Ctrl+Alt+V | | Ctrl+Alt+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | -| Shift+Alt+KeyV | М | Shift+Alt+V | | Shift+Alt+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | -| Ctrl+Shift+Alt+KeyV | М | Ctrl+Shift+Alt+V | | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyW | ц | W | | W | w | W | [KeyW] | | -| Ctrl+KeyW | ц | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | -| Shift+KeyW | Ц | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | -| Ctrl+Shift+KeyW | Ц | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | -| Alt+KeyW | ц | Alt+W | | Alt+W | alt+w | Alt+W | alt+[KeyW] | | -| Ctrl+Alt+KeyW | ц | Ctrl+Alt+W | | Ctrl+Alt+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | -| Shift+Alt+KeyW | Ц | Shift+Alt+W | | Shift+Alt+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | -| Ctrl+Shift+Alt+KeyW | Ц | Ctrl+Shift+Alt+W | | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyX | ч | X | | X | x | X | [KeyX] | | -| Ctrl+KeyX | ч | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | -| Shift+KeyX | Ч | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | -| Ctrl+Shift+KeyX | Ч | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | -| Alt+KeyX | ч | Alt+X | | Alt+X | alt+x | Alt+X | alt+[KeyX] | | -| Ctrl+Alt+KeyX | ч | Ctrl+Alt+X | | Ctrl+Alt+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | -| Shift+Alt+KeyX | Ч | Shift+Alt+X | | Shift+Alt+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | -| Ctrl+Shift+Alt+KeyX | Ч | Ctrl+Shift+Alt+X | | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyY | н | Y | | Y | y | Y | [KeyY] | | -| Ctrl+KeyY | н | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyY] | | -| Shift+KeyY | Н | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyY] | | -| Ctrl+Shift+KeyY | Н | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyY] | | -| Alt+KeyY | н | Alt+Y | | Alt+Y | alt+y | Alt+Y | alt+[KeyY] | | -| Ctrl+Alt+KeyY | н | Ctrl+Alt+Y | | Ctrl+Alt+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyY] | | -| Shift+Alt+KeyY | Н | Shift+Alt+Y | | Shift+Alt+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyY] | | -| Ctrl+Shift+Alt+KeyY | Н | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyY] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyZ | я | Z | | Z | z | Z | [KeyZ] | | -| Ctrl+KeyZ | я | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyZ] | | -| Shift+KeyZ | Я | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyZ] | | -| Ctrl+Shift+KeyZ | Я | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyZ] | | -| Alt+KeyZ | я | Alt+Z | | Alt+Z | alt+z | Alt+Z | alt+[KeyZ] | | -| Ctrl+Alt+KeyZ | я | Ctrl+Alt+Z | | Ctrl+Alt+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyZ] | | -| Shift+Alt+KeyZ | Я | Shift+Alt+Z | | Shift+Alt+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyZ] | | -| Ctrl+Shift+Alt+KeyZ | Я | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyZ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit1 | 1 | 1 | | 1 | 1 | 1 | [Digit1] | | -| Ctrl+Digit1 | 1 | Ctrl+1 | | Ctrl+1 | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | | -| Shift+Digit1 | ! | Shift+1 | | Shift+1 | shift+1 | Shift+1 | shift+[Digit1] | | -| Ctrl+Shift+Digit1 | ! | Ctrl+Shift+1 | | Ctrl+Shift+1 | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | | -| Alt+Digit1 | 1 | Alt+1 | | Alt+1 | alt+1 | Alt+1 | alt+[Digit1] | | -| Ctrl+Alt+Digit1 | 1 | Ctrl+Alt+1 | | Ctrl+Alt+1 | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | | -| Shift+Alt+Digit1 | ! | Shift+Alt+1 | | Shift+Alt+1 | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | | -| Ctrl+Shift+Alt+Digit1 | ! | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit2 | 2 | 2 | | 2 | 2 | 2 | [Digit2] | | -| Ctrl+Digit2 | 2 | Ctrl+2 | | Ctrl+2 | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | | -| Shift+Digit2 | " | Shift+2 | | Shift+2 | shift+2 | Shift+2 | shift+[Digit2] | | -| | | Shift+' | | | | | | | -| Ctrl+Shift+Digit2 | " | Ctrl+Shift+2 | | Ctrl+Shift+2 | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | | -| | | Ctrl+Shift+' | | | | | | | -| Alt+Digit2 | 2 | Alt+2 | | Alt+2 | alt+2 | Alt+2 | alt+[Digit2] | | -| Ctrl+Alt+Digit2 | 2 | Ctrl+Alt+2 | | Ctrl+Alt+2 | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | | -| Shift+Alt+Digit2 | " | Shift+Alt+2 | | Shift+Alt+2 | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | | -| | | Shift+Alt+' | | | | | | | -| Ctrl+Shift+Alt+Digit2 | " | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | | -| | | Ctrl+Shift+Alt+' | | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit3 | 3 | 3 | | 3 | 3 | 3 | [Digit3] | | -| Ctrl+Digit3 | 3 | Ctrl+3 | | Ctrl+3 | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | | -| Shift+Digit3 | № | Shift+3 | | Shift+3 | shift+3 | Shift+3 | shift+[Digit3] | | -| Ctrl+Shift+Digit3 | № | Ctrl+Shift+3 | | Ctrl+Shift+3 | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | | -| Alt+Digit3 | 3 | Alt+3 | | Alt+3 | alt+3 | Alt+3 | alt+[Digit3] | | -| Ctrl+Alt+Digit3 | 3 | Ctrl+Alt+3 | | Ctrl+Alt+3 | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | | -| Shift+Alt+Digit3 | № | Shift+Alt+3 | | Shift+Alt+3 | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | | -| Ctrl+Shift+Alt+Digit3 | № | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit4 | 4 | 4 | | 4 | 4 | 4 | [Digit4] | | -| Ctrl+Digit4 | 4 | Ctrl+4 | | Ctrl+4 | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | | -| Shift+Digit4 | ; | Shift+4 | | Shift+4 | shift+4 | Shift+4 | shift+[Digit4] | | -| | | ; | | | | | | | -| Ctrl+Shift+Digit4 | ; | Ctrl+Shift+4 | | Ctrl+Shift+4 | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | | -| | | Ctrl+; | | | | | | | -| Alt+Digit4 | 4 | Alt+4 | | Alt+4 | alt+4 | Alt+4 | alt+[Digit4] | | -| Ctrl+Alt+Digit4 | 4 | Ctrl+Alt+4 | | Ctrl+Alt+4 | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | | -| Shift+Alt+Digit4 | ; | Shift+Alt+4 | | Shift+Alt+4 | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | | -| | | Alt+; | | | | | | | -| Ctrl+Shift+Alt+Digit4 | ; | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | | -| | | Ctrl+Alt+; | | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit5 | 5 | 5 | | 5 | 5 | 5 | [Digit5] | | -| Ctrl+Digit5 | 5 | Ctrl+5 | | Ctrl+5 | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | | -| Shift+Digit5 | % | Shift+5 | | Shift+5 | shift+5 | Shift+5 | shift+[Digit5] | | -| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+5 | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | | -| Alt+Digit5 | 5 | Alt+5 | | Alt+5 | alt+5 | Alt+5 | alt+[Digit5] | | -| Ctrl+Alt+Digit5 | 5 | Ctrl+Alt+5 | | Ctrl+Alt+5 | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | | -| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Alt+5 | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | | -| Ctrl+Shift+Alt+Digit5 | % | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit6 | 6 | 6 | | 6 | 6 | 6 | [Digit6] | | -| Ctrl+Digit6 | 6 | Ctrl+6 | | Ctrl+6 | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | | -| Shift+Digit6 | : | Shift+6 | | Shift+6 | shift+6 | Shift+6 | shift+[Digit6] | | -| | | Shift+; | | | | | | | -| Ctrl+Shift+Digit6 | : | Ctrl+Shift+6 | | Ctrl+Shift+6 | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | | -| | | Ctrl+Shift+; | | | | | | | -| Alt+Digit6 | 6 | Alt+6 | | Alt+6 | alt+6 | Alt+6 | alt+[Digit6] | | -| Ctrl+Alt+Digit6 | 6 | Ctrl+Alt+6 | | Ctrl+Alt+6 | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | | -| Shift+Alt+Digit6 | : | Shift+Alt+6 | | Shift+Alt+6 | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | | -| | | Shift+Alt+; | | | | | | | -| Ctrl+Shift+Alt+Digit6 | : | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | | -| | | Ctrl+Shift+Alt+; | | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit7 | 7 | 7 | | 7 | 7 | 7 | [Digit7] | | -| Ctrl+Digit7 | 7 | Ctrl+7 | | Ctrl+7 | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | | -| Shift+Digit7 | ? | Shift+7 | | Shift+7 | shift+7 | Shift+7 | shift+[Digit7] | | -| | | Shift+/ | | | | | | | -| Ctrl+Shift+Digit7 | ? | Ctrl+Shift+7 | | Ctrl+Shift+7 | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | | -| | | Ctrl+Shift+/ | | | | | | | -| Alt+Digit7 | 7 | Alt+7 | | Alt+7 | alt+7 | Alt+7 | alt+[Digit7] | | -| Ctrl+Alt+Digit7 | 7 | Ctrl+Alt+7 | | Ctrl+Alt+7 | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | | -| Shift+Alt+Digit7 | ? | Shift+Alt+7 | | Shift+Alt+7 | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | | -| | | Shift+Alt+/ | | | | | | | -| Ctrl+Shift+Alt+Digit7 | ? | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | | -| | | Ctrl+Shift+Alt+/ | | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit8 | 8 | 8 | | 8 | 8 | 8 | [Digit8] | | -| Ctrl+Digit8 | 8 | Ctrl+8 | | Ctrl+8 | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | | -| Shift+Digit8 | * | Shift+8 | | Shift+8 | shift+8 | Shift+8 | shift+[Digit8] | | -| Ctrl+Shift+Digit8 | * | Ctrl+Shift+8 | | Ctrl+Shift+8 | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | | -| Alt+Digit8 | 8 | Alt+8 | | Alt+8 | alt+8 | Alt+8 | alt+[Digit8] | | -| Ctrl+Alt+Digit8 | 8 | Ctrl+Alt+8 | | Ctrl+Alt+8 | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | | -| Shift+Alt+Digit8 | * | Shift+Alt+8 | | Shift+Alt+8 | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | | -| Ctrl+Shift+Alt+Digit8 | * | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit9 | 9 | 9 | | 9 | 9 | 9 | [Digit9] | | -| Ctrl+Digit9 | 9 | Ctrl+9 | | Ctrl+9 | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | | -| Shift+Digit9 | ( | Shift+9 | | Shift+9 | shift+9 | Shift+9 | shift+[Digit9] | | -| Ctrl+Shift+Digit9 | ( | Ctrl+Shift+9 | | Ctrl+Shift+9 | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | | -| Alt+Digit9 | 9 | Alt+9 | | Alt+9 | alt+9 | Alt+9 | alt+[Digit9] | | -| Ctrl+Alt+Digit9 | 9 | Ctrl+Alt+9 | | Ctrl+Alt+9 | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | | -| Shift+Alt+Digit9 | ( | Shift+Alt+9 | | Shift+Alt+9 | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | | -| Ctrl+Shift+Alt+Digit9 | ( | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit0 | 0 | 0 | | 0 | 0 | 0 | [Digit0] | | -| Ctrl+Digit0 | 0 | Ctrl+0 | | Ctrl+0 | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | | -| Shift+Digit0 | ) | Shift+0 | | Shift+0 | shift+0 | Shift+0 | shift+[Digit0] | | -| Ctrl+Shift+Digit0 | ) | Ctrl+Shift+0 | | Ctrl+Shift+0 | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | | -| Alt+Digit0 | 0 | Alt+0 | | Alt+0 | alt+0 | Alt+0 | alt+[Digit0] | | -| Ctrl+Alt+Digit0 | 0 | Ctrl+Alt+0 | | Ctrl+Alt+0 | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | | -| Shift+Alt+Digit0 | ) | Shift+Alt+0 | | Shift+Alt+0 | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | | -| Ctrl+Shift+Alt+Digit0 | ) | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Minus | - | - | | - | - | null | [Minus] | | -| Ctrl+Minus | - | Ctrl+- | | Ctrl+- | ctrl+- | null | ctrl+[Minus] | | -| Shift+Minus | _ | Shift+- | | Shift+- | shift+- | null | shift+[Minus] | | -| Ctrl+Shift+Minus | _ | Ctrl+Shift+- | | Ctrl+Shift+- | ctrl+shift+- | null | ctrl+shift+[Minus] | | -| Alt+Minus | - | Alt+- | | Alt+- | alt+- | null | alt+[Minus] | | -| Ctrl+Alt+Minus | - | Ctrl+Alt+- | | Ctrl+Alt+- | ctrl+alt+- | null | ctrl+alt+[Minus] | | -| Shift+Alt+Minus | _ | Shift+Alt+- | | Shift+Alt+- | shift+alt+- | null | shift+alt+[Minus] | | -| Ctrl+Shift+Alt+Minus | _ | Ctrl+Shift+Alt+- | | Ctrl+Shift+Alt+- | ctrl+shift+alt+- | null | ctrl+shift+alt+[Minus] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Equal | = | = | | = | = | null | [Equal] | | -| Ctrl+Equal | = | Ctrl+= | | Ctrl+= | ctrl+= | null | ctrl+[Equal] | | -| Shift+Equal | + | Shift+= | | Shift+= | shift+= | null | shift+[Equal] | | -| Ctrl+Shift+Equal | + | Ctrl+Shift+= | | Ctrl+Shift+= | ctrl+shift+= | null | ctrl+shift+[Equal] | | -| Alt+Equal | = | Alt+= | | Alt+= | alt+= | null | alt+[Equal] | | -| Ctrl+Alt+Equal | = | Ctrl+Alt+= | | Ctrl+Alt+= | ctrl+alt+= | null | ctrl+alt+[Equal] | | -| Shift+Alt+Equal | + | Shift+Alt+= | | Shift+Alt+= | shift+alt+= | null | shift+alt+[Equal] | | -| Ctrl+Shift+Alt+Equal | + | Ctrl+Shift+Alt+= | | Ctrl+Shift+Alt+= | ctrl+shift+alt+= | null | ctrl+shift+alt+[Equal] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketLeft | х | | | х | [BracketLeft] | null | [BracketLeft] | NO | -| Ctrl+BracketLeft | х | | | Ctrl+х | ctrl+[BracketLeft] | null | ctrl+[BracketLeft] | NO | -| Shift+BracketLeft | Х | | | Shift+х | shift+[BracketLeft] | null | shift+[BracketLeft] | NO | -| Ctrl+Shift+BracketLeft | Х | | | Ctrl+Shift+х | ctrl+shift+[BracketLeft] | null | ctrl+shift+[BracketLeft] | NO | -| Alt+BracketLeft | х | | | Alt+х | alt+[BracketLeft] | null | alt+[BracketLeft] | NO | -| Ctrl+Alt+BracketLeft | х | | | Ctrl+Alt+х | ctrl+alt+[BracketLeft] | null | ctrl+alt+[BracketLeft] | NO | -| Shift+Alt+BracketLeft | Х | | | Shift+Alt+х | shift+alt+[BracketLeft] | null | shift+alt+[BracketLeft] | NO | -| Ctrl+Shift+Alt+BracketLeft | Х | | | Ctrl+Shift+Alt+х | ctrl+shift+alt+[BracketLeft] | null | ctrl+shift+alt+[BracketLeft] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketRight | ъ | | | ъ | [BracketRight] | null | [BracketRight] | NO | -| Ctrl+BracketRight | ъ | | | Ctrl+ъ | ctrl+[BracketRight] | null | ctrl+[BracketRight] | NO | -| Shift+BracketRight | Ъ | | | Shift+ъ | shift+[BracketRight] | null | shift+[BracketRight] | NO | -| Ctrl+Shift+BracketRight | Ъ | | | Ctrl+Shift+ъ | ctrl+shift+[BracketRight] | null | ctrl+shift+[BracketRight] | NO | -| Alt+BracketRight | ъ | | | Alt+ъ | alt+[BracketRight] | null | alt+[BracketRight] | NO | -| Ctrl+Alt+BracketRight | ъ | | | Ctrl+Alt+ъ | ctrl+alt+[BracketRight] | null | ctrl+alt+[BracketRight] | NO | -| Shift+Alt+BracketRight | Ъ | | | Shift+Alt+ъ | shift+alt+[BracketRight] | null | shift+alt+[BracketRight] | NO | -| Ctrl+Shift+Alt+BracketRight | Ъ | | | Ctrl+Shift+Alt+ъ | ctrl+shift+alt+[BracketRight] | null | ctrl+shift+alt+[BracketRight] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backslash | \ | \ | | \ | [Backslash] | null | [Backslash] | NO | -| Ctrl+Backslash | \ | Ctrl+\ | | Ctrl+\ | ctrl+[Backslash] | null | ctrl+[Backslash] | NO | -| Shift+Backslash | / | / | 1 | Shift+\ | shift+[Backslash] | null | shift+[Backslash] | NO | -| Ctrl+Shift+Backslash | / | Ctrl+/ | 1 | Ctrl+Shift+\ | ctrl+shift+[Backslash] | null | ctrl+shift+[Backslash] | NO | -| Alt+Backslash | \ | Alt+\ | | Alt+\ | alt+[Backslash] | null | alt+[Backslash] | NO | -| Ctrl+Alt+Backslash | \ | Ctrl+Alt+\ | | Ctrl+Alt+\ | ctrl+alt+[Backslash] | null | ctrl+alt+[Backslash] | NO | -| Shift+Alt+Backslash | / | Alt+/ | 1 | Shift+Alt+\ | shift+alt+[Backslash] | null | shift+alt+[Backslash] | NO | -| Ctrl+Shift+Alt+Backslash | / | Ctrl+Alt+/ | 1 | Ctrl+Shift+Alt+\ | ctrl+shift+alt+[Backslash] | null | ctrl+shift+alt+[Backslash] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlHash | --- | | | null | null | null | null | | -| Ctrl+IntlHash | --- | | | null | null | null | null | | -| Shift+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | -| Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | -| Shift+Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Semicolon | ж | | | ж | [Semicolon] | null | [Semicolon] | NO | -| Ctrl+Semicolon | ж | | | Ctrl+ж | ctrl+[Semicolon] | null | ctrl+[Semicolon] | NO | -| Shift+Semicolon | Ж | | | Shift+ж | shift+[Semicolon] | null | shift+[Semicolon] | NO | -| Ctrl+Shift+Semicolon | Ж | | | Ctrl+Shift+ж | ctrl+shift+[Semicolon] | null | ctrl+shift+[Semicolon] | NO | -| Alt+Semicolon | ж | | | Alt+ж | alt+[Semicolon] | null | alt+[Semicolon] | NO | -| Ctrl+Alt+Semicolon | ж | | | Ctrl+Alt+ж | ctrl+alt+[Semicolon] | null | ctrl+alt+[Semicolon] | NO | -| Shift+Alt+Semicolon | Ж | | | Shift+Alt+ж | shift+alt+[Semicolon] | null | shift+alt+[Semicolon] | NO | -| Ctrl+Shift+Alt+Semicolon | Ж | | | Ctrl+Shift+Alt+ж | ctrl+shift+alt+[Semicolon] | null | ctrl+shift+alt+[Semicolon] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Quote | э | | | э | [Quote] | null | [Quote] | NO | -| Ctrl+Quote | э | | | Ctrl+э | ctrl+[Quote] | null | ctrl+[Quote] | NO | -| Shift+Quote | Э | | | Shift+э | shift+[Quote] | null | shift+[Quote] | NO | -| Ctrl+Shift+Quote | Э | | | Ctrl+Shift+э | ctrl+shift+[Quote] | null | ctrl+shift+[Quote] | NO | -| Alt+Quote | э | | | Alt+э | alt+[Quote] | null | alt+[Quote] | NO | -| Ctrl+Alt+Quote | э | | | Ctrl+Alt+э | ctrl+alt+[Quote] | null | ctrl+alt+[Quote] | NO | -| Shift+Alt+Quote | Э | | | Shift+Alt+э | shift+alt+[Quote] | null | shift+alt+[Quote] | NO | -| Ctrl+Shift+Alt+Quote | Э | | | Ctrl+Shift+Alt+э | ctrl+shift+alt+[Quote] | null | ctrl+shift+alt+[Quote] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backquote | ё | | | ё | [Backquote] | null | [Backquote] | NO | -| Ctrl+Backquote | ё | | | Ctrl+ё | ctrl+[Backquote] | null | ctrl+[Backquote] | NO | -| Shift+Backquote | Ё | | | Shift+ё | shift+[Backquote] | null | shift+[Backquote] | NO | -| Ctrl+Shift+Backquote | Ё | | | Ctrl+Shift+ё | ctrl+shift+[Backquote] | null | ctrl+shift+[Backquote] | NO | -| Alt+Backquote | ё | | | Alt+ё | alt+[Backquote] | null | alt+[Backquote] | NO | -| Ctrl+Alt+Backquote | ё | | | Ctrl+Alt+ё | ctrl+alt+[Backquote] | null | ctrl+alt+[Backquote] | NO | -| Shift+Alt+Backquote | Ё | | | Shift+Alt+ё | shift+alt+[Backquote] | null | shift+alt+[Backquote] | NO | -| Ctrl+Shift+Alt+Backquote | Ё | | | Ctrl+Shift+Alt+ё | ctrl+shift+alt+[Backquote] | null | ctrl+shift+alt+[Backquote] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Comma | б | | | б | [Comma] | null | [Comma] | NO | -| Ctrl+Comma | б | | | Ctrl+б | ctrl+[Comma] | null | ctrl+[Comma] | NO | -| Shift+Comma | Б | | | Shift+б | shift+[Comma] | null | shift+[Comma] | NO | -| Ctrl+Shift+Comma | Б | | | Ctrl+Shift+б | ctrl+shift+[Comma] | null | ctrl+shift+[Comma] | NO | -| Alt+Comma | б | | | Alt+б | alt+[Comma] | null | alt+[Comma] | NO | -| Ctrl+Alt+Comma | б | | | Ctrl+Alt+б | ctrl+alt+[Comma] | null | ctrl+alt+[Comma] | NO | -| Shift+Alt+Comma | Б | | | Shift+Alt+б | shift+alt+[Comma] | null | shift+alt+[Comma] | NO | -| Ctrl+Shift+Alt+Comma | Б | | | Ctrl+Shift+Alt+б | ctrl+shift+alt+[Comma] | null | ctrl+shift+alt+[Comma] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Period | ю | | | ю | [Period] | null | [Period] | NO | -| Ctrl+Period | ю | | | Ctrl+ю | ctrl+[Period] | null | ctrl+[Period] | NO | -| Shift+Period | Ю | | | Shift+ю | shift+[Period] | null | shift+[Period] | NO | -| Ctrl+Shift+Period | Ю | | | Ctrl+Shift+ю | ctrl+shift+[Period] | null | ctrl+shift+[Period] | NO | -| Alt+Period | ю | | | Alt+ю | alt+[Period] | null | alt+[Period] | NO | -| Ctrl+Alt+Period | ю | | | Ctrl+Alt+ю | ctrl+alt+[Period] | null | ctrl+alt+[Period] | NO | -| Shift+Alt+Period | Ю | | | Shift+Alt+ю | shift+alt+[Period] | null | shift+alt+[Period] | NO | -| Ctrl+Shift+Alt+Period | Ю | | | Ctrl+Shift+Alt+ю | ctrl+shift+alt+[Period] | null | ctrl+shift+alt+[Period] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Slash | . | . | | . | [Slash] | null | [Slash] | NO | -| Ctrl+Slash | . | Ctrl+. | | Ctrl+. | ctrl+[Slash] | null | ctrl+[Slash] | NO | -| Shift+Slash | , | , | | Shift+. | shift+[Slash] | null | shift+[Slash] | NO | -| Ctrl+Shift+Slash | , | Ctrl+, | | Ctrl+Shift+. | ctrl+shift+[Slash] | null | ctrl+shift+[Slash] | NO | -| Alt+Slash | . | Alt+. | | Alt+. | alt+[Slash] | null | alt+[Slash] | NO | -| Ctrl+Alt+Slash | . | Ctrl+Alt+. | | Ctrl+Alt+. | ctrl+alt+[Slash] | null | ctrl+alt+[Slash] | NO | -| Shift+Alt+Slash | , | Alt+, | | Shift+Alt+. | shift+alt+[Slash] | null | shift+alt+[Slash] | NO | -| Ctrl+Shift+Alt+Slash | , | Ctrl+Alt+, | | Ctrl+Shift+Alt+. | ctrl+shift+alt+[Slash] | null | ctrl+shift+alt+[Slash] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | -| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | -| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | -| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | -| Alt+ArrowUp | --- | Alt+UpArrow | | Alt+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | -| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Alt+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | -| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Alt+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | -| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | -| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | -| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | -| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | -| Alt+Numpad0 | --- | Alt+NumPad0 | | Alt+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | -| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | -| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Alt+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | -| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlBackslash | / | / | 2 | / | [IntlBackslash] | null | [IntlBackslash] | NO | -| Ctrl+IntlBackslash | / | Ctrl+/ | 2 | Ctrl+/ | ctrl+[IntlBackslash] | null | ctrl+[IntlBackslash] | NO | -| Shift+IntlBackslash | | | Shift+\ | | Shift+/ | shift+[IntlBackslash] | null | shift+[IntlBackslash] | NO | -| Ctrl+Shift+IntlBackslash | | | Ctrl+Shift+\ | | Ctrl+Shift+/ | ctrl+shift+[IntlBackslash] | null | ctrl+shift+[IntlBackslash] | NO | -| Alt+IntlBackslash | / | Alt+/ | 2 | Alt+/ | alt+[IntlBackslash] | null | alt+[IntlBackslash] | NO | -| Ctrl+Alt+IntlBackslash | | | Ctrl+Alt+/ | 2 | Ctrl+Alt+/ | ctrl+alt+[IntlBackslash] | null | ctrl+alt+[IntlBackslash] | NO | -| Shift+Alt+IntlBackslash | | | Shift+Alt+\ | | Shift+Alt+/ | shift+alt+[IntlBackslash] | null | shift+alt+[IntlBackslash] | NO | -| Ctrl+Shift+Alt+IntlBackslash | ¦ | Ctrl+Shift+Alt+\ | | Ctrl+Shift+Alt+/ | ctrl+shift+alt+[IntlBackslash] | null | ctrl+shift+alt+[IntlBackslash] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | -| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | -| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | -| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | -| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | -| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | -| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | -| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | -| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | -| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | -| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | -| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | -| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | -| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | -| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/macLinuxFallbackKeyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/electron-browser/macLinuxFallbackKeyboardMapper.test.ts deleted file mode 100644 index b7db656ffd6..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/macLinuxFallbackKeyboardMapper.test.ts +++ /dev/null @@ -1,352 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { KeyChord, KeyCode, KeyMod, ScanCode } from 'vs/base/common/keyCodes'; -import { SimpleKeybinding, createKeybinding, ScanCodeBinding } from 'vs/base/common/keybindings'; -import { OperatingSystem } from 'vs/base/common/platform'; -import { MacLinuxFallbackKeyboardMapper } from 'vs/workbench/services/keybinding/common/macLinuxFallbackKeyboardMapper'; -import { IResolvedKeybinding, assertResolveKeybinding, assertResolveKeyboardEvent, assertResolveUserBinding } from 'vs/workbench/services/keybinding/test/electron-browser/keyboardMapperTestUtils'; - -suite('keyboardMapper - MAC fallback', () => { - - const mapper = new MacLinuxFallbackKeyboardMapper(OperatingSystem.Macintosh); - - function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void { - assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Macintosh)!, expected); - } - - test('resolveKeybinding Cmd+Z', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.KeyZ, - [{ - label: '⌘Z', - ariaLabel: 'Command+Z', - electronAccelerator: 'Cmd+Z', - userSettingsLabel: 'cmd+z', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['meta+Z'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Cmd+K Cmd+=', () => { - _assertResolveKeybinding( - KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Equal), - [{ - label: '⌘K ⌘=', - ariaLabel: 'Command+K Command+=', - electronAccelerator: null, - userSettingsLabel: 'cmd+k cmd+=', - isWYSIWYG: true, - isChord: true, - dispatchParts: ['meta+K', 'meta+='], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveKeyboardEvent Cmd+Z', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: false, - metaKey: true, - keyCode: KeyCode.KeyZ, - code: null! - }, - { - label: '⌘Z', - ariaLabel: 'Command+Z', - electronAccelerator: 'Cmd+Z', - userSettingsLabel: 'cmd+z', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['meta+Z'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveUserBinding empty', () => { - assertResolveUserBinding(mapper, [], []); - }); - - test('resolveUserBinding Cmd+[Comma] Cmd+/', () => { - assertResolveUserBinding( - mapper, [ - new ScanCodeBinding(false, false, false, true, ScanCode.Comma), - new SimpleKeybinding(false, false, false, true, KeyCode.Slash), - ], - [{ - label: '⌘, ⌘/', - ariaLabel: 'Command+, Command+/', - electronAccelerator: null, - userSettingsLabel: 'cmd+, cmd+/', - isWYSIWYG: true, - isChord: true, - dispatchParts: ['meta+,', 'meta+/'], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveKeyboardEvent Single Modifier Meta+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: false, - metaKey: true, - keyCode: KeyCode.Meta, - code: null! - }, - { - label: '⌘', - ariaLabel: 'Command', - electronAccelerator: null, - userSettingsLabel: 'cmd', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['meta'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier Shift+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: true, - altKey: false, - metaKey: false, - keyCode: KeyCode.Shift, - code: null! - }, - { - label: '⇧', - ariaLabel: 'Shift', - electronAccelerator: null, - userSettingsLabel: 'shift', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['shift'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier Alt+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: true, - metaKey: false, - keyCode: KeyCode.Alt, - code: null! - }, - { - label: '⌥', - ariaLabel: 'Option', - electronAccelerator: null, - userSettingsLabel: 'alt', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['alt'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier Meta+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: false, - metaKey: true, - keyCode: KeyCode.Meta, - code: null! - }, - { - label: '⌘', - ariaLabel: 'Command', - electronAccelerator: null, - userSettingsLabel: 'cmd', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['meta'], - } - ); - }); - - test('resolveKeyboardEvent Only Modifiers Ctrl+Shift+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: true, - altKey: false, - metaKey: false, - keyCode: KeyCode.Shift, - code: null! - }, - { - label: '⌃⇧', - ariaLabel: 'Control+Shift', - electronAccelerator: null, - userSettingsLabel: 'ctrl+shift', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: [null], - } - ); - }); -}); - -suite('keyboardMapper - LINUX fallback', () => { - - const mapper = new MacLinuxFallbackKeyboardMapper(OperatingSystem.Linux); - - function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void { - assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Linux)!, expected); - } - - test('resolveKeybinding Ctrl+Z', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.KeyZ, - [{ - label: 'Ctrl+Z', - ariaLabel: 'Control+Z', - electronAccelerator: 'Ctrl+Z', - userSettingsLabel: 'ctrl+z', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+Z'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+K Ctrl+=', () => { - _assertResolveKeybinding( - KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Equal), - [{ - label: 'Ctrl+K Ctrl+=', - ariaLabel: 'Control+K Control+=', - electronAccelerator: null, - userSettingsLabel: 'ctrl+k ctrl+=', - isWYSIWYG: true, - isChord: true, - dispatchParts: ['ctrl+K', 'ctrl+='], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveKeyboardEvent Ctrl+Z', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: KeyCode.KeyZ, - code: null! - }, - { - label: 'Ctrl+Z', - ariaLabel: 'Control+Z', - electronAccelerator: 'Ctrl+Z', - userSettingsLabel: 'ctrl+z', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+Z'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveUserBinding Ctrl+[Comma] Ctrl+/', () => { - assertResolveUserBinding( - mapper, [ - new ScanCodeBinding(true, false, false, false, ScanCode.Comma), - new SimpleKeybinding(true, false, false, false, KeyCode.Slash), - ], - [{ - label: 'Ctrl+, Ctrl+/', - ariaLabel: 'Control+, Control+/', - electronAccelerator: null, - userSettingsLabel: 'ctrl+, ctrl+/', - isWYSIWYG: true, - isChord: true, - dispatchParts: ['ctrl+,', 'ctrl+/'], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveUserBinding Ctrl+[Comma]', () => { - assertResolveUserBinding( - mapper, [ - new ScanCodeBinding(true, false, false, false, ScanCode.Comma), - ], - [{ - label: 'Ctrl+,', - ariaLabel: 'Control+,', - electronAccelerator: 'Ctrl+,', - userSettingsLabel: 'ctrl+,', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+,'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeyboardEvent Single Modifier Ctrl+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: KeyCode.Ctrl, - code: null! - }, - { - label: 'Ctrl', - ariaLabel: 'Control', - electronAccelerator: null, - userSettingsLabel: 'ctrl', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['ctrl'], - } - ); - }); -}); diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/macLinuxKeyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/electron-browser/macLinuxKeyboardMapper.test.ts deleted file mode 100644 index a5984fc12e0..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/macLinuxKeyboardMapper.test.ts +++ /dev/null @@ -1,1730 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as assert from 'assert'; -import { KeyChord, KeyCode, KeyMod, ScanCode, ScanCodeUtils } from 'vs/base/common/keyCodes'; -import { SimpleKeybinding, createKeybinding, createSimpleKeybinding, ScanCodeBinding } from 'vs/base/common/keybindings'; -import { UserSettingsLabelProvider } from 'vs/base/common/keybindingLabels'; -import { OperatingSystem } from 'vs/base/common/platform'; -import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding'; -import { MacLinuxKeyboardMapper } from 'vs/workbench/services/keybinding/common/macLinuxKeyboardMapper'; -import { IResolvedKeybinding, assertMapping, assertResolveKeybinding, assertResolveKeyboardEvent, assertResolveUserBinding, readRawMapping } from 'vs/workbench/services/keybinding/test/electron-browser/keyboardMapperTestUtils'; -import { IMacLinuxKeyboardMapping } from 'vs/platform/keyboardLayout/common/keyboardLayout'; - -const WRITE_FILE_IF_DIFFERENT = false; - -async function createKeyboardMapper(isUSStandard: boolean, file: string, OS: OperatingSystem): Promise { - const rawMappings = await readRawMapping(file); - return new MacLinuxKeyboardMapper(isUSStandard, rawMappings, OS); -} - -suite('keyboardMapper - MAC de_ch', () => { - - let mapper: MacLinuxKeyboardMapper; - - suiteSetup(async () => { - const _mapper = await createKeyboardMapper(false, 'mac_de_ch', OperatingSystem.Macintosh); - mapper = _mapper; - }); - - test('mapping', () => { - return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'mac_de_ch.txt'); - }); - - function assertKeybindingTranslation(kb: number, expected: string | string[]): void { - _assertKeybindingTranslation(mapper, OperatingSystem.Macintosh, kb, expected); - } - - function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void { - assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Macintosh)!, expected); - } - - test('kb => hw', () => { - // unchanged - assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.Digit1, 'cmd+Digit1'); - assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.KeyB, 'cmd+KeyB'); - assertKeybindingTranslation(KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyB, 'shift+cmd+KeyB'); - assertKeybindingTranslation(KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyB, 'ctrl+shift+alt+cmd+KeyB'); - - // flips Y and Z - assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.KeyZ, 'cmd+KeyY'); - assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.KeyY, 'cmd+KeyZ'); - - // Ctrl+/ - assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.Slash, 'shift+cmd+Digit7'); - }); - - test('resolveKeybinding Cmd+A', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.KeyA, - [{ - label: '⌘A', - ariaLabel: 'Command+A', - electronAccelerator: 'Cmd+A', - userSettingsLabel: 'cmd+a', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['meta+[KeyA]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Cmd+B', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.KeyB, - [{ - label: '⌘B', - ariaLabel: 'Command+B', - electronAccelerator: 'Cmd+B', - userSettingsLabel: 'cmd+b', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['meta+[KeyB]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Cmd+Z', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.KeyZ, - [{ - label: '⌘Z', - ariaLabel: 'Command+Z', - electronAccelerator: 'Cmd+Z', - userSettingsLabel: 'cmd+z', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['meta+[KeyY]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeyboardEvent Cmd+[KeyY]', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: false, - metaKey: true, - keyCode: -1, - code: 'KeyY' - }, - { - label: '⌘Z', - ariaLabel: 'Command+Z', - electronAccelerator: 'Cmd+Z', - userSettingsLabel: 'cmd+z', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['meta+[KeyY]'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveKeybinding Cmd+]', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.BracketRight, - [{ - label: '⌃⌥⌘6', - ariaLabel: 'Control+Option+Command+6', - electronAccelerator: 'Ctrl+Alt+Cmd+6', - userSettingsLabel: 'ctrl+alt+cmd+6', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+alt+meta+[Digit6]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeyboardEvent Cmd+[BracketRight]', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: false, - metaKey: true, - keyCode: -1, - code: 'BracketRight' - }, - { - label: '⌘¨', - ariaLabel: 'Command+¨', - electronAccelerator: null, - userSettingsLabel: 'cmd+[BracketRight]', - isWYSIWYG: false, - isChord: false, - dispatchParts: ['meta+[BracketRight]'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveKeybinding Shift+]', () => { - _assertResolveKeybinding( - KeyMod.Shift | KeyCode.BracketRight, - [{ - label: '⌃⌥9', - ariaLabel: 'Control+Option+9', - electronAccelerator: 'Ctrl+Alt+9', - userSettingsLabel: 'ctrl+alt+9', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+alt+[Digit9]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Cmd+/', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.Slash, - [{ - label: '⇧⌘7', - ariaLabel: 'Shift+Command+7', - electronAccelerator: 'Shift+Cmd+7', - userSettingsLabel: 'shift+cmd+7', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['shift+meta+[Digit7]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Cmd+Shift+/', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Slash, - [{ - label: '⇧⌘\'', - ariaLabel: 'Shift+Command+\'', - electronAccelerator: null, - userSettingsLabel: 'shift+cmd+[Minus]', - isWYSIWYG: false, - isChord: false, - dispatchParts: ['shift+meta+[Minus]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Cmd+K Cmd+\\', () => { - _assertResolveKeybinding( - KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Backslash), - [{ - label: '⌘K ⌃⇧⌥⌘7', - ariaLabel: 'Command+K Control+Shift+Option+Command+7', - electronAccelerator: null, - userSettingsLabel: 'cmd+k ctrl+shift+alt+cmd+7', - isWYSIWYG: true, - isChord: true, - dispatchParts: ['meta+[KeyK]', 'ctrl+shift+alt+meta+[Digit7]'], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveKeybinding Cmd+K Cmd+=', () => { - _assertResolveKeybinding( - KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Equal), - [{ - label: '⌘K ⇧⌘0', - ariaLabel: 'Command+K Shift+Command+0', - electronAccelerator: null, - userSettingsLabel: 'cmd+k shift+cmd+0', - isWYSIWYG: true, - isChord: true, - dispatchParts: ['meta+[KeyK]', 'shift+meta+[Digit0]'], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveKeybinding Cmd+DownArrow', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.DownArrow, - [{ - label: '⌘↓', - ariaLabel: 'Command+DownArrow', - electronAccelerator: 'Cmd+Down', - userSettingsLabel: 'cmd+down', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['meta+[ArrowDown]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Cmd+NUMPAD_0', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.Numpad0, - [{ - label: '⌘NumPad0', - ariaLabel: 'Command+NumPad0', - electronAccelerator: null, - userSettingsLabel: 'cmd+numpad0', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['meta+[Numpad0]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+Home', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.Home, - [{ - label: '⌘Home', - ariaLabel: 'Command+Home', - electronAccelerator: 'Cmd+Home', - userSettingsLabel: 'cmd+home', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['meta+[Home]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeyboardEvent Ctrl+[Home]', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: false, - metaKey: true, - keyCode: -1, - code: 'Home' - }, - { - label: '⌘Home', - ariaLabel: 'Command+Home', - electronAccelerator: 'Cmd+Home', - userSettingsLabel: 'cmd+home', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['meta+[Home]'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveUserBinding empty', () => { - assertResolveUserBinding(mapper, [], []); - }); - - test('resolveUserBinding Cmd+[Comma] Cmd+/', () => { - assertResolveUserBinding( - mapper, - [ - new ScanCodeBinding(false, false, false, true, ScanCode.Comma), - new SimpleKeybinding(false, false, false, true, KeyCode.Slash), - ], - [{ - label: '⌘, ⇧⌘7', - ariaLabel: 'Command+, Shift+Command+7', - electronAccelerator: null, - userSettingsLabel: 'cmd+[Comma] shift+cmd+7', - isWYSIWYG: false, - isChord: true, - dispatchParts: ['meta+[Comma]', 'shift+meta+[Digit7]'], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveKeyboardEvent Single Modifier MetaLeft+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: false, - metaKey: true, - keyCode: -1, - code: 'MetaLeft' - }, - { - label: '⌘', - ariaLabel: 'Command', - electronAccelerator: null, - userSettingsLabel: 'cmd', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['meta'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier MetaRight+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: false, - metaKey: true, - keyCode: -1, - code: 'MetaRight' - }, - { - label: '⌘', - ariaLabel: 'Command', - electronAccelerator: null, - userSettingsLabel: 'cmd', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['meta'], - } - ); - }); -}); - -suite('keyboardMapper - MAC en_us', () => { - - let mapper: MacLinuxKeyboardMapper; - - suiteSetup(async () => { - const _mapper = await createKeyboardMapper(true, 'mac_en_us', OperatingSystem.Macintosh); - mapper = _mapper; - }); - - test('mapping', () => { - return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'mac_en_us.txt'); - }); - - test('resolveUserBinding Cmd+[Comma] Cmd+/', () => { - assertResolveUserBinding( - mapper, - [ - new ScanCodeBinding(false, false, false, true, ScanCode.Comma), - new SimpleKeybinding(false, false, false, true, KeyCode.Slash), - ], - [{ - label: '⌘, ⌘/', - ariaLabel: 'Command+, Command+/', - electronAccelerator: null, - userSettingsLabel: 'cmd+, cmd+/', - isWYSIWYG: true, - isChord: true, - dispatchParts: ['meta+[Comma]', 'meta+[Slash]'], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveKeyboardEvent Single Modifier MetaLeft+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: false, - metaKey: true, - keyCode: -1, - code: 'MetaLeft' - }, - { - label: '⌘', - ariaLabel: 'Command', - electronAccelerator: null, - userSettingsLabel: 'cmd', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['meta'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier MetaRight+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: false, - metaKey: true, - keyCode: -1, - code: 'MetaRight' - }, - { - label: '⌘', - ariaLabel: 'Command', - electronAccelerator: null, - userSettingsLabel: 'cmd', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['meta'], - } - ); - }); -}); - -suite('keyboardMapper - LINUX de_ch', () => { - - let mapper: MacLinuxKeyboardMapper; - - suiteSetup(async () => { - const _mapper = await createKeyboardMapper(false, 'linux_de_ch', OperatingSystem.Linux); - mapper = _mapper; - }); - - test('mapping', () => { - return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'linux_de_ch.txt'); - }); - - function assertKeybindingTranslation(kb: number, expected: string | string[]): void { - _assertKeybindingTranslation(mapper, OperatingSystem.Linux, kb, expected); - } - - function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void { - assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Linux)!, expected); - } - - test('kb => hw', () => { - // unchanged - assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.Digit1, 'ctrl+Digit1'); - assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.KeyB, 'ctrl+KeyB'); - assertKeybindingTranslation(KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyB, 'ctrl+shift+KeyB'); - assertKeybindingTranslation(KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyB, 'ctrl+shift+alt+meta+KeyB'); - - // flips Y and Z - assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.KeyZ, 'ctrl+KeyY'); - assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.KeyY, 'ctrl+KeyZ'); - - // Ctrl+/ - assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.Slash, 'ctrl+shift+Digit7'); - }); - - test('resolveKeybinding Ctrl+A', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.KeyA, - [{ - label: 'Ctrl+A', - ariaLabel: 'Control+A', - electronAccelerator: 'Ctrl+A', - userSettingsLabel: 'ctrl+a', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[KeyA]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+Z', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.KeyZ, - [{ - label: 'Ctrl+Z', - ariaLabel: 'Control+Z', - electronAccelerator: 'Ctrl+Z', - userSettingsLabel: 'ctrl+z', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[KeyY]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeyboardEvent Ctrl+[KeyY]', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'KeyY' - }, - { - label: 'Ctrl+Z', - ariaLabel: 'Control+Z', - electronAccelerator: 'Ctrl+Z', - userSettingsLabel: 'ctrl+z', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[KeyY]'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveKeybinding Ctrl+]', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.BracketRight, - [] - ); - }); - - test('resolveKeyboardEvent Ctrl+[BracketRight]', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'BracketRight' - }, - { - label: 'Ctrl+¨', - ariaLabel: 'Control+¨', - electronAccelerator: null, - userSettingsLabel: 'ctrl+[BracketRight]', - isWYSIWYG: false, - isChord: false, - dispatchParts: ['ctrl+[BracketRight]'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveKeybinding Shift+]', () => { - _assertResolveKeybinding( - KeyMod.Shift | KeyCode.BracketRight, - [{ - label: 'Ctrl+Alt+0', - ariaLabel: 'Control+Alt+0', - electronAccelerator: 'Ctrl+Alt+0', - userSettingsLabel: 'ctrl+alt+0', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+alt+[Digit0]'], - singleModifierDispatchParts: [null], - }, { - label: 'Ctrl+Alt+$', - ariaLabel: 'Control+Alt+$', - electronAccelerator: null, - userSettingsLabel: 'ctrl+alt+[Backslash]', - isWYSIWYG: false, - isChord: false, - dispatchParts: ['ctrl+alt+[Backslash]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+/', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.Slash, - [{ - label: 'Ctrl+Shift+7', - ariaLabel: 'Control+Shift+7', - electronAccelerator: 'Ctrl+Shift+7', - userSettingsLabel: 'ctrl+shift+7', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+shift+[Digit7]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+Shift+/', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Slash, - [{ - label: 'Ctrl+Shift+\'', - ariaLabel: 'Control+Shift+\'', - electronAccelerator: null, - userSettingsLabel: 'ctrl+shift+[Minus]', - isWYSIWYG: false, - isChord: false, - dispatchParts: ['ctrl+shift+[Minus]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+K Ctrl+\\', () => { - _assertResolveKeybinding( - KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Backslash), - [] - ); - }); - - test('resolveKeybinding Ctrl+K Ctrl+=', () => { - _assertResolveKeybinding( - KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Equal), - [{ - label: 'Ctrl+K Ctrl+Shift+0', - ariaLabel: 'Control+K Control+Shift+0', - electronAccelerator: null, - userSettingsLabel: 'ctrl+k ctrl+shift+0', - isWYSIWYG: true, - isChord: true, - dispatchParts: ['ctrl+[KeyK]', 'ctrl+shift+[Digit0]'], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveKeybinding Ctrl+DownArrow', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.DownArrow, - [{ - label: 'Ctrl+DownArrow', - ariaLabel: 'Control+DownArrow', - electronAccelerator: 'Ctrl+Down', - userSettingsLabel: 'ctrl+down', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[ArrowDown]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+NUMPAD_0', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.Numpad0, - [{ - label: 'Ctrl+NumPad0', - ariaLabel: 'Control+NumPad0', - electronAccelerator: null, - userSettingsLabel: 'ctrl+numpad0', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[Numpad0]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+Home', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.Home, - [{ - label: 'Ctrl+Home', - ariaLabel: 'Control+Home', - electronAccelerator: 'Ctrl+Home', - userSettingsLabel: 'ctrl+home', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[Home]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeyboardEvent Ctrl+[Home]', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'Home' - }, - { - label: 'Ctrl+Home', - ariaLabel: 'Control+Home', - electronAccelerator: 'Ctrl+Home', - userSettingsLabel: 'ctrl+home', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[Home]'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveKeyboardEvent Ctrl+[KeyX]', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'KeyX' - }, - { - label: 'Ctrl+X', - ariaLabel: 'Control+X', - electronAccelerator: 'Ctrl+X', - userSettingsLabel: 'ctrl+x', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[KeyX]'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveUserBinding Ctrl+[Comma] Ctrl+/', () => { - assertResolveUserBinding( - mapper, [ - new ScanCodeBinding(true, false, false, false, ScanCode.Comma), - new SimpleKeybinding(true, false, false, false, KeyCode.Slash), - ], - [{ - label: 'Ctrl+, Ctrl+Shift+7', - ariaLabel: 'Control+, Control+Shift+7', - electronAccelerator: null, - userSettingsLabel: 'ctrl+[Comma] ctrl+shift+7', - isWYSIWYG: false, - isChord: true, - dispatchParts: ['ctrl+[Comma]', 'ctrl+shift+[Digit7]'], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveKeyboardEvent Single Modifier ControlLeft+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'ControlLeft' - }, - { - label: 'Ctrl', - ariaLabel: 'Control', - electronAccelerator: null, - userSettingsLabel: 'ctrl', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['ctrl'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier ControlRight+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'ControlRight' - }, - { - label: 'Ctrl', - ariaLabel: 'Control', - electronAccelerator: null, - userSettingsLabel: 'ctrl', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['ctrl'], - } - ); - }); -}); - -suite('keyboardMapper - LINUX en_us', () => { - - let mapper: MacLinuxKeyboardMapper; - - suiteSetup(async () => { - const _mapper = await createKeyboardMapper(true, 'linux_en_us', OperatingSystem.Linux); - mapper = _mapper; - }); - - test('mapping', () => { - return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'linux_en_us.txt'); - }); - - function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void { - assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Linux)!, expected); - } - - test('resolveKeybinding Ctrl+A', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.KeyA, - [{ - label: 'Ctrl+A', - ariaLabel: 'Control+A', - electronAccelerator: 'Ctrl+A', - userSettingsLabel: 'ctrl+a', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[KeyA]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+Z', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.KeyZ, - [{ - label: 'Ctrl+Z', - ariaLabel: 'Control+Z', - electronAccelerator: 'Ctrl+Z', - userSettingsLabel: 'ctrl+z', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[KeyZ]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeyboardEvent Ctrl+[KeyZ]', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'KeyZ' - }, - { - label: 'Ctrl+Z', - ariaLabel: 'Control+Z', - electronAccelerator: 'Ctrl+Z', - userSettingsLabel: 'ctrl+z', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[KeyZ]'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveKeybinding Ctrl+]', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.BracketRight, - [{ - label: 'Ctrl+]', - ariaLabel: 'Control+]', - electronAccelerator: 'Ctrl+]', - userSettingsLabel: 'ctrl+]', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[BracketRight]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeyboardEvent Ctrl+[BracketRight]', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'BracketRight' - }, - { - label: 'Ctrl+]', - ariaLabel: 'Control+]', - electronAccelerator: 'Ctrl+]', - userSettingsLabel: 'ctrl+]', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[BracketRight]'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveKeybinding Shift+]', () => { - _assertResolveKeybinding( - KeyMod.Shift | KeyCode.BracketRight, - [{ - label: 'Shift+]', - ariaLabel: 'Shift+]', - electronAccelerator: 'Shift+]', - userSettingsLabel: 'shift+]', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['shift+[BracketRight]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+/', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.Slash, - [{ - label: 'Ctrl+/', - ariaLabel: 'Control+/', - electronAccelerator: 'Ctrl+/', - userSettingsLabel: 'ctrl+/', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[Slash]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+Shift+/', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Slash, - [{ - label: 'Ctrl+Shift+/', - ariaLabel: 'Control+Shift+/', - electronAccelerator: 'Ctrl+Shift+/', - userSettingsLabel: 'ctrl+shift+/', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+shift+[Slash]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+K Ctrl+\\', () => { - _assertResolveKeybinding( - KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Backslash), - [{ - label: 'Ctrl+K Ctrl+\\', - ariaLabel: 'Control+K Control+\\', - electronAccelerator: null, - userSettingsLabel: 'ctrl+k ctrl+\\', - isWYSIWYG: true, - isChord: true, - dispatchParts: ['ctrl+[KeyK]', 'ctrl+[Backslash]'], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveKeybinding Ctrl+K Ctrl+=', () => { - _assertResolveKeybinding( - KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Equal), - [{ - label: 'Ctrl+K Ctrl+=', - ariaLabel: 'Control+K Control+=', - electronAccelerator: null, - userSettingsLabel: 'ctrl+k ctrl+=', - isWYSIWYG: true, - isChord: true, - dispatchParts: ['ctrl+[KeyK]', 'ctrl+[Equal]'], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveKeybinding Ctrl+DownArrow', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.DownArrow, - [{ - label: 'Ctrl+DownArrow', - ariaLabel: 'Control+DownArrow', - electronAccelerator: 'Ctrl+Down', - userSettingsLabel: 'ctrl+down', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[ArrowDown]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+NUMPAD_0', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.Numpad0, - [{ - label: 'Ctrl+NumPad0', - ariaLabel: 'Control+NumPad0', - electronAccelerator: null, - userSettingsLabel: 'ctrl+numpad0', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[Numpad0]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+Home', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.Home, - [{ - label: 'Ctrl+Home', - ariaLabel: 'Control+Home', - electronAccelerator: 'Ctrl+Home', - userSettingsLabel: 'ctrl+home', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[Home]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeyboardEvent Ctrl+[Home]', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'Home' - }, - { - label: 'Ctrl+Home', - ariaLabel: 'Control+Home', - electronAccelerator: 'Ctrl+Home', - userSettingsLabel: 'ctrl+home', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[Home]'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveKeybinding Ctrl+Shift+,', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Comma, - [{ - label: 'Ctrl+Shift+,', - ariaLabel: 'Control+Shift+,', - electronAccelerator: 'Ctrl+Shift+,', - userSettingsLabel: 'ctrl+shift+,', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+shift+[Comma]'], - singleModifierDispatchParts: [null], - }, { - label: 'Ctrl+<', - ariaLabel: 'Control+<', - electronAccelerator: null, - userSettingsLabel: 'ctrl+[IntlBackslash]', - isWYSIWYG: false, - isChord: false, - dispatchParts: ['ctrl+[IntlBackslash]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('issue #23393: resolveKeybinding Ctrl+Enter', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.Enter, - [{ - label: 'Ctrl+Enter', - ariaLabel: 'Control+Enter', - electronAccelerator: 'Ctrl+Enter', - userSettingsLabel: 'ctrl+enter', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[Enter]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('issue #23393: resolveKeyboardEvent Ctrl+[NumpadEnter]', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'NumpadEnter' - }, - { - label: 'Ctrl+Enter', - ariaLabel: 'Control+Enter', - electronAccelerator: 'Ctrl+Enter', - userSettingsLabel: 'ctrl+enter', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[Enter]'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveUserBinding Ctrl+[Comma] Ctrl+/', () => { - assertResolveUserBinding( - mapper, [ - new ScanCodeBinding(true, false, false, false, ScanCode.Comma), - new SimpleKeybinding(true, false, false, false, KeyCode.Slash), - ], - [{ - label: 'Ctrl+, Ctrl+/', - ariaLabel: 'Control+, Control+/', - electronAccelerator: null, - userSettingsLabel: 'ctrl+, ctrl+/', - isWYSIWYG: true, - isChord: true, - dispatchParts: ['ctrl+[Comma]', 'ctrl+[Slash]'], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveUserBinding Ctrl+[Comma]', () => { - assertResolveUserBinding( - mapper, [ - new ScanCodeBinding(true, false, false, false, ScanCode.Comma) - ], - [{ - label: 'Ctrl+,', - ariaLabel: 'Control+,', - electronAccelerator: 'Ctrl+,', - userSettingsLabel: 'ctrl+,', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[Comma]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeyboardEvent Single Modifier ControlLeft+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'ControlLeft' - }, - { - label: 'Ctrl', - ariaLabel: 'Control', - electronAccelerator: null, - userSettingsLabel: 'ctrl', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['ctrl'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier ControlRight+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'ControlRight' - }, - { - label: 'Ctrl', - ariaLabel: 'Control', - electronAccelerator: null, - userSettingsLabel: 'ctrl', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['ctrl'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier ShiftLeft+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: true, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'ShiftLeft' - }, - { - label: 'Shift', - ariaLabel: 'Shift', - electronAccelerator: null, - userSettingsLabel: 'shift', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['shift'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier ShiftRight+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: true, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'ShiftRight' - }, - { - label: 'Shift', - ariaLabel: 'Shift', - electronAccelerator: null, - userSettingsLabel: 'shift', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['shift'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier AltLeft+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: true, - metaKey: false, - keyCode: -1, - code: 'AltLeft' - }, - { - label: 'Alt', - ariaLabel: 'Alt', - electronAccelerator: null, - userSettingsLabel: 'alt', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['alt'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier AltRight+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: true, - metaKey: false, - keyCode: -1, - code: 'AltRight' - }, - { - label: 'Alt', - ariaLabel: 'Alt', - electronAccelerator: null, - userSettingsLabel: 'alt', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['alt'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier MetaLeft+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: false, - metaKey: true, - keyCode: -1, - code: 'MetaLeft' - }, - { - label: 'Super', - ariaLabel: 'Super', - electronAccelerator: null, - userSettingsLabel: 'meta', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['meta'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier MetaRight+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: false, - metaKey: true, - keyCode: -1, - code: 'MetaRight' - }, - { - label: 'Super', - ariaLabel: 'Super', - electronAccelerator: null, - userSettingsLabel: 'meta', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['meta'], - } - ); - }); - - test('resolveKeyboardEvent Only Modifiers Ctrl+Shift+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: true, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'ShiftLeft' - }, - { - label: 'Ctrl+Shift', - ariaLabel: 'Control+Shift', - electronAccelerator: null, - userSettingsLabel: 'ctrl+shift', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: [null], - } - ); - }); -}); - -suite('keyboardMapper', () => { - - test('issue #23706: Linux UK layout: Ctrl + Apostrophe also toggles terminal', () => { - const mapper = new MacLinuxKeyboardMapper(false, { - 'Backquote': { - 'value': '`', - 'withShift': '¬', - 'withAltGr': '|', - 'withShiftAltGr': '|' - } - }, OperatingSystem.Linux); - - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: -1, - code: 'Backquote' - }, - { - label: 'Ctrl+`', - ariaLabel: 'Control+`', - electronAccelerator: null, - userSettingsLabel: 'ctrl+`', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[Backquote]'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('issue #24064: NumLock/NumPad keys stopped working in 1.11 on Linux', () => { - const mapper = new MacLinuxKeyboardMapper(false, {}, OperatingSystem.Linux); - - function assertNumpadKeyboardEvent(keyCode: KeyCode, code: string, label: string, electronAccelerator: string | null, userSettingsLabel: string, dispatch: string): void { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: keyCode, - code: code - }, - { - label: label, - ariaLabel: label, - electronAccelerator: electronAccelerator, - userSettingsLabel: userSettingsLabel, - isWYSIWYG: true, - isChord: false, - dispatchParts: [dispatch], - singleModifierDispatchParts: [null], - } - ); - } - - assertNumpadKeyboardEvent(KeyCode.End, 'Numpad1', 'End', 'End', 'end', '[End]'); - assertNumpadKeyboardEvent(KeyCode.DownArrow, 'Numpad2', 'DownArrow', 'Down', 'down', '[ArrowDown]'); - assertNumpadKeyboardEvent(KeyCode.PageDown, 'Numpad3', 'PageDown', 'PageDown', 'pagedown', '[PageDown]'); - assertNumpadKeyboardEvent(KeyCode.LeftArrow, 'Numpad4', 'LeftArrow', 'Left', 'left', '[ArrowLeft]'); - assertNumpadKeyboardEvent(KeyCode.Unknown, 'Numpad5', 'NumPad5', null!, 'numpad5', '[Numpad5]'); - assertNumpadKeyboardEvent(KeyCode.RightArrow, 'Numpad6', 'RightArrow', 'Right', 'right', '[ArrowRight]'); - assertNumpadKeyboardEvent(KeyCode.Home, 'Numpad7', 'Home', 'Home', 'home', '[Home]'); - assertNumpadKeyboardEvent(KeyCode.UpArrow, 'Numpad8', 'UpArrow', 'Up', 'up', '[ArrowUp]'); - assertNumpadKeyboardEvent(KeyCode.PageUp, 'Numpad9', 'PageUp', 'PageUp', 'pageup', '[PageUp]'); - assertNumpadKeyboardEvent(KeyCode.Insert, 'Numpad0', 'Insert', 'Insert', 'insert', '[Insert]'); - assertNumpadKeyboardEvent(KeyCode.Delete, 'NumpadDecimal', 'Delete', 'Delete', 'delete', '[Delete]'); - }); - - test('issue #24107: Delete, Insert, Home, End, PgUp, PgDn, and arrow keys no longer work editor in 1.11', () => { - const mapper = new MacLinuxKeyboardMapper(false, {}, OperatingSystem.Linux); - - function assertKeyboardEvent(keyCode: KeyCode, code: string, label: string, electronAccelerator: string, userSettingsLabel: string, dispatch: string): void { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: keyCode, - code: code - }, - { - label: label, - ariaLabel: label, - electronAccelerator: electronAccelerator, - userSettingsLabel: userSettingsLabel, - isWYSIWYG: true, - isChord: false, - dispatchParts: [dispatch], - singleModifierDispatchParts: [null], - } - ); - } - - // https://github.com/microsoft/vscode/issues/24107#issuecomment-292318497 - assertKeyboardEvent(KeyCode.UpArrow, 'Lang3', 'UpArrow', 'Up', 'up', '[ArrowUp]'); - assertKeyboardEvent(KeyCode.DownArrow, 'NumpadEnter', 'DownArrow', 'Down', 'down', '[ArrowDown]'); - assertKeyboardEvent(KeyCode.LeftArrow, 'Convert', 'LeftArrow', 'Left', 'left', '[ArrowLeft]'); - assertKeyboardEvent(KeyCode.RightArrow, 'NonConvert', 'RightArrow', 'Right', 'right', '[ArrowRight]'); - assertKeyboardEvent(KeyCode.Delete, 'PrintScreen', 'Delete', 'Delete', 'delete', '[Delete]'); - assertKeyboardEvent(KeyCode.Insert, 'NumpadDivide', 'Insert', 'Insert', 'insert', '[Insert]'); - assertKeyboardEvent(KeyCode.End, 'Unknown', 'End', 'End', 'end', '[End]'); - assertKeyboardEvent(KeyCode.Home, 'IntlRo', 'Home', 'Home', 'home', '[Home]'); - assertKeyboardEvent(KeyCode.PageDown, 'ControlRight', 'PageDown', 'PageDown', 'pagedown', '[PageDown]'); - assertKeyboardEvent(KeyCode.PageUp, 'Lang4', 'PageUp', 'PageUp', 'pageup', '[PageUp]'); - - // https://github.com/microsoft/vscode/issues/24107#issuecomment-292323924 - assertKeyboardEvent(KeyCode.PageDown, 'ControlRight', 'PageDown', 'PageDown', 'pagedown', '[PageDown]'); - assertKeyboardEvent(KeyCode.PageUp, 'Lang4', 'PageUp', 'PageUp', 'pageup', '[PageUp]'); - assertKeyboardEvent(KeyCode.End, '', 'End', 'End', 'end', '[End]'); - assertKeyboardEvent(KeyCode.Home, 'IntlRo', 'Home', 'Home', 'home', '[Home]'); - assertKeyboardEvent(KeyCode.Delete, 'PrintScreen', 'Delete', 'Delete', 'delete', '[Delete]'); - assertKeyboardEvent(KeyCode.Insert, 'NumpadDivide', 'Insert', 'Insert', 'insert', '[Insert]'); - assertKeyboardEvent(KeyCode.RightArrow, 'NonConvert', 'RightArrow', 'Right', 'right', '[ArrowRight]'); - assertKeyboardEvent(KeyCode.LeftArrow, 'Convert', 'LeftArrow', 'Left', 'left', '[ArrowLeft]'); - assertKeyboardEvent(KeyCode.DownArrow, 'NumpadEnter', 'DownArrow', 'Down', 'down', '[ArrowDown]'); - assertKeyboardEvent(KeyCode.UpArrow, 'Lang3', 'UpArrow', 'Up', 'up', '[ArrowUp]'); - }); -}); - -suite('keyboardMapper - LINUX ru', () => { - - let mapper: MacLinuxKeyboardMapper; - - suiteSetup(async () => { - const _mapper = await createKeyboardMapper(false, 'linux_ru', OperatingSystem.Linux); - mapper = _mapper; - }); - - test('mapping', () => { - return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'linux_ru.txt'); - }); - - function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void { - assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Linux)!, expected); - } - - test('resolveKeybinding Ctrl+S', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.KeyS, - [{ - label: 'Ctrl+S', - ariaLabel: 'Control+S', - electronAccelerator: 'Ctrl+S', - userSettingsLabel: 'ctrl+s', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+[KeyS]'], - singleModifierDispatchParts: [null], - }] - ); - }); -}); - -suite('keyboardMapper - LINUX en_uk', () => { - - let mapper: MacLinuxKeyboardMapper; - - suiteSetup(async () => { - const _mapper = await createKeyboardMapper(false, 'linux_en_uk', OperatingSystem.Linux); - mapper = _mapper; - }); - - test('mapping', () => { - return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'linux_en_uk.txt'); - }); - - test('issue #24522: resolveKeyboardEvent Ctrl+Alt+[Minus]', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: true, - metaKey: false, - keyCode: -1, - code: 'Minus' - }, - { - label: 'Ctrl+Alt+-', - ariaLabel: 'Control+Alt+-', - electronAccelerator: null, - userSettingsLabel: 'ctrl+alt+[Minus]', - isWYSIWYG: false, - isChord: false, - dispatchParts: ['ctrl+alt+[Minus]'], - singleModifierDispatchParts: [null], - } - ); - }); -}); - -suite('keyboardMapper - MAC zh_hant', () => { - - let mapper: MacLinuxKeyboardMapper; - - suiteSetup(async () => { - const _mapper = await createKeyboardMapper(false, 'mac_zh_hant', OperatingSystem.Macintosh); - mapper = _mapper; - }); - - test('mapping', () => { - return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'mac_zh_hant.txt'); - }); - - function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void { - assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Macintosh)!, expected); - } - - test('issue #28237 resolveKeybinding Cmd+C', () => { - _assertResolveKeybinding( - KeyMod.CtrlCmd | KeyCode.KeyC, - [{ - label: '⌘C', - ariaLabel: 'Command+C', - electronAccelerator: 'Cmd+C', - userSettingsLabel: 'cmd+c', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['meta+[KeyC]'], - singleModifierDispatchParts: [null], - }] - ); - }); -}); - -suite('keyboardMapper - MAC zh_hant2', () => { - - let mapper: MacLinuxKeyboardMapper; - - suiteSetup(async () => { - const _mapper = await createKeyboardMapper(false, 'mac_zh_hant2', OperatingSystem.Macintosh); - mapper = _mapper; - }); - - test('mapping', () => { - return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'mac_zh_hant2.txt'); - }); -}); - -function _assertKeybindingTranslation(mapper: MacLinuxKeyboardMapper, OS: OperatingSystem, kb: number, _expected: string | string[]): void { - let expected: string[]; - if (typeof _expected === 'string') { - expected = [_expected]; - } else if (Array.isArray(_expected)) { - expected = _expected; - } else { - expected = []; - } - - const runtimeKeybinding = createSimpleKeybinding(kb, OS); - - const keybindingLabel = new USLayoutResolvedKeybinding(runtimeKeybinding.toChord(), OS).getUserSettingsLabel(); - - const actualHardwareKeypresses = mapper.simpleKeybindingToScanCodeBinding(runtimeKeybinding); - if (actualHardwareKeypresses.length === 0) { - assert.deepStrictEqual([], expected, `simpleKeybindingToHardwareKeypress -- "${keybindingLabel}" -- actual: "[]" -- expected: "${expected}"`); - return; - } - - const actual = actualHardwareKeypresses - .map(k => UserSettingsLabelProvider.toLabel(OS, [k], (keybinding) => ScanCodeUtils.toString(keybinding.scanCode))); - assert.deepStrictEqual(actual, expected, `simpleKeybindingToHardwareKeypress -- "${keybindingLabel}" -- actual: "${actual}" -- expected: "${expected}"`); -} diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/mac_de_ch.js b/src/vs/workbench/services/keybinding/test/electron-browser/mac_de_ch.js deleted file mode 100644 index 6da177d6785..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/mac_de_ch.js +++ /dev/null @@ -1,1188 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -define({ - KeyA: { - value: 'a', - valueIsDeadKey: false, - withShift: 'A', - withShiftIsDeadKey: false, - withAltGr: 'å', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Å', - withShiftAltGrIsDeadKey: false - }, - KeyB: { - value: 'b', - valueIsDeadKey: false, - withShift: 'B', - withShiftIsDeadKey: false, - withAltGr: '∫', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - KeyC: { - value: 'c', - valueIsDeadKey: false, - withShift: 'C', - withShiftIsDeadKey: false, - withAltGr: '©', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - KeyD: { - value: 'd', - valueIsDeadKey: false, - withShift: 'D', - withShiftIsDeadKey: false, - withAltGr: '∂', - withAltGrIsDeadKey: false, - withShiftAltGr: 'fl', - withShiftAltGrIsDeadKey: false - }, - KeyE: { - value: 'e', - valueIsDeadKey: false, - withShift: 'E', - withShiftIsDeadKey: false, - withAltGr: '€', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ë', - withShiftAltGrIsDeadKey: false - }, - KeyF: { - value: 'f', - valueIsDeadKey: false, - withShift: 'F', - withShiftIsDeadKey: false, - withAltGr: 'ƒ', - withAltGrIsDeadKey: false, - withShiftAltGr: '‡', - withShiftAltGrIsDeadKey: false - }, - KeyG: { - value: 'g', - valueIsDeadKey: false, - withShift: 'G', - withShiftIsDeadKey: false, - withAltGr: '@', - withAltGrIsDeadKey: false, - withShiftAltGr: '‚', - withShiftAltGrIsDeadKey: false - }, - KeyH: { - value: 'h', - valueIsDeadKey: false, - withShift: 'H', - withShiftIsDeadKey: false, - withAltGr: 'ª', - withAltGrIsDeadKey: false, - withShiftAltGr: '·', - withShiftAltGrIsDeadKey: false - }, - KeyI: { - value: 'i', - valueIsDeadKey: false, - withShift: 'I', - withShiftIsDeadKey: false, - withAltGr: '¡', - withAltGrIsDeadKey: false, - withShiftAltGr: 'ı', - withShiftAltGrIsDeadKey: false - }, - KeyJ: { - value: 'j', - valueIsDeadKey: false, - withShift: 'J', - withShiftIsDeadKey: false, - withAltGr: 'º', - withAltGrIsDeadKey: false, - withShiftAltGr: '˜', - withShiftAltGrIsDeadKey: false - }, - KeyK: { - value: 'k', - valueIsDeadKey: false, - withShift: 'K', - withShiftIsDeadKey: false, - withAltGr: '∆', - withAltGrIsDeadKey: false, - withShiftAltGr: '¯', - withShiftAltGrIsDeadKey: false - }, - KeyL: { - value: 'l', - valueIsDeadKey: false, - withShift: 'L', - withShiftIsDeadKey: false, - withAltGr: '¬', - withAltGrIsDeadKey: false, - withShiftAltGr: 'ˆ', - withShiftAltGrIsDeadKey: false - }, - KeyM: { - value: 'm', - valueIsDeadKey: false, - withShift: 'M', - withShiftIsDeadKey: false, - withAltGr: 'µ', - withAltGrIsDeadKey: false, - withShiftAltGr: '˚', - withShiftAltGrIsDeadKey: false - }, - KeyN: { - value: 'n', - valueIsDeadKey: false, - withShift: 'N', - withShiftIsDeadKey: false, - withAltGr: '~', - withAltGrIsDeadKey: true, - withShiftAltGr: '˙', - withShiftAltGrIsDeadKey: false - }, - KeyO: { - value: 'o', - valueIsDeadKey: false, - withShift: 'O', - withShiftIsDeadKey: false, - withAltGr: 'ø', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ø', - withShiftAltGrIsDeadKey: false - }, - KeyP: { - value: 'p', - valueIsDeadKey: false, - withShift: 'P', - withShiftIsDeadKey: false, - withAltGr: 'π', - withAltGrIsDeadKey: false, - withShiftAltGr: '∏', - withShiftAltGrIsDeadKey: false - }, - KeyQ: { - value: 'q', - valueIsDeadKey: false, - withShift: 'Q', - withShiftIsDeadKey: false, - withAltGr: 'œ', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Œ', - withShiftAltGrIsDeadKey: false - }, - KeyR: { - value: 'r', - valueIsDeadKey: false, - withShift: 'R', - withShiftIsDeadKey: false, - withAltGr: '®', - withAltGrIsDeadKey: false, - withShiftAltGr: 'È', - withShiftAltGrIsDeadKey: false - }, - KeyS: { - value: 's', - valueIsDeadKey: false, - withShift: 'S', - withShiftIsDeadKey: false, - withAltGr: 'ß', - withAltGrIsDeadKey: false, - withShiftAltGr: 'fi', - withShiftAltGrIsDeadKey: false - }, - KeyT: { - value: 't', - valueIsDeadKey: false, - withShift: 'T', - withShiftIsDeadKey: false, - withAltGr: '†', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Î', - withShiftAltGrIsDeadKey: false - }, - KeyU: { - value: 'u', - valueIsDeadKey: false, - withShift: 'U', - withShiftIsDeadKey: false, - withAltGr: '°', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ù', - withShiftAltGrIsDeadKey: false - }, - KeyV: { - value: 'v', - valueIsDeadKey: false, - withShift: 'V', - withShiftIsDeadKey: false, - withAltGr: '√', - withAltGrIsDeadKey: false, - withShiftAltGr: '◊', - withShiftAltGrIsDeadKey: false - }, - KeyW: { - value: 'w', - valueIsDeadKey: false, - withShift: 'W', - withShiftIsDeadKey: false, - withAltGr: '∑', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Á', - withShiftAltGrIsDeadKey: false - }, - KeyX: { - value: 'x', - valueIsDeadKey: false, - withShift: 'X', - withShiftIsDeadKey: false, - withAltGr: '≈', - withAltGrIsDeadKey: false, - withShiftAltGr: '™', - withShiftAltGrIsDeadKey: false - }, - KeyY: { - value: 'z', - valueIsDeadKey: false, - withShift: 'Z', - withShiftIsDeadKey: false, - withAltGr: 'Ω', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Í', - withShiftAltGrIsDeadKey: false - }, - KeyZ: { - value: 'y', - valueIsDeadKey: false, - withShift: 'Y', - withShiftIsDeadKey: false, - withAltGr: '¥', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ÿ', - withShiftAltGrIsDeadKey: false - }, - Digit1: { - value: '1', - valueIsDeadKey: false, - withShift: '+', - withShiftIsDeadKey: false, - withAltGr: '±', - withAltGrIsDeadKey: false, - withShiftAltGr: '∞', - withShiftAltGrIsDeadKey: false - }, - Digit2: { - value: '2', - valueIsDeadKey: false, - withShift: '"', - withShiftIsDeadKey: false, - withAltGr: '“', - withAltGrIsDeadKey: false, - withShiftAltGr: '”', - withShiftAltGrIsDeadKey: false - }, - Digit3: { - value: '3', - valueIsDeadKey: false, - withShift: '*', - withShiftIsDeadKey: false, - withAltGr: '#', - withAltGrIsDeadKey: false, - withShiftAltGr: '‹', - withShiftAltGrIsDeadKey: false - }, - Digit4: { - value: '4', - valueIsDeadKey: false, - withShift: 'ç', - withShiftIsDeadKey: false, - withAltGr: 'Ç', - withAltGrIsDeadKey: false, - withShiftAltGr: '⁄', - withShiftAltGrIsDeadKey: false - }, - Digit5: { - value: '5', - valueIsDeadKey: false, - withShift: '%', - withShiftIsDeadKey: false, - withAltGr: '[', - withAltGrIsDeadKey: false, - withShiftAltGr: '[', - withShiftAltGrIsDeadKey: false - }, - Digit6: { - value: '6', - valueIsDeadKey: false, - withShift: '&', - withShiftIsDeadKey: false, - withAltGr: ']', - withAltGrIsDeadKey: false, - withShiftAltGr: ']', - withShiftAltGrIsDeadKey: false - }, - Digit7: { - value: '7', - valueIsDeadKey: false, - withShift: '/', - withShiftIsDeadKey: false, - withAltGr: '|', - withAltGrIsDeadKey: false, - withShiftAltGr: '\\', - withShiftAltGrIsDeadKey: false - }, - Digit8: { - value: '8', - valueIsDeadKey: false, - withShift: '(', - withShiftIsDeadKey: false, - withAltGr: '{', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ò', - withShiftAltGrIsDeadKey: false - }, - Digit9: { - value: '9', - valueIsDeadKey: false, - withShift: ')', - withShiftIsDeadKey: false, - withAltGr: '}', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ô', - withShiftAltGrIsDeadKey: false - }, - Digit0: { - value: '0', - valueIsDeadKey: false, - withShift: '=', - withShiftIsDeadKey: false, - withAltGr: '≠', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ú', - withShiftAltGrIsDeadKey: false - }, - Enter: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Escape: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Backspace: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Tab: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Space: { - value: ' ', - valueIsDeadKey: false, - withShift: ' ', - withShiftIsDeadKey: false, - withAltGr: ' ', - withAltGrIsDeadKey: false, - withShiftAltGr: ' ', - withShiftAltGrIsDeadKey: false - }, - Minus: { - value: '\'', - valueIsDeadKey: false, - withShift: '?', - withShiftIsDeadKey: false, - withAltGr: '¿', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Equal: { - value: '^', - valueIsDeadKey: true, - withShift: '`', - withShiftIsDeadKey: true, - withAltGr: '´', - withAltGrIsDeadKey: true, - withShiftAltGr: '^', - withShiftAltGrIsDeadKey: false - }, - BracketLeft: { - value: 'ü', - valueIsDeadKey: false, - withShift: 'è', - withShiftIsDeadKey: false, - withAltGr: '§', - withAltGrIsDeadKey: false, - withShiftAltGr: 'ÿ', - withShiftAltGrIsDeadKey: false - }, - BracketRight: { - value: '¨', - valueIsDeadKey: true, - withShift: '!', - withShiftIsDeadKey: false, - withAltGr: '‘', - withAltGrIsDeadKey: false, - withShiftAltGr: '’', - withShiftAltGrIsDeadKey: false - }, - Backslash: { - value: '$', - valueIsDeadKey: false, - withShift: '£', - withShiftIsDeadKey: false, - withAltGr: '¶', - withAltGrIsDeadKey: false, - withShiftAltGr: '•', - withShiftAltGrIsDeadKey: false - }, - Semicolon: { - value: 'ö', - valueIsDeadKey: false, - withShift: 'é', - withShiftIsDeadKey: false, - withAltGr: '¢', - withAltGrIsDeadKey: false, - withShiftAltGr: '˘', - withShiftAltGrIsDeadKey: false - }, - Quote: { - value: 'ä', - valueIsDeadKey: false, - withShift: 'à', - withShiftIsDeadKey: false, - withAltGr: 'æ', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Æ', - withShiftAltGrIsDeadKey: false - }, - Backquote: { - value: '<', - valueIsDeadKey: false, - withShift: '>', - withShiftIsDeadKey: false, - withAltGr: '≤', - withAltGrIsDeadKey: false, - withShiftAltGr: '≥', - withShiftAltGrIsDeadKey: false - }, - Comma: { - value: ',', - valueIsDeadKey: false, - withShift: ';', - withShiftIsDeadKey: false, - withAltGr: '«', - withAltGrIsDeadKey: false, - withShiftAltGr: '»', - withShiftAltGrIsDeadKey: false - }, - Period: { - value: '.', - valueIsDeadKey: false, - withShift: ':', - withShiftIsDeadKey: false, - withAltGr: '…', - withAltGrIsDeadKey: false, - withShiftAltGr: '÷', - withShiftAltGrIsDeadKey: false - }, - Slash: { - value: '-', - valueIsDeadKey: false, - withShift: '_', - withShiftIsDeadKey: false, - withAltGr: '–', - withAltGrIsDeadKey: false, - withShiftAltGr: '—', - withShiftAltGrIsDeadKey: false - }, - CapsLock: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F1: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F2: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F3: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F4: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F5: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F6: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F7: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F8: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F9: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F10: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F11: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F12: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Insert: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Home: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - PageUp: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Delete: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - End: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - PageDown: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowDown: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowUp: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumLock: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumpadDivide: { - value: '/', - valueIsDeadKey: false, - withShift: '/', - withShiftIsDeadKey: false, - withAltGr: '/', - withAltGrIsDeadKey: false, - withShiftAltGr: '/', - withShiftAltGrIsDeadKey: false - }, - NumpadMultiply: { - value: '*', - valueIsDeadKey: false, - withShift: '*', - withShiftIsDeadKey: false, - withAltGr: '*', - withAltGrIsDeadKey: false, - withShiftAltGr: '*', - withShiftAltGrIsDeadKey: false - }, - NumpadSubtract: { - value: '-', - valueIsDeadKey: false, - withShift: '-', - withShiftIsDeadKey: false, - withAltGr: '-', - withAltGrIsDeadKey: false, - withShiftAltGr: '-', - withShiftAltGrIsDeadKey: false - }, - NumpadAdd: { - value: '+', - valueIsDeadKey: false, - withShift: '+', - withShiftIsDeadKey: false, - withAltGr: '+', - withAltGrIsDeadKey: false, - withShiftAltGr: '+', - withShiftAltGrIsDeadKey: false - }, - NumpadEnter: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Numpad1: { - value: '1', - valueIsDeadKey: false, - withShift: '1', - withShiftIsDeadKey: false, - withAltGr: '1', - withAltGrIsDeadKey: false, - withShiftAltGr: '1', - withShiftAltGrIsDeadKey: false - }, - Numpad2: { - value: '2', - valueIsDeadKey: false, - withShift: '2', - withShiftIsDeadKey: false, - withAltGr: '2', - withAltGrIsDeadKey: false, - withShiftAltGr: '2', - withShiftAltGrIsDeadKey: false - }, - Numpad3: { - value: '3', - valueIsDeadKey: false, - withShift: '3', - withShiftIsDeadKey: false, - withAltGr: '3', - withAltGrIsDeadKey: false, - withShiftAltGr: '3', - withShiftAltGrIsDeadKey: false - }, - Numpad4: { - value: '4', - valueIsDeadKey: false, - withShift: '4', - withShiftIsDeadKey: false, - withAltGr: '4', - withAltGrIsDeadKey: false, - withShiftAltGr: '4', - withShiftAltGrIsDeadKey: false - }, - Numpad5: { - value: '5', - valueIsDeadKey: false, - withShift: '5', - withShiftIsDeadKey: false, - withAltGr: '5', - withAltGrIsDeadKey: false, - withShiftAltGr: '5', - withShiftAltGrIsDeadKey: false - }, - Numpad6: { - value: '6', - valueIsDeadKey: false, - withShift: '6', - withShiftIsDeadKey: false, - withAltGr: '6', - withAltGrIsDeadKey: false, - withShiftAltGr: '6', - withShiftAltGrIsDeadKey: false - }, - Numpad7: { - value: '7', - valueIsDeadKey: false, - withShift: '7', - withShiftIsDeadKey: false, - withAltGr: '7', - withAltGrIsDeadKey: false, - withShiftAltGr: '7', - withShiftAltGrIsDeadKey: false - }, - Numpad8: { - value: '8', - valueIsDeadKey: false, - withShift: '8', - withShiftIsDeadKey: false, - withAltGr: '8', - withAltGrIsDeadKey: false, - withShiftAltGr: '8', - withShiftAltGrIsDeadKey: false - }, - Numpad9: { - value: '9', - valueIsDeadKey: false, - withShift: '9', - withShiftIsDeadKey: false, - withAltGr: '9', - withAltGrIsDeadKey: false, - withShiftAltGr: '9', - withShiftAltGrIsDeadKey: false - }, - Numpad0: { - value: '0', - valueIsDeadKey: false, - withShift: '0', - withShiftIsDeadKey: false, - withAltGr: '0', - withAltGrIsDeadKey: false, - withShiftAltGr: '0', - withShiftAltGrIsDeadKey: false - }, - NumpadDecimal: { - value: '.', - valueIsDeadKey: false, - withShift: ',', - withShiftIsDeadKey: false, - withAltGr: '.', - withAltGrIsDeadKey: false, - withShiftAltGr: '.', - withShiftAltGrIsDeadKey: false - }, - IntlBackslash: { - value: '§', - valueIsDeadKey: false, - withShift: '°', - withShiftIsDeadKey: false, - withAltGr: 'fi', - withAltGrIsDeadKey: false, - withShiftAltGr: '‰', - withShiftAltGrIsDeadKey: false - }, - ContextMenu: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumpadEqual: { - value: '=', - valueIsDeadKey: false, - withShift: '=', - withShiftIsDeadKey: false, - withAltGr: '=', - withAltGrIsDeadKey: false, - withShiftAltGr: '=', - withShiftAltGrIsDeadKey: false - }, - F13: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F14: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F15: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F16: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F17: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F18: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F19: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F20: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AudioVolumeMute: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AudioVolumeUp: { - value: '', - valueIsDeadKey: false, - withShift: '=', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '=', - withShiftAltGrIsDeadKey: false - }, - AudioVolumeDown: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumpadComma: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - IntlRo: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - KanaMode: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - IntlYen: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ControlLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ShiftLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AltLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - MetaLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ControlRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ShiftRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AltRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - MetaRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - } -}); diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/mac_de_ch.txt b/src/vs/workbench/services/keybinding/test/electron-browser/mac_de_ch.txt deleted file mode 100644 index 60627a704dc..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/mac_de_ch.txt +++ /dev/null @@ -1,529 +0,0 @@ -isUSStandard: false ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyA | a | A | | A | a | A | [KeyA] | | -| Ctrl+KeyA | a | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | -| Shift+KeyA | A | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | -| Ctrl+Shift+KeyA | A | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | -| Alt+KeyA | a | Alt+A | | Option+A | alt+a | Alt+A | alt+[KeyA] | | -| Ctrl+Alt+KeyA | å | Ctrl+Alt+A | | Ctrl+Option+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | -| Shift+Alt+KeyA | A | Shift+Alt+A | | Shift+Option+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | -| Ctrl+Shift+Alt+KeyA | Å | Ctrl+Shift+Alt+A | | Ctrl+Shift+Option+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyB | b | B | | B | b | B | [KeyB] | | -| Ctrl+KeyB | b | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | -| Shift+KeyB | B | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | -| Ctrl+Shift+KeyB | B | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | -| Alt+KeyB | b | Alt+B | | Option+B | alt+b | Alt+B | alt+[KeyB] | | -| Ctrl+Alt+KeyB | ∫ | Ctrl+Alt+B | | Ctrl+Option+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | -| Shift+Alt+KeyB | B | Shift+Alt+B | | Shift+Option+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | -| Ctrl+Shift+Alt+KeyB | --- | Ctrl+Shift+Alt+B | | Ctrl+Shift+Option+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyC | c | C | | C | c | C | [KeyC] | | -| Ctrl+KeyC | c | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | -| Shift+KeyC | C | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | -| Ctrl+Shift+KeyC | C | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | -| Alt+KeyC | c | Alt+C | | Option+C | alt+c | Alt+C | alt+[KeyC] | | -| Ctrl+Alt+KeyC | © | Ctrl+Alt+C | | Ctrl+Option+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | -| Shift+Alt+KeyC | C | Shift+Alt+C | | Shift+Option+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | -| Ctrl+Shift+Alt+KeyC | --- | Ctrl+Shift+Alt+C | | Ctrl+Shift+Option+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyD | d | D | | D | d | D | [KeyD] | | -| Ctrl+KeyD | d | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | -| Shift+KeyD | D | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | -| Ctrl+Shift+KeyD | D | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | -| Alt+KeyD | d | Alt+D | | Option+D | alt+d | Alt+D | alt+[KeyD] | | -| Ctrl+Alt+KeyD | ∂ | Ctrl+Alt+D | | Ctrl+Option+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | -| Shift+Alt+KeyD | D | Shift+Alt+D | | Shift+Option+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | -| Ctrl+Shift+Alt+KeyD | fl | Ctrl+Shift+Alt+D | | Ctrl+Shift+Option+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyE | e | E | | E | e | E | [KeyE] | | -| Ctrl+KeyE | e | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | -| Shift+KeyE | E | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | -| Ctrl+Shift+KeyE | E | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | -| Alt+KeyE | e | Alt+E | | Option+E | alt+e | Alt+E | alt+[KeyE] | | -| Ctrl+Alt+KeyE | € | Ctrl+Alt+E | | Ctrl+Option+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | -| Shift+Alt+KeyE | E | Shift+Alt+E | | Shift+Option+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | -| Ctrl+Shift+Alt+KeyE | Ë | Ctrl+Shift+Alt+E | | Ctrl+Shift+Option+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyF | f | F | | F | f | F | [KeyF] | | -| Ctrl+KeyF | f | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | -| Shift+KeyF | F | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | -| Ctrl+Shift+KeyF | F | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | -| Alt+KeyF | f | Alt+F | | Option+F | alt+f | Alt+F | alt+[KeyF] | | -| Ctrl+Alt+KeyF | ƒ | Ctrl+Alt+F | | Ctrl+Option+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | -| Shift+Alt+KeyF | F | Shift+Alt+F | | Shift+Option+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | -| Ctrl+Shift+Alt+KeyF | ‡ | Ctrl+Shift+Alt+F | | Ctrl+Shift+Option+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyG | g | G | | G | g | G | [KeyG] | | -| Ctrl+KeyG | g | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | -| Shift+KeyG | G | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | -| Ctrl+Shift+KeyG | G | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | -| Alt+KeyG | g | Alt+G | | Option+G | alt+g | Alt+G | alt+[KeyG] | | -| Ctrl+Alt+KeyG | @ | Ctrl+Alt+G | | Ctrl+Option+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | -| Shift+Alt+KeyG | G | Shift+Alt+G | | Shift+Option+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | -| Ctrl+Shift+Alt+KeyG | ‚ | Ctrl+Shift+Alt+G | | Ctrl+Shift+Option+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyH | h | H | | H | h | H | [KeyH] | | -| Ctrl+KeyH | h | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | -| Shift+KeyH | H | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | -| Ctrl+Shift+KeyH | H | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | -| Alt+KeyH | h | Alt+H | | Option+H | alt+h | Alt+H | alt+[KeyH] | | -| Ctrl+Alt+KeyH | ª | Ctrl+Alt+H | | Ctrl+Option+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | -| Shift+Alt+KeyH | H | Shift+Alt+H | | Shift+Option+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | -| Ctrl+Shift+Alt+KeyH | · | Ctrl+Shift+Alt+H | | Ctrl+Shift+Option+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyI | i | I | | I | i | I | [KeyI] | | -| Ctrl+KeyI | i | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | -| Shift+KeyI | I | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | -| Ctrl+Shift+KeyI | I | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | -| Alt+KeyI | i | Alt+I | | Option+I | alt+i | Alt+I | alt+[KeyI] | | -| Ctrl+Alt+KeyI | ¡ | Ctrl+Alt+I | | Ctrl+Option+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | -| Shift+Alt+KeyI | I | Shift+Alt+I | | Shift+Option+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | -| Ctrl+Shift+Alt+KeyI | ı | Ctrl+Shift+Alt+I | | Ctrl+Shift+Option+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyJ | j | J | | J | j | J | [KeyJ] | | -| Ctrl+KeyJ | j | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | -| Shift+KeyJ | J | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | -| Ctrl+Shift+KeyJ | J | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | -| Alt+KeyJ | j | Alt+J | | Option+J | alt+j | Alt+J | alt+[KeyJ] | | -| Ctrl+Alt+KeyJ | º | Ctrl+Alt+J | | Ctrl+Option+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | -| Shift+Alt+KeyJ | J | Shift+Alt+J | | Shift+Option+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | -| Ctrl+Shift+Alt+KeyJ | ˜ | Ctrl+Shift+Alt+J | | Ctrl+Shift+Option+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyK | k | K | | K | k | K | [KeyK] | | -| Ctrl+KeyK | k | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | -| Shift+KeyK | K | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | -| Ctrl+Shift+KeyK | K | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | -| Alt+KeyK | k | Alt+K | | Option+K | alt+k | Alt+K | alt+[KeyK] | | -| Ctrl+Alt+KeyK | ∆ | Ctrl+Alt+K | | Ctrl+Option+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | -| Shift+Alt+KeyK | K | Shift+Alt+K | | Shift+Option+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | -| Ctrl+Shift+Alt+KeyK | ¯ | Ctrl+Shift+Alt+K | | Ctrl+Shift+Option+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyL | l | L | | L | l | L | [KeyL] | | -| Ctrl+KeyL | l | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | -| Shift+KeyL | L | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | -| Ctrl+Shift+KeyL | L | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | -| Alt+KeyL | l | Alt+L | | Option+L | alt+l | Alt+L | alt+[KeyL] | | -| Ctrl+Alt+KeyL | ¬ | Ctrl+Alt+L | | Ctrl+Option+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | -| Shift+Alt+KeyL | L | Shift+Alt+L | | Shift+Option+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | -| Ctrl+Shift+Alt+KeyL | ˆ | Ctrl+Shift+Alt+L | | Ctrl+Shift+Option+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyM | m | M | | M | m | M | [KeyM] | | -| Ctrl+KeyM | m | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | -| Shift+KeyM | M | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | -| Ctrl+Shift+KeyM | M | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | -| Alt+KeyM | m | Alt+M | | Option+M | alt+m | Alt+M | alt+[KeyM] | | -| Ctrl+Alt+KeyM | µ | Ctrl+Alt+M | | Ctrl+Option+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | -| Shift+Alt+KeyM | M | Shift+Alt+M | | Shift+Option+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | -| Ctrl+Shift+Alt+KeyM | ˚ | Ctrl+Shift+Alt+M | | Ctrl+Shift+Option+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyN | n | N | | N | n | N | [KeyN] | | -| Ctrl+KeyN | n | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | -| Shift+KeyN | N | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | -| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | -| Alt+KeyN | n | Alt+N | | Option+N | alt+n | Alt+N | alt+[KeyN] | | -| Ctrl+Alt+KeyN | ~ | Ctrl+Alt+N | | Ctrl+Option+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | -| | | Shift+` | | | | | | | -| Shift+Alt+KeyN | N | Shift+Alt+N | | Shift+Option+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | -| Ctrl+Shift+Alt+KeyN | ˙ | Ctrl+Shift+Alt+N | | Ctrl+Shift+Option+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyO | o | O | | O | o | O | [KeyO] | | -| Ctrl+KeyO | o | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | -| Shift+KeyO | O | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | -| Ctrl+Shift+KeyO | O | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | -| Alt+KeyO | o | Alt+O | | Option+O | alt+o | Alt+O | alt+[KeyO] | | -| Ctrl+Alt+KeyO | ø | Ctrl+Alt+O | | Ctrl+Option+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | -| Shift+Alt+KeyO | O | Shift+Alt+O | | Shift+Option+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | -| Ctrl+Shift+Alt+KeyO | Ø | Ctrl+Shift+Alt+O | | Ctrl+Shift+Option+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyP | p | P | | P | p | P | [KeyP] | | -| Ctrl+KeyP | p | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | -| Shift+KeyP | P | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | -| Ctrl+Shift+KeyP | P | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | -| Alt+KeyP | p | Alt+P | | Option+P | alt+p | Alt+P | alt+[KeyP] | | -| Ctrl+Alt+KeyP | π | Ctrl+Alt+P | | Ctrl+Option+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | -| Shift+Alt+KeyP | P | Shift+Alt+P | | Shift+Option+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | -| Ctrl+Shift+Alt+KeyP | ∏ | Ctrl+Shift+Alt+P | | Ctrl+Shift+Option+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyQ | q | Q | | Q | q | Q | [KeyQ] | | -| Ctrl+KeyQ | q | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | -| Shift+KeyQ | Q | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | -| Ctrl+Shift+KeyQ | Q | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | -| Alt+KeyQ | q | Alt+Q | | Option+Q | alt+q | Alt+Q | alt+[KeyQ] | | -| Ctrl+Alt+KeyQ | œ | Ctrl+Alt+Q | | Ctrl+Option+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | -| Shift+Alt+KeyQ | Q | Shift+Alt+Q | | Shift+Option+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | -| Ctrl+Shift+Alt+KeyQ | Œ | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Option+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyR | r | R | | R | r | R | [KeyR] | | -| Ctrl+KeyR | r | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | -| Shift+KeyR | R | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | -| Ctrl+Shift+KeyR | R | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | -| Alt+KeyR | r | Alt+R | | Option+R | alt+r | Alt+R | alt+[KeyR] | | -| Ctrl+Alt+KeyR | ® | Ctrl+Alt+R | | Ctrl+Option+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | -| Shift+Alt+KeyR | R | Shift+Alt+R | | Shift+Option+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | -| Ctrl+Shift+Alt+KeyR | È | Ctrl+Shift+Alt+R | | Ctrl+Shift+Option+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyS | s | S | | S | s | S | [KeyS] | | -| Ctrl+KeyS | s | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | -| Shift+KeyS | S | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | -| Ctrl+Shift+KeyS | S | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | -| Alt+KeyS | s | Alt+S | | Option+S | alt+s | Alt+S | alt+[KeyS] | | -| Ctrl+Alt+KeyS | ß | Ctrl+Alt+S | | Ctrl+Option+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | -| Shift+Alt+KeyS | S | Shift+Alt+S | | Shift+Option+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | -| Ctrl+Shift+Alt+KeyS | fi | Ctrl+Shift+Alt+S | | Ctrl+Shift+Option+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyT | t | T | | T | t | T | [KeyT] | | -| Ctrl+KeyT | t | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | -| Shift+KeyT | T | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | -| Ctrl+Shift+KeyT | T | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | -| Alt+KeyT | t | Alt+T | | Option+T | alt+t | Alt+T | alt+[KeyT] | | -| Ctrl+Alt+KeyT | † | Ctrl+Alt+T | | Ctrl+Option+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | -| Shift+Alt+KeyT | T | Shift+Alt+T | | Shift+Option+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | -| Ctrl+Shift+Alt+KeyT | Î | Ctrl+Shift+Alt+T | | Ctrl+Shift+Option+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyU | u | U | | U | u | U | [KeyU] | | -| Ctrl+KeyU | u | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | -| Shift+KeyU | U | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | -| Ctrl+Shift+KeyU | U | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | -| Alt+KeyU | u | Alt+U | | Option+U | alt+u | Alt+U | alt+[KeyU] | | -| Ctrl+Alt+KeyU | ° | Ctrl+Alt+U | | Ctrl+Option+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | -| Shift+Alt+KeyU | U | Shift+Alt+U | | Shift+Option+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | -| Ctrl+Shift+Alt+KeyU | Ù | Ctrl+Shift+Alt+U | | Ctrl+Shift+Option+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyV | v | V | | V | v | V | [KeyV] | | -| Ctrl+KeyV | v | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | -| Shift+KeyV | V | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | -| Ctrl+Shift+KeyV | V | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | -| Alt+KeyV | v | Alt+V | | Option+V | alt+v | Alt+V | alt+[KeyV] | | -| Ctrl+Alt+KeyV | √ | Ctrl+Alt+V | | Ctrl+Option+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | -| Shift+Alt+KeyV | V | Shift+Alt+V | | Shift+Option+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | -| Ctrl+Shift+Alt+KeyV | ◊ | Ctrl+Shift+Alt+V | | Ctrl+Shift+Option+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyW | w | W | | W | w | W | [KeyW] | | -| Ctrl+KeyW | w | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | -| Shift+KeyW | W | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | -| Ctrl+Shift+KeyW | W | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | -| Alt+KeyW | w | Alt+W | | Option+W | alt+w | Alt+W | alt+[KeyW] | | -| Ctrl+Alt+KeyW | ∑ | Ctrl+Alt+W | | Ctrl+Option+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | -| Shift+Alt+KeyW | W | Shift+Alt+W | | Shift+Option+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | -| Ctrl+Shift+Alt+KeyW | Á | Ctrl+Shift+Alt+W | | Ctrl+Shift+Option+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyX | x | X | | X | x | X | [KeyX] | | -| Ctrl+KeyX | x | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | -| Shift+KeyX | X | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | -| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | -| Alt+KeyX | x | Alt+X | | Option+X | alt+x | Alt+X | alt+[KeyX] | | -| Ctrl+Alt+KeyX | ≈ | Ctrl+Alt+X | | Ctrl+Option+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | -| Shift+Alt+KeyX | X | Shift+Alt+X | | Shift+Option+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | -| Ctrl+Shift+Alt+KeyX | ™ | Ctrl+Shift+Alt+X | | Ctrl+Shift+Option+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyY | z | Z | | Z | z | Z | [KeyY] | | -| Ctrl+KeyY | z | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyY] | | -| Shift+KeyY | Z | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyY] | | -| Ctrl+Shift+KeyY | Z | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyY] | | -| Alt+KeyY | z | Alt+Z | | Option+Z | alt+z | Alt+Z | alt+[KeyY] | | -| Ctrl+Alt+KeyY | Ω | Ctrl+Alt+Z | | Ctrl+Option+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyY] | | -| Shift+Alt+KeyY | Z | Shift+Alt+Z | | Shift+Option+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyY] | | -| Ctrl+Shift+Alt+KeyY | Í | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Option+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyY] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyZ | y | Y | | Y | y | Y | [KeyZ] | | -| Ctrl+KeyZ | y | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyZ] | | -| Shift+KeyZ | Y | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyZ] | | -| Ctrl+Shift+KeyZ | Y | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyZ] | | -| Alt+KeyZ | y | Alt+Y | | Option+Y | alt+y | Alt+Y | alt+[KeyZ] | | -| Ctrl+Alt+KeyZ | ¥ | Ctrl+Alt+Y | | Ctrl+Option+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyZ] | | -| Shift+Alt+KeyZ | Y | Shift+Alt+Y | | Shift+Option+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyZ] | | -| Ctrl+Shift+Alt+KeyZ | Ÿ | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Option+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyZ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit1 | 1 | 1 | | 1 | 1 | 1 | [Digit1] | | -| Ctrl+Digit1 | 1 | Ctrl+1 | | Ctrl+1 | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | | -| Shift+Digit1 | + | Shift+1 | | Shift+1 | shift+1 | Shift+1 | shift+[Digit1] | | -| | | Shift+= | | | | | | | -| Ctrl+Shift+Digit1 | + | Ctrl+Shift+1 | | Ctrl+Shift+1 | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | | -| | | Ctrl+Shift+= | | | | | | | -| Alt+Digit1 | 1 | Alt+1 | | Option+1 | alt+1 | Alt+1 | alt+[Digit1] | | -| Ctrl+Alt+Digit1 | ± | Ctrl+Alt+1 | | Ctrl+Option+1 | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | | -| Shift+Alt+Digit1 | + | Shift+Alt+1 | | Shift+Option+1 | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | | -| | | Shift+Alt+= | | | | | | | -| Ctrl+Shift+Alt+Digit1 | ∞ | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Option+1 | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | | -| | | Ctrl+Shift+Alt+= | | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit2 | 2 | 2 | | 2 | 2 | 2 | [Digit2] | | -| Ctrl+Digit2 | 2 | Ctrl+2 | | Ctrl+2 | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | | -| Shift+Digit2 | " | Shift+2 | | Shift+2 | shift+2 | Shift+2 | shift+[Digit2] | | -| | | Shift+' | | | | | | | -| Ctrl+Shift+Digit2 | " | Ctrl+Shift+2 | | Ctrl+Shift+2 | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | | -| | | Ctrl+Shift+' | | | | | | | -| Alt+Digit2 | 2 | Alt+2 | | Option+2 | alt+2 | Alt+2 | alt+[Digit2] | | -| Ctrl+Alt+Digit2 | “ | Ctrl+Alt+2 | | Ctrl+Option+2 | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | | -| Shift+Alt+Digit2 | " | Shift+Alt+2 | | Shift+Option+2 | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | | -| | | Shift+Alt+' | | | | | | | -| Ctrl+Shift+Alt+Digit2 | ” | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Option+2 | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | | -| | | Ctrl+Shift+Alt+' | | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit3 | 3 | 3 | | 3 | 3 | 3 | [Digit3] | | -| Ctrl+Digit3 | 3 | Ctrl+3 | | Ctrl+3 | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | | -| Shift+Digit3 | * | Shift+3 | | Shift+3 | shift+3 | Shift+3 | shift+[Digit3] | | -| Ctrl+Shift+Digit3 | * | Ctrl+Shift+3 | | Ctrl+Shift+3 | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | | -| Alt+Digit3 | 3 | Alt+3 | | Option+3 | alt+3 | Alt+3 | alt+[Digit3] | | -| Ctrl+Alt+Digit3 | # | Ctrl+Alt+3 | | Ctrl+Option+3 | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | | -| Shift+Alt+Digit3 | * | Shift+Alt+3 | | Shift+Option+3 | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | | -| Ctrl+Shift+Alt+Digit3 | ‹ | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Option+3 | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit4 | 4 | 4 | | 4 | 4 | 4 | [Digit4] | | -| Ctrl+Digit4 | 4 | Ctrl+4 | | Ctrl+4 | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | | -| Shift+Digit4 | ç | Shift+4 | | Shift+4 | shift+4 | Shift+4 | shift+[Digit4] | | -| Ctrl+Shift+Digit4 | ç | Ctrl+Shift+4 | | Ctrl+Shift+4 | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | | -| Alt+Digit4 | 4 | Alt+4 | | Option+4 | alt+4 | Alt+4 | alt+[Digit4] | | -| Ctrl+Alt+Digit4 | Ç | Ctrl+Alt+4 | | Ctrl+Option+4 | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | | -| Shift+Alt+Digit4 | ç | Shift+Alt+4 | | Shift+Option+4 | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | | -| Ctrl+Shift+Alt+Digit4 | ⁄ | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Option+4 | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit5 | 5 | 5 | | 5 | 5 | 5 | [Digit5] | | -| Ctrl+Digit5 | 5 | Ctrl+5 | | Ctrl+5 | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | | -| Shift+Digit5 | % | Shift+5 | | Shift+5 | shift+5 | Shift+5 | shift+[Digit5] | | -| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+5 | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | | -| Alt+Digit5 | 5 | Alt+5 | | Option+5 | alt+5 | Alt+5 | alt+[Digit5] | | -| Ctrl+Alt+Digit5 | [ | Ctrl+Alt+5 | | Ctrl+Option+5 | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | | -| | | [ | | | | | | | -| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Option+5 | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | | -| Ctrl+Shift+Alt+Digit5 | [ | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Option+5 | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit6 | 6 | 6 | | 6 | 6 | 6 | [Digit6] | | -| Ctrl+Digit6 | 6 | Ctrl+6 | | Ctrl+6 | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | | -| Shift+Digit6 | & | Shift+6 | | Shift+6 | shift+6 | Shift+6 | shift+[Digit6] | | -| Ctrl+Shift+Digit6 | & | Ctrl+Shift+6 | | Ctrl+Shift+6 | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | | -| Alt+Digit6 | 6 | Alt+6 | | Option+6 | alt+6 | Alt+6 | alt+[Digit6] | | -| Ctrl+Alt+Digit6 | ] | Ctrl+Alt+6 | | Ctrl+Option+6 | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | | -| | | ] | | | | | | | -| Shift+Alt+Digit6 | & | Shift+Alt+6 | | Shift+Option+6 | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | | -| Ctrl+Shift+Alt+Digit6 | ] | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Option+6 | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit7 | 7 | 7 | | 7 | 7 | 7 | [Digit7] | | -| Ctrl+Digit7 | 7 | Ctrl+7 | | Ctrl+7 | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | | -| Shift+Digit7 | / | Shift+7 | | Shift+7 | shift+7 | Shift+7 | shift+[Digit7] | | -| | | / | | | | | | | -| Ctrl+Shift+Digit7 | / | Ctrl+Shift+7 | | Ctrl+Shift+7 | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | | -| | | Ctrl+/ | | | | | | | -| Alt+Digit7 | 7 | Alt+7 | | Option+7 | alt+7 | Alt+7 | alt+[Digit7] | | -| Ctrl+Alt+Digit7 | | | Ctrl+Alt+7 | | Ctrl+Option+7 | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | | -| | | Shift+\ | | | | | | | -| Shift+Alt+Digit7 | / | Shift+Alt+7 | | Shift+Option+7 | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | | -| | | Alt+/ | | | | | | | -| Ctrl+Shift+Alt+Digit7 | \ | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Option+7 | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | | -| | | \ | | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit8 | 8 | 8 | | 8 | 8 | 8 | [Digit8] | | -| Ctrl+Digit8 | 8 | Ctrl+8 | | Ctrl+8 | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | | -| Shift+Digit8 | ( | Shift+8 | | Shift+8 | shift+8 | Shift+8 | shift+[Digit8] | | -| Ctrl+Shift+Digit8 | ( | Ctrl+Shift+8 | | Ctrl+Shift+8 | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | | -| Alt+Digit8 | 8 | Alt+8 | | Option+8 | alt+8 | Alt+8 | alt+[Digit8] | | -| Ctrl+Alt+Digit8 | { | Ctrl+Alt+8 | | Ctrl+Option+8 | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | | -| | | Shift+[ | | | | | | | -| Shift+Alt+Digit8 | ( | Shift+Alt+8 | | Shift+Option+8 | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | | -| Ctrl+Shift+Alt+Digit8 | Ò | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Option+8 | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit9 | 9 | 9 | | 9 | 9 | 9 | [Digit9] | | -| Ctrl+Digit9 | 9 | Ctrl+9 | | Ctrl+9 | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | | -| Shift+Digit9 | ) | Shift+9 | | Shift+9 | shift+9 | Shift+9 | shift+[Digit9] | | -| Ctrl+Shift+Digit9 | ) | Ctrl+Shift+9 | | Ctrl+Shift+9 | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | | -| Alt+Digit9 | 9 | Alt+9 | | Option+9 | alt+9 | Alt+9 | alt+[Digit9] | | -| Ctrl+Alt+Digit9 | } | Ctrl+Alt+9 | | Ctrl+Option+9 | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | | -| | | Shift+] | | | | | | | -| Shift+Alt+Digit9 | ) | Shift+Alt+9 | | Shift+Option+9 | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | | -| Ctrl+Shift+Alt+Digit9 | Ô | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Option+9 | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit0 | 0 | 0 | | 0 | 0 | 0 | [Digit0] | | -| Ctrl+Digit0 | 0 | Ctrl+0 | | Ctrl+0 | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | | -| Shift+Digit0 | = | Shift+0 | | Shift+0 | shift+0 | Shift+0 | shift+[Digit0] | | -| | | = | | | | | | | -| Ctrl+Shift+Digit0 | = | Ctrl+Shift+0 | | Ctrl+Shift+0 | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | | -| | | Ctrl+= | | | | | | | -| Alt+Digit0 | 0 | Alt+0 | | Option+0 | alt+0 | Alt+0 | alt+[Digit0] | | -| Ctrl+Alt+Digit0 | ≠ | Ctrl+Alt+0 | | Ctrl+Option+0 | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | | -| Shift+Alt+Digit0 | = | Shift+Alt+0 | | Shift+Option+0 | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | | -| | | Alt+= | | | | | | | -| Ctrl+Shift+Alt+Digit0 | Ú | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Option+0 | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | | -| | | Ctrl+Alt+= | | | | | | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Minus | ' | ' | | ' | [Minus] | null | [Minus] | NO | -| Ctrl+Minus | ' | Ctrl+' | | Ctrl+' | ctrl+[Minus] | null | ctrl+[Minus] | NO | -| Shift+Minus | ? | Shift+/ | | Shift+' | shift+[Minus] | null | shift+[Minus] | NO | -| Ctrl+Shift+Minus | ? | Ctrl+Shift+/ | | Ctrl+Shift+' | ctrl+shift+[Minus] | null | ctrl+shift+[Minus] | NO | -| Alt+Minus | ' | Alt+' | | Option+' | alt+[Minus] | null | alt+[Minus] | NO | -| Ctrl+Alt+Minus | ¿ | Ctrl+Alt+' | | Ctrl+Option+' | ctrl+alt+[Minus] | null | ctrl+alt+[Minus] | NO | -| Shift+Alt+Minus | ? | Shift+Alt+/ | | Shift+Option+' | shift+alt+[Minus] | null | shift+alt+[Minus] | NO | -| Ctrl+Shift+Alt+Minus |  | Ctrl+Shift+Alt+/ | | Ctrl+Shift+Option+' | ctrl+shift+alt+[Minus] | null | ctrl+shift+alt+[Minus] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Equal | ^ | | | ^ | [Equal] | null | [Equal] | NO | -| Ctrl+Equal | ^ | | | Ctrl+^ | ctrl+[Equal] | null | ctrl+[Equal] | NO | -| Shift+Equal | ` | ` | | Shift+^ | shift+[Equal] | null | shift+[Equal] | NO | -| Ctrl+Shift+Equal | ` | Ctrl+` | | Ctrl+Shift+^ | ctrl+shift+[Equal] | null | ctrl+shift+[Equal] | NO | -| Alt+Equal | ^ | | | Option+^ | alt+[Equal] | null | alt+[Equal] | NO | -| Ctrl+Alt+Equal | ´ | | | Ctrl+Option+^ | ctrl+alt+[Equal] | null | ctrl+alt+[Equal] | NO | -| Shift+Alt+Equal | ` | Alt+` | | Shift+Option+^ | shift+alt+[Equal] | null | shift+alt+[Equal] | NO | -| Ctrl+Shift+Alt+Equal | ^ | Ctrl+Alt+` | | Ctrl+Shift+Option+^ | ctrl+shift+alt+[Equal] | null | ctrl+shift+alt+[Equal] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketLeft | ü | | | ü | [BracketLeft] | null | [BracketLeft] | NO | -| Ctrl+BracketLeft | ü | | | Ctrl+ü | ctrl+[BracketLeft] | null | ctrl+[BracketLeft] | NO | -| Shift+BracketLeft | è | | | Shift+ü | shift+[BracketLeft] | null | shift+[BracketLeft] | NO | -| Ctrl+Shift+BracketLeft | è | | | Ctrl+Shift+ü | ctrl+shift+[BracketLeft] | null | ctrl+shift+[BracketLeft] | NO | -| Alt+BracketLeft | ü | | | Option+ü | alt+[BracketLeft] | null | alt+[BracketLeft] | NO | -| Ctrl+Alt+BracketLeft | § | | | Ctrl+Option+ü | ctrl+alt+[BracketLeft] | null | ctrl+alt+[BracketLeft] | NO | -| Shift+Alt+BracketLeft | è | | | Shift+Option+ü | shift+alt+[BracketLeft] | null | shift+alt+[BracketLeft] | NO | -| Ctrl+Shift+Alt+BracketLeft | ÿ | | | Ctrl+Shift+Option+ü | ctrl+shift+alt+[BracketLeft] | null | ctrl+shift+alt+[BracketLeft] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketRight | ¨ | | | ¨ | [BracketRight] | null | [BracketRight] | NO | -| Ctrl+BracketRight | ¨ | | | Ctrl+¨ | ctrl+[BracketRight] | null | ctrl+[BracketRight] | NO | -| Shift+BracketRight | ! | | | Shift+¨ | shift+[BracketRight] | null | shift+[BracketRight] | NO | -| Ctrl+Shift+BracketRight | ! | | | Ctrl+Shift+¨ | ctrl+shift+[BracketRight] | null | ctrl+shift+[BracketRight] | NO | -| Alt+BracketRight | ¨ | | | Option+¨ | alt+[BracketRight] | null | alt+[BracketRight] | NO | -| Ctrl+Alt+BracketRight | ‘ | | | Ctrl+Option+¨ | ctrl+alt+[BracketRight] | null | ctrl+alt+[BracketRight] | NO | -| Shift+Alt+BracketRight | ! | | | Shift+Option+¨ | shift+alt+[BracketRight] | null | shift+alt+[BracketRight] | NO | -| Ctrl+Shift+Alt+BracketRight | ’ | | | Ctrl+Shift+Option+¨ | ctrl+shift+alt+[BracketRight] | null | ctrl+shift+alt+[BracketRight] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backslash | $ | | | $ | [Backslash] | null | [Backslash] | NO | -| Ctrl+Backslash | $ | | | Ctrl+$ | ctrl+[Backslash] | null | ctrl+[Backslash] | NO | -| Shift+Backslash | £ | | | Shift+$ | shift+[Backslash] | null | shift+[Backslash] | NO | -| Ctrl+Shift+Backslash | £ | | | Ctrl+Shift+$ | ctrl+shift+[Backslash] | null | ctrl+shift+[Backslash] | NO | -| Alt+Backslash | $ | | | Option+$ | alt+[Backslash] | null | alt+[Backslash] | NO | -| Ctrl+Alt+Backslash | ¶ | | | Ctrl+Option+$ | ctrl+alt+[Backslash] | null | ctrl+alt+[Backslash] | NO | -| Shift+Alt+Backslash | £ | | | Shift+Option+$ | shift+alt+[Backslash] | null | shift+alt+[Backslash] | NO | -| Ctrl+Shift+Alt+Backslash | • | | | Ctrl+Shift+Option+$ | ctrl+shift+alt+[Backslash] | null | ctrl+shift+alt+[Backslash] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlHash | --- | | | null | null | null | null | | -| Ctrl+IntlHash | --- | | | null | null | null | null | | -| Shift+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | -| Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | -| Shift+Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Semicolon | ö | | | ö | [Semicolon] | null | [Semicolon] | NO | -| Ctrl+Semicolon | ö | | | Ctrl+ö | ctrl+[Semicolon] | null | ctrl+[Semicolon] | NO | -| Shift+Semicolon | é | | | Shift+ö | shift+[Semicolon] | null | shift+[Semicolon] | NO | -| Ctrl+Shift+Semicolon | é | | | Ctrl+Shift+ö | ctrl+shift+[Semicolon] | null | ctrl+shift+[Semicolon] | NO | -| Alt+Semicolon | ö | | | Option+ö | alt+[Semicolon] | null | alt+[Semicolon] | NO | -| Ctrl+Alt+Semicolon | ¢ | | | Ctrl+Option+ö | ctrl+alt+[Semicolon] | null | ctrl+alt+[Semicolon] | NO | -| Shift+Alt+Semicolon | é | | | Shift+Option+ö | shift+alt+[Semicolon] | null | shift+alt+[Semicolon] | NO | -| Ctrl+Shift+Alt+Semicolon | ˘ | | | Ctrl+Shift+Option+ö | ctrl+shift+alt+[Semicolon] | null | ctrl+shift+alt+[Semicolon] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Quote | ä | | | ä | [Quote] | null | [Quote] | NO | -| Ctrl+Quote | ä | | | Ctrl+ä | ctrl+[Quote] | null | ctrl+[Quote] | NO | -| Shift+Quote | à | | | Shift+ä | shift+[Quote] | null | shift+[Quote] | NO | -| Ctrl+Shift+Quote | à | | | Ctrl+Shift+ä | ctrl+shift+[Quote] | null | ctrl+shift+[Quote] | NO | -| Alt+Quote | ä | | | Option+ä | alt+[Quote] | null | alt+[Quote] | NO | -| Ctrl+Alt+Quote | æ | | | Ctrl+Option+ä | ctrl+alt+[Quote] | null | ctrl+alt+[Quote] | NO | -| Shift+Alt+Quote | à | | | Shift+Option+ä | shift+alt+[Quote] | null | shift+alt+[Quote] | NO | -| Ctrl+Shift+Alt+Quote | Æ | | | Ctrl+Shift+Option+ä | ctrl+shift+alt+[Quote] | null | ctrl+shift+alt+[Quote] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backquote | < | Shift+, | | < | [Backquote] | null | [Backquote] | NO | -| Ctrl+Backquote | < | Ctrl+Shift+, | | Ctrl+< | ctrl+[Backquote] | null | ctrl+[Backquote] | NO | -| Shift+Backquote | > | Shift+. | | Shift+< | shift+[Backquote] | null | shift+[Backquote] | NO | -| Ctrl+Shift+Backquote | > | Ctrl+Shift+. | | Ctrl+Shift+< | ctrl+shift+[Backquote] | null | ctrl+shift+[Backquote] | NO | -| Alt+Backquote | < | Shift+Alt+, | | Option+< | alt+[Backquote] | null | alt+[Backquote] | NO | -| Ctrl+Alt+Backquote | ≤ | Ctrl+Shift+Alt+, | | Ctrl+Option+< | ctrl+alt+[Backquote] | null | ctrl+alt+[Backquote] | NO | -| Shift+Alt+Backquote | > | Shift+Alt+. | | Shift+Option+< | shift+alt+[Backquote] | null | shift+alt+[Backquote] | NO | -| Ctrl+Shift+Alt+Backquote | ≥ | Ctrl+Shift+Alt+. | | Ctrl+Shift+Option+< | ctrl+shift+alt+[Backquote] | null | ctrl+shift+alt+[Backquote] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Comma | , | , | | , | [Comma] | null | [Comma] | NO | -| Ctrl+Comma | , | Ctrl+, | | Ctrl+, | ctrl+[Comma] | null | ctrl+[Comma] | NO | -| Shift+Comma | ; | ; | | Shift+, | shift+[Comma] | null | shift+[Comma] | NO | -| Ctrl+Shift+Comma | ; | Ctrl+; | | Ctrl+Shift+, | ctrl+shift+[Comma] | null | ctrl+shift+[Comma] | NO | -| Alt+Comma | , | Alt+, | | Option+, | alt+[Comma] | null | alt+[Comma] | NO | -| Ctrl+Alt+Comma | « | Ctrl+Alt+, | | Ctrl+Option+, | ctrl+alt+[Comma] | null | ctrl+alt+[Comma] | NO | -| Shift+Alt+Comma | ; | Alt+; | | Shift+Option+, | shift+alt+[Comma] | null | shift+alt+[Comma] | NO | -| Ctrl+Shift+Alt+Comma | » | Ctrl+Alt+; | | Ctrl+Shift+Option+, | ctrl+shift+alt+[Comma] | null | ctrl+shift+alt+[Comma] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Period | . | . | | . | [Period] | null | [Period] | NO | -| Ctrl+Period | . | Ctrl+. | | Ctrl+. | ctrl+[Period] | null | ctrl+[Period] | NO | -| Shift+Period | : | Shift+; | | Shift+. | shift+[Period] | null | shift+[Period] | NO | -| Ctrl+Shift+Period | : | Ctrl+Shift+; | | Ctrl+Shift+. | ctrl+shift+[Period] | null | ctrl+shift+[Period] | NO | -| Alt+Period | . | Alt+. | | Option+. | alt+[Period] | null | alt+[Period] | NO | -| Ctrl+Alt+Period | … | Ctrl+Alt+. | | Ctrl+Option+. | ctrl+alt+[Period] | null | ctrl+alt+[Period] | NO | -| Shift+Alt+Period | : | Shift+Alt+; | | Shift+Option+. | shift+alt+[Period] | null | shift+alt+[Period] | NO | -| Ctrl+Shift+Alt+Period | ÷ | Ctrl+Shift+Alt+; | | Ctrl+Shift+Option+. | ctrl+shift+alt+[Period] | null | ctrl+shift+alt+[Period] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Slash | - | - | | - | - | - | [Slash] | | -| Ctrl+Slash | - | Ctrl+- | | Ctrl+- | ctrl+- | Ctrl+- | ctrl+[Slash] | | -| Shift+Slash | _ | Shift+- | | Shift+- | shift+- | Shift+- | shift+[Slash] | | -| Ctrl+Shift+Slash | _ | Ctrl+Shift+- | | Ctrl+Shift+- | ctrl+shift+- | Ctrl+Shift+- | ctrl+shift+[Slash] | | -| Alt+Slash | - | Alt+- | | Option+- | alt+- | Alt+- | alt+[Slash] | | -| Ctrl+Alt+Slash | – | Ctrl+Alt+- | | Ctrl+Option+- | ctrl+alt+- | Ctrl+Alt+- | ctrl+alt+[Slash] | | -| Shift+Alt+Slash | _ | Shift+Alt+- | | Shift+Option+- | shift+alt+- | Shift+Alt+- | shift+alt+[Slash] | | -| Ctrl+Shift+Alt+Slash | — | Ctrl+Shift+Alt+- | | Ctrl+Shift+Option+- | ctrl+shift+alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+[Slash] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | -| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | -| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | -| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | -| Alt+ArrowUp | --- | Alt+UpArrow | | Option+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | -| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Option+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | -| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Option+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | -| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Option+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | -| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | -| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | -| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | -| Alt+Numpad0 | --- | Alt+NumPad0 | | Option+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | -| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Option+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | -| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Option+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | -| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Option+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlBackslash | § | | | § | [IntlBackslash] | null | [IntlBackslash] | NO | -| Ctrl+IntlBackslash | § | | | Ctrl+§ | ctrl+[IntlBackslash] | null | ctrl+[IntlBackslash] | NO | -| Shift+IntlBackslash | ° | | | Shift+§ | shift+[IntlBackslash] | null | shift+[IntlBackslash] | NO | -| Ctrl+Shift+IntlBackslash | ° | | | Ctrl+Shift+§ | ctrl+shift+[IntlBackslash] | null | ctrl+shift+[IntlBackslash] | NO | -| Alt+IntlBackslash | § | | | Option+§ | alt+[IntlBackslash] | null | alt+[IntlBackslash] | NO | -| Ctrl+Alt+IntlBackslash | fi | | | Ctrl+Option+§ | ctrl+alt+[IntlBackslash] | null | ctrl+alt+[IntlBackslash] | NO | -| Shift+Alt+IntlBackslash | ° | | | Shift+Option+§ | shift+alt+[IntlBackslash] | null | shift+alt+[IntlBackslash] | NO | -| Ctrl+Shift+Alt+IntlBackslash | ‰ | | | Ctrl+Shift+Option+§ | ctrl+shift+alt+[IntlBackslash] | null | ctrl+shift+alt+[IntlBackslash] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | -| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | -| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | -| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | -| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | -| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | -| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | -| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | -| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | -| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | -| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | -| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | -| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | -| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | -| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/mac_en_us.js b/src/vs/workbench/services/keybinding/test/electron-browser/mac_en_us.js deleted file mode 100644 index 1b62128a42d..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/mac_en_us.js +++ /dev/null @@ -1,1188 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -define({ - KeyA: { - value: 'a', - valueIsDeadKey: false, - withShift: 'A', - withShiftIsDeadKey: false, - withAltGr: 'å', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Å', - withShiftAltGrIsDeadKey: false - }, - KeyB: { - value: 'b', - valueIsDeadKey: false, - withShift: 'B', - withShiftIsDeadKey: false, - withAltGr: '∫', - withAltGrIsDeadKey: false, - withShiftAltGr: 'ı', - withShiftAltGrIsDeadKey: false - }, - KeyC: { - value: 'c', - valueIsDeadKey: false, - withShift: 'C', - withShiftIsDeadKey: false, - withAltGr: 'ç', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ç', - withShiftAltGrIsDeadKey: false - }, - KeyD: { - value: 'd', - valueIsDeadKey: false, - withShift: 'D', - withShiftIsDeadKey: false, - withAltGr: '∂', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Î', - withShiftAltGrIsDeadKey: false - }, - KeyE: { - value: 'e', - valueIsDeadKey: false, - withShift: 'E', - withShiftIsDeadKey: false, - withAltGr: '´', - withAltGrIsDeadKey: true, - withShiftAltGr: '´', - withShiftAltGrIsDeadKey: false - }, - KeyF: { - value: 'f', - valueIsDeadKey: false, - withShift: 'F', - withShiftIsDeadKey: false, - withAltGr: 'ƒ', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ï', - withShiftAltGrIsDeadKey: false - }, - KeyG: { - value: 'g', - valueIsDeadKey: false, - withShift: 'G', - withShiftIsDeadKey: false, - withAltGr: '©', - withAltGrIsDeadKey: false, - withShiftAltGr: '˝', - withShiftAltGrIsDeadKey: false - }, - KeyH: { - value: 'h', - valueIsDeadKey: false, - withShift: 'H', - withShiftIsDeadKey: false, - withAltGr: '˙', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ó', - withShiftAltGrIsDeadKey: false - }, - KeyI: { - value: 'i', - valueIsDeadKey: false, - withShift: 'I', - withShiftIsDeadKey: false, - withAltGr: 'ˆ', - withAltGrIsDeadKey: true, - withShiftAltGr: 'ˆ', - withShiftAltGrIsDeadKey: false - }, - KeyJ: { - value: 'j', - valueIsDeadKey: false, - withShift: 'J', - withShiftIsDeadKey: false, - withAltGr: '∆', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ô', - withShiftAltGrIsDeadKey: false - }, - KeyK: { - value: 'k', - valueIsDeadKey: false, - withShift: 'K', - withShiftIsDeadKey: false, - withAltGr: '˚', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - KeyL: { - value: 'l', - valueIsDeadKey: false, - withShift: 'L', - withShiftIsDeadKey: false, - withAltGr: '¬', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ò', - withShiftAltGrIsDeadKey: false - }, - KeyM: { - value: 'm', - valueIsDeadKey: false, - withShift: 'M', - withShiftIsDeadKey: false, - withAltGr: 'µ', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Â', - withShiftAltGrIsDeadKey: false - }, - KeyN: { - value: 'n', - valueIsDeadKey: false, - withShift: 'N', - withShiftIsDeadKey: false, - withAltGr: '˜', - withAltGrIsDeadKey: true, - withShiftAltGr: '˜', - withShiftAltGrIsDeadKey: false - }, - KeyO: { - value: 'o', - valueIsDeadKey: false, - withShift: 'O', - withShiftIsDeadKey: false, - withAltGr: 'ø', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ø', - withShiftAltGrIsDeadKey: false - }, - KeyP: { - value: 'p', - valueIsDeadKey: false, - withShift: 'P', - withShiftIsDeadKey: false, - withAltGr: 'π', - withAltGrIsDeadKey: false, - withShiftAltGr: '∏', - withShiftAltGrIsDeadKey: false - }, - KeyQ: { - value: 'q', - valueIsDeadKey: false, - withShift: 'Q', - withShiftIsDeadKey: false, - withAltGr: 'œ', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Œ', - withShiftAltGrIsDeadKey: false - }, - KeyR: { - value: 'r', - valueIsDeadKey: false, - withShift: 'R', - withShiftIsDeadKey: false, - withAltGr: '®', - withAltGrIsDeadKey: false, - withShiftAltGr: '‰', - withShiftAltGrIsDeadKey: false - }, - KeyS: { - value: 's', - valueIsDeadKey: false, - withShift: 'S', - withShiftIsDeadKey: false, - withAltGr: 'ß', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Í', - withShiftAltGrIsDeadKey: false - }, - KeyT: { - value: 't', - valueIsDeadKey: false, - withShift: 'T', - withShiftIsDeadKey: false, - withAltGr: '†', - withAltGrIsDeadKey: false, - withShiftAltGr: 'ˇ', - withShiftAltGrIsDeadKey: false - }, - KeyU: { - value: 'u', - valueIsDeadKey: false, - withShift: 'U', - withShiftIsDeadKey: false, - withAltGr: '¨', - withAltGrIsDeadKey: true, - withShiftAltGr: '¨', - withShiftAltGrIsDeadKey: false - }, - KeyV: { - value: 'v', - valueIsDeadKey: false, - withShift: 'V', - withShiftIsDeadKey: false, - withAltGr: '√', - withAltGrIsDeadKey: false, - withShiftAltGr: '◊', - withShiftAltGrIsDeadKey: false - }, - KeyW: { - value: 'w', - valueIsDeadKey: false, - withShift: 'W', - withShiftIsDeadKey: false, - withAltGr: '∑', - withAltGrIsDeadKey: false, - withShiftAltGr: '„', - withShiftAltGrIsDeadKey: false - }, - KeyX: { - value: 'x', - valueIsDeadKey: false, - withShift: 'X', - withShiftIsDeadKey: false, - withAltGr: '≈', - withAltGrIsDeadKey: false, - withShiftAltGr: '˛', - withShiftAltGrIsDeadKey: false - }, - KeyY: { - value: 'y', - valueIsDeadKey: false, - withShift: 'Y', - withShiftIsDeadKey: false, - withAltGr: '¥', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Á', - withShiftAltGrIsDeadKey: false - }, - KeyZ: { - value: 'z', - valueIsDeadKey: false, - withShift: 'Z', - withShiftIsDeadKey: false, - withAltGr: 'Ω', - withAltGrIsDeadKey: false, - withShiftAltGr: '¸', - withShiftAltGrIsDeadKey: false - }, - Digit1: { - value: '1', - valueIsDeadKey: false, - withShift: '!', - withShiftIsDeadKey: false, - withAltGr: '¡', - withAltGrIsDeadKey: false, - withShiftAltGr: '⁄', - withShiftAltGrIsDeadKey: false - }, - Digit2: { - value: '2', - valueIsDeadKey: false, - withShift: '@', - withShiftIsDeadKey: false, - withAltGr: '™', - withAltGrIsDeadKey: false, - withShiftAltGr: '€', - withShiftAltGrIsDeadKey: false - }, - Digit3: { - value: '3', - valueIsDeadKey: false, - withShift: '#', - withShiftIsDeadKey: false, - withAltGr: '£', - withAltGrIsDeadKey: false, - withShiftAltGr: '‹', - withShiftAltGrIsDeadKey: false - }, - Digit4: { - value: '4', - valueIsDeadKey: false, - withShift: '$', - withShiftIsDeadKey: false, - withAltGr: '¢', - withAltGrIsDeadKey: false, - withShiftAltGr: '›', - withShiftAltGrIsDeadKey: false - }, - Digit5: { - value: '5', - valueIsDeadKey: false, - withShift: '%', - withShiftIsDeadKey: false, - withAltGr: '∞', - withAltGrIsDeadKey: false, - withShiftAltGr: 'fi', - withShiftAltGrIsDeadKey: false - }, - Digit6: { - value: '6', - valueIsDeadKey: false, - withShift: '^', - withShiftIsDeadKey: false, - withAltGr: '§', - withAltGrIsDeadKey: false, - withShiftAltGr: 'fl', - withShiftAltGrIsDeadKey: false - }, - Digit7: { - value: '7', - valueIsDeadKey: false, - withShift: '&', - withShiftIsDeadKey: false, - withAltGr: '¶', - withAltGrIsDeadKey: false, - withShiftAltGr: '‡', - withShiftAltGrIsDeadKey: false - }, - Digit8: { - value: '8', - valueIsDeadKey: false, - withShift: '*', - withShiftIsDeadKey: false, - withAltGr: '•', - withAltGrIsDeadKey: false, - withShiftAltGr: '°', - withShiftAltGrIsDeadKey: false - }, - Digit9: { - value: '9', - valueIsDeadKey: false, - withShift: '(', - withShiftIsDeadKey: false, - withAltGr: 'ª', - withAltGrIsDeadKey: false, - withShiftAltGr: '·', - withShiftAltGrIsDeadKey: false - }, - Digit0: { - value: '0', - valueIsDeadKey: false, - withShift: ')', - withShiftIsDeadKey: false, - withAltGr: 'º', - withAltGrIsDeadKey: false, - withShiftAltGr: '‚', - withShiftAltGrIsDeadKey: false - }, - Enter: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Escape: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Backspace: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Tab: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Space: { - value: ' ', - valueIsDeadKey: false, - withShift: ' ', - withShiftIsDeadKey: false, - withAltGr: ' ', - withAltGrIsDeadKey: false, - withShiftAltGr: ' ', - withShiftAltGrIsDeadKey: false - }, - Minus: { - value: '-', - valueIsDeadKey: false, - withShift: '_', - withShiftIsDeadKey: false, - withAltGr: '–', - withAltGrIsDeadKey: false, - withShiftAltGr: '—', - withShiftAltGrIsDeadKey: false - }, - Equal: { - value: '=', - valueIsDeadKey: false, - withShift: '+', - withShiftIsDeadKey: false, - withAltGr: '≠', - withAltGrIsDeadKey: false, - withShiftAltGr: '±', - withShiftAltGrIsDeadKey: false - }, - BracketLeft: { - value: '[', - valueIsDeadKey: false, - withShift: '{', - withShiftIsDeadKey: false, - withAltGr: '“', - withAltGrIsDeadKey: false, - withShiftAltGr: '”', - withShiftAltGrIsDeadKey: false - }, - BracketRight: { - value: ']', - valueIsDeadKey: false, - withShift: '}', - withShiftIsDeadKey: false, - withAltGr: '‘', - withAltGrIsDeadKey: false, - withShiftAltGr: '’', - withShiftAltGrIsDeadKey: false - }, - Backslash: { - value: '\\', - valueIsDeadKey: false, - withShift: '|', - withShiftIsDeadKey: false, - withAltGr: '«', - withAltGrIsDeadKey: false, - withShiftAltGr: '»', - withShiftAltGrIsDeadKey: false - }, - Semicolon: { - value: ';', - valueIsDeadKey: false, - withShift: ':', - withShiftIsDeadKey: false, - withAltGr: '…', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ú', - withShiftAltGrIsDeadKey: false - }, - Quote: { - value: '\'', - valueIsDeadKey: false, - withShift: '"', - withShiftIsDeadKey: false, - withAltGr: 'æ', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Æ', - withShiftAltGrIsDeadKey: false - }, - Backquote: { - value: '`', - valueIsDeadKey: false, - withShift: '~', - withShiftIsDeadKey: false, - withAltGr: '`', - withAltGrIsDeadKey: true, - withShiftAltGr: '`', - withShiftAltGrIsDeadKey: false - }, - Comma: { - value: ',', - valueIsDeadKey: false, - withShift: '<', - withShiftIsDeadKey: false, - withAltGr: '≤', - withAltGrIsDeadKey: false, - withShiftAltGr: '¯', - withShiftAltGrIsDeadKey: false - }, - Period: { - value: '.', - valueIsDeadKey: false, - withShift: '>', - withShiftIsDeadKey: false, - withAltGr: '≥', - withAltGrIsDeadKey: false, - withShiftAltGr: '˘', - withShiftAltGrIsDeadKey: false - }, - Slash: { - value: '/', - valueIsDeadKey: false, - withShift: '?', - withShiftIsDeadKey: false, - withAltGr: '÷', - withAltGrIsDeadKey: false, - withShiftAltGr: '¿', - withShiftAltGrIsDeadKey: false - }, - CapsLock: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F1: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F2: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F3: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F4: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F5: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F6: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F7: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F8: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F9: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F10: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F11: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F12: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Insert: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Home: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - PageUp: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Delete: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - End: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - PageDown: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowDown: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowUp: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumLock: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumpadDivide: { - value: '/', - valueIsDeadKey: false, - withShift: '/', - withShiftIsDeadKey: false, - withAltGr: '/', - withAltGrIsDeadKey: false, - withShiftAltGr: '/', - withShiftAltGrIsDeadKey: false - }, - NumpadMultiply: { - value: '*', - valueIsDeadKey: false, - withShift: '*', - withShiftIsDeadKey: false, - withAltGr: '*', - withAltGrIsDeadKey: false, - withShiftAltGr: '*', - withShiftAltGrIsDeadKey: false - }, - NumpadSubtract: { - value: '-', - valueIsDeadKey: false, - withShift: '-', - withShiftIsDeadKey: false, - withAltGr: '-', - withAltGrIsDeadKey: false, - withShiftAltGr: '-', - withShiftAltGrIsDeadKey: false - }, - NumpadAdd: { - value: '+', - valueIsDeadKey: false, - withShift: '+', - withShiftIsDeadKey: false, - withAltGr: '+', - withAltGrIsDeadKey: false, - withShiftAltGr: '+', - withShiftAltGrIsDeadKey: false - }, - NumpadEnter: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Numpad1: { - value: '1', - valueIsDeadKey: false, - withShift: '1', - withShiftIsDeadKey: false, - withAltGr: '1', - withAltGrIsDeadKey: false, - withShiftAltGr: '1', - withShiftAltGrIsDeadKey: false - }, - Numpad2: { - value: '2', - valueIsDeadKey: false, - withShift: '2', - withShiftIsDeadKey: false, - withAltGr: '2', - withAltGrIsDeadKey: false, - withShiftAltGr: '2', - withShiftAltGrIsDeadKey: false - }, - Numpad3: { - value: '3', - valueIsDeadKey: false, - withShift: '3', - withShiftIsDeadKey: false, - withAltGr: '3', - withAltGrIsDeadKey: false, - withShiftAltGr: '3', - withShiftAltGrIsDeadKey: false - }, - Numpad4: { - value: '4', - valueIsDeadKey: false, - withShift: '4', - withShiftIsDeadKey: false, - withAltGr: '4', - withAltGrIsDeadKey: false, - withShiftAltGr: '4', - withShiftAltGrIsDeadKey: false - }, - Numpad5: { - value: '5', - valueIsDeadKey: false, - withShift: '5', - withShiftIsDeadKey: false, - withAltGr: '5', - withAltGrIsDeadKey: false, - withShiftAltGr: '5', - withShiftAltGrIsDeadKey: false - }, - Numpad6: { - value: '6', - valueIsDeadKey: false, - withShift: '6', - withShiftIsDeadKey: false, - withAltGr: '6', - withAltGrIsDeadKey: false, - withShiftAltGr: '6', - withShiftAltGrIsDeadKey: false - }, - Numpad7: { - value: '7', - valueIsDeadKey: false, - withShift: '7', - withShiftIsDeadKey: false, - withAltGr: '7', - withAltGrIsDeadKey: false, - withShiftAltGr: '7', - withShiftAltGrIsDeadKey: false - }, - Numpad8: { - value: '8', - valueIsDeadKey: false, - withShift: '8', - withShiftIsDeadKey: false, - withAltGr: '8', - withAltGrIsDeadKey: false, - withShiftAltGr: '8', - withShiftAltGrIsDeadKey: false - }, - Numpad9: { - value: '9', - valueIsDeadKey: false, - withShift: '9', - withShiftIsDeadKey: false, - withAltGr: '9', - withAltGrIsDeadKey: false, - withShiftAltGr: '9', - withShiftAltGrIsDeadKey: false - }, - Numpad0: { - value: '0', - valueIsDeadKey: false, - withShift: '0', - withShiftIsDeadKey: false, - withAltGr: '0', - withAltGrIsDeadKey: false, - withShiftAltGr: '0', - withShiftAltGrIsDeadKey: false - }, - NumpadDecimal: { - value: '.', - valueIsDeadKey: false, - withShift: '.', - withShiftIsDeadKey: false, - withAltGr: '.', - withAltGrIsDeadKey: false, - withShiftAltGr: '.', - withShiftAltGrIsDeadKey: false - }, - IntlBackslash: { - value: '§', - valueIsDeadKey: false, - withShift: '±', - withShiftIsDeadKey: false, - withAltGr: '§', - withAltGrIsDeadKey: false, - withShiftAltGr: '±', - withShiftAltGrIsDeadKey: false - }, - ContextMenu: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumpadEqual: { - value: '=', - valueIsDeadKey: false, - withShift: '=', - withShiftIsDeadKey: false, - withAltGr: '=', - withAltGrIsDeadKey: false, - withShiftAltGr: '=', - withShiftAltGrIsDeadKey: false - }, - F13: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F14: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F15: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F16: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F17: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F18: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F19: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F20: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AudioVolumeMute: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AudioVolumeUp: { - value: '', - valueIsDeadKey: false, - withShift: '=', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '=', - withShiftAltGrIsDeadKey: false - }, - AudioVolumeDown: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumpadComma: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - IntlRo: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - KanaMode: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - IntlYen: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ControlLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ShiftLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AltLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - MetaLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ControlRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ShiftRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AltRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - MetaRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - } -}); diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/mac_en_us.txt b/src/vs/workbench/services/keybinding/test/electron-browser/mac_en_us.txt deleted file mode 100644 index 833fdf61c32..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/mac_en_us.txt +++ /dev/null @@ -1,507 +0,0 @@ -isUSStandard: true ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyA | a | A | | A | a | A | [KeyA] | | -| Ctrl+KeyA | a | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | -| Shift+KeyA | A | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | -| Ctrl+Shift+KeyA | A | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | -| Alt+KeyA | a | Alt+A | | Option+A | alt+a | Alt+A | alt+[KeyA] | | -| Ctrl+Alt+KeyA | å | Ctrl+Alt+A | | Ctrl+Option+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | -| Shift+Alt+KeyA | A | Shift+Alt+A | | Shift+Option+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | -| Ctrl+Shift+Alt+KeyA | Å | Ctrl+Shift+Alt+A | | Ctrl+Shift+Option+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyB | b | B | | B | b | B | [KeyB] | | -| Ctrl+KeyB | b | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | -| Shift+KeyB | B | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | -| Ctrl+Shift+KeyB | B | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | -| Alt+KeyB | b | Alt+B | | Option+B | alt+b | Alt+B | alt+[KeyB] | | -| Ctrl+Alt+KeyB | ∫ | Ctrl+Alt+B | | Ctrl+Option+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | -| Shift+Alt+KeyB | B | Shift+Alt+B | | Shift+Option+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | -| Ctrl+Shift+Alt+KeyB | ı | Ctrl+Shift+Alt+B | | Ctrl+Shift+Option+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyC | c | C | | C | c | C | [KeyC] | | -| Ctrl+KeyC | c | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | -| Shift+KeyC | C | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | -| Ctrl+Shift+KeyC | C | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | -| Alt+KeyC | c | Alt+C | | Option+C | alt+c | Alt+C | alt+[KeyC] | | -| Ctrl+Alt+KeyC | ç | Ctrl+Alt+C | | Ctrl+Option+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | -| Shift+Alt+KeyC | C | Shift+Alt+C | | Shift+Option+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | -| Ctrl+Shift+Alt+KeyC | Ç | Ctrl+Shift+Alt+C | | Ctrl+Shift+Option+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyD | d | D | | D | d | D | [KeyD] | | -| Ctrl+KeyD | d | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | -| Shift+KeyD | D | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | -| Ctrl+Shift+KeyD | D | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | -| Alt+KeyD | d | Alt+D | | Option+D | alt+d | Alt+D | alt+[KeyD] | | -| Ctrl+Alt+KeyD | ∂ | Ctrl+Alt+D | | Ctrl+Option+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | -| Shift+Alt+KeyD | D | Shift+Alt+D | | Shift+Option+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | -| Ctrl+Shift+Alt+KeyD | Î | Ctrl+Shift+Alt+D | | Ctrl+Shift+Option+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyE | e | E | | E | e | E | [KeyE] | | -| Ctrl+KeyE | e | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | -| Shift+KeyE | E | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | -| Ctrl+Shift+KeyE | E | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | -| Alt+KeyE | e | Alt+E | | Option+E | alt+e | Alt+E | alt+[KeyE] | | -| Ctrl+Alt+KeyE | ´ | Ctrl+Alt+E | | Ctrl+Option+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | -| Shift+Alt+KeyE | E | Shift+Alt+E | | Shift+Option+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | -| Ctrl+Shift+Alt+KeyE | ´ | Ctrl+Shift+Alt+E | | Ctrl+Shift+Option+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyF | f | F | | F | f | F | [KeyF] | | -| Ctrl+KeyF | f | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | -| Shift+KeyF | F | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | -| Ctrl+Shift+KeyF | F | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | -| Alt+KeyF | f | Alt+F | | Option+F | alt+f | Alt+F | alt+[KeyF] | | -| Ctrl+Alt+KeyF | ƒ | Ctrl+Alt+F | | Ctrl+Option+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | -| Shift+Alt+KeyF | F | Shift+Alt+F | | Shift+Option+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | -| Ctrl+Shift+Alt+KeyF | Ï | Ctrl+Shift+Alt+F | | Ctrl+Shift+Option+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyG | g | G | | G | g | G | [KeyG] | | -| Ctrl+KeyG | g | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | -| Shift+KeyG | G | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | -| Ctrl+Shift+KeyG | G | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | -| Alt+KeyG | g | Alt+G | | Option+G | alt+g | Alt+G | alt+[KeyG] | | -| Ctrl+Alt+KeyG | © | Ctrl+Alt+G | | Ctrl+Option+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | -| Shift+Alt+KeyG | G | Shift+Alt+G | | Shift+Option+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | -| Ctrl+Shift+Alt+KeyG | ˝ | Ctrl+Shift+Alt+G | | Ctrl+Shift+Option+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyH | h | H | | H | h | H | [KeyH] | | -| Ctrl+KeyH | h | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | -| Shift+KeyH | H | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | -| Ctrl+Shift+KeyH | H | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | -| Alt+KeyH | h | Alt+H | | Option+H | alt+h | Alt+H | alt+[KeyH] | | -| Ctrl+Alt+KeyH | ˙ | Ctrl+Alt+H | | Ctrl+Option+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | -| Shift+Alt+KeyH | H | Shift+Alt+H | | Shift+Option+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | -| Ctrl+Shift+Alt+KeyH | Ó | Ctrl+Shift+Alt+H | | Ctrl+Shift+Option+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyI | i | I | | I | i | I | [KeyI] | | -| Ctrl+KeyI | i | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | -| Shift+KeyI | I | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | -| Ctrl+Shift+KeyI | I | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | -| Alt+KeyI | i | Alt+I | | Option+I | alt+i | Alt+I | alt+[KeyI] | | -| Ctrl+Alt+KeyI | ˆ | Ctrl+Alt+I | | Ctrl+Option+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | -| Shift+Alt+KeyI | I | Shift+Alt+I | | Shift+Option+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | -| Ctrl+Shift+Alt+KeyI | ˆ | Ctrl+Shift+Alt+I | | Ctrl+Shift+Option+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyJ | j | J | | J | j | J | [KeyJ] | | -| Ctrl+KeyJ | j | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | -| Shift+KeyJ | J | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | -| Ctrl+Shift+KeyJ | J | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | -| Alt+KeyJ | j | Alt+J | | Option+J | alt+j | Alt+J | alt+[KeyJ] | | -| Ctrl+Alt+KeyJ | ∆ | Ctrl+Alt+J | | Ctrl+Option+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | -| Shift+Alt+KeyJ | J | Shift+Alt+J | | Shift+Option+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | -| Ctrl+Shift+Alt+KeyJ | Ô | Ctrl+Shift+Alt+J | | Ctrl+Shift+Option+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyK | k | K | | K | k | K | [KeyK] | | -| Ctrl+KeyK | k | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | -| Shift+KeyK | K | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | -| Ctrl+Shift+KeyK | K | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | -| Alt+KeyK | k | Alt+K | | Option+K | alt+k | Alt+K | alt+[KeyK] | | -| Ctrl+Alt+KeyK | ˚ | Ctrl+Alt+K | | Ctrl+Option+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | -| Shift+Alt+KeyK | K | Shift+Alt+K | | Shift+Option+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | -| Ctrl+Shift+Alt+KeyK |  | Ctrl+Shift+Alt+K | | Ctrl+Shift+Option+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyL | l | L | | L | l | L | [KeyL] | | -| Ctrl+KeyL | l | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | -| Shift+KeyL | L | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | -| Ctrl+Shift+KeyL | L | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | -| Alt+KeyL | l | Alt+L | | Option+L | alt+l | Alt+L | alt+[KeyL] | | -| Ctrl+Alt+KeyL | ¬ | Ctrl+Alt+L | | Ctrl+Option+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | -| Shift+Alt+KeyL | L | Shift+Alt+L | | Shift+Option+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | -| Ctrl+Shift+Alt+KeyL | Ò | Ctrl+Shift+Alt+L | | Ctrl+Shift+Option+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyM | m | M | | M | m | M | [KeyM] | | -| Ctrl+KeyM | m | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | -| Shift+KeyM | M | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | -| Ctrl+Shift+KeyM | M | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | -| Alt+KeyM | m | Alt+M | | Option+M | alt+m | Alt+M | alt+[KeyM] | | -| Ctrl+Alt+KeyM | µ | Ctrl+Alt+M | | Ctrl+Option+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | -| Shift+Alt+KeyM | M | Shift+Alt+M | | Shift+Option+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | -| Ctrl+Shift+Alt+KeyM |  | Ctrl+Shift+Alt+M | | Ctrl+Shift+Option+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyN | n | N | | N | n | N | [KeyN] | | -| Ctrl+KeyN | n | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | -| Shift+KeyN | N | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | -| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | -| Alt+KeyN | n | Alt+N | | Option+N | alt+n | Alt+N | alt+[KeyN] | | -| Ctrl+Alt+KeyN | ˜ | Ctrl+Alt+N | | Ctrl+Option+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | -| Shift+Alt+KeyN | N | Shift+Alt+N | | Shift+Option+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | -| Ctrl+Shift+Alt+KeyN | ˜ | Ctrl+Shift+Alt+N | | Ctrl+Shift+Option+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyO | o | O | | O | o | O | [KeyO] | | -| Ctrl+KeyO | o | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | -| Shift+KeyO | O | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | -| Ctrl+Shift+KeyO | O | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | -| Alt+KeyO | o | Alt+O | | Option+O | alt+o | Alt+O | alt+[KeyO] | | -| Ctrl+Alt+KeyO | ø | Ctrl+Alt+O | | Ctrl+Option+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | -| Shift+Alt+KeyO | O | Shift+Alt+O | | Shift+Option+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | -| Ctrl+Shift+Alt+KeyO | Ø | Ctrl+Shift+Alt+O | | Ctrl+Shift+Option+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyP | p | P | | P | p | P | [KeyP] | | -| Ctrl+KeyP | p | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | -| Shift+KeyP | P | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | -| Ctrl+Shift+KeyP | P | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | -| Alt+KeyP | p | Alt+P | | Option+P | alt+p | Alt+P | alt+[KeyP] | | -| Ctrl+Alt+KeyP | π | Ctrl+Alt+P | | Ctrl+Option+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | -| Shift+Alt+KeyP | P | Shift+Alt+P | | Shift+Option+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | -| Ctrl+Shift+Alt+KeyP | ∏ | Ctrl+Shift+Alt+P | | Ctrl+Shift+Option+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyQ | q | Q | | Q | q | Q | [KeyQ] | | -| Ctrl+KeyQ | q | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | -| Shift+KeyQ | Q | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | -| Ctrl+Shift+KeyQ | Q | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | -| Alt+KeyQ | q | Alt+Q | | Option+Q | alt+q | Alt+Q | alt+[KeyQ] | | -| Ctrl+Alt+KeyQ | œ | Ctrl+Alt+Q | | Ctrl+Option+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | -| Shift+Alt+KeyQ | Q | Shift+Alt+Q | | Shift+Option+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | -| Ctrl+Shift+Alt+KeyQ | Œ | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Option+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyR | r | R | | R | r | R | [KeyR] | | -| Ctrl+KeyR | r | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | -| Shift+KeyR | R | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | -| Ctrl+Shift+KeyR | R | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | -| Alt+KeyR | r | Alt+R | | Option+R | alt+r | Alt+R | alt+[KeyR] | | -| Ctrl+Alt+KeyR | ® | Ctrl+Alt+R | | Ctrl+Option+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | -| Shift+Alt+KeyR | R | Shift+Alt+R | | Shift+Option+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | -| Ctrl+Shift+Alt+KeyR | ‰ | Ctrl+Shift+Alt+R | | Ctrl+Shift+Option+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyS | s | S | | S | s | S | [KeyS] | | -| Ctrl+KeyS | s | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | -| Shift+KeyS | S | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | -| Ctrl+Shift+KeyS | S | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | -| Alt+KeyS | s | Alt+S | | Option+S | alt+s | Alt+S | alt+[KeyS] | | -| Ctrl+Alt+KeyS | ß | Ctrl+Alt+S | | Ctrl+Option+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | -| Shift+Alt+KeyS | S | Shift+Alt+S | | Shift+Option+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | -| Ctrl+Shift+Alt+KeyS | Í | Ctrl+Shift+Alt+S | | Ctrl+Shift+Option+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyT | t | T | | T | t | T | [KeyT] | | -| Ctrl+KeyT | t | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | -| Shift+KeyT | T | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | -| Ctrl+Shift+KeyT | T | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | -| Alt+KeyT | t | Alt+T | | Option+T | alt+t | Alt+T | alt+[KeyT] | | -| Ctrl+Alt+KeyT | † | Ctrl+Alt+T | | Ctrl+Option+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | -| Shift+Alt+KeyT | T | Shift+Alt+T | | Shift+Option+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | -| Ctrl+Shift+Alt+KeyT | ˇ | Ctrl+Shift+Alt+T | | Ctrl+Shift+Option+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyU | u | U | | U | u | U | [KeyU] | | -| Ctrl+KeyU | u | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | -| Shift+KeyU | U | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | -| Ctrl+Shift+KeyU | U | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | -| Alt+KeyU | u | Alt+U | | Option+U | alt+u | Alt+U | alt+[KeyU] | | -| Ctrl+Alt+KeyU | ¨ | Ctrl+Alt+U | | Ctrl+Option+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | -| Shift+Alt+KeyU | U | Shift+Alt+U | | Shift+Option+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | -| Ctrl+Shift+Alt+KeyU | ¨ | Ctrl+Shift+Alt+U | | Ctrl+Shift+Option+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyV | v | V | | V | v | V | [KeyV] | | -| Ctrl+KeyV | v | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | -| Shift+KeyV | V | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | -| Ctrl+Shift+KeyV | V | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | -| Alt+KeyV | v | Alt+V | | Option+V | alt+v | Alt+V | alt+[KeyV] | | -| Ctrl+Alt+KeyV | √ | Ctrl+Alt+V | | Ctrl+Option+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | -| Shift+Alt+KeyV | V | Shift+Alt+V | | Shift+Option+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | -| Ctrl+Shift+Alt+KeyV | ◊ | Ctrl+Shift+Alt+V | | Ctrl+Shift+Option+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyW | w | W | | W | w | W | [KeyW] | | -| Ctrl+KeyW | w | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | -| Shift+KeyW | W | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | -| Ctrl+Shift+KeyW | W | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | -| Alt+KeyW | w | Alt+W | | Option+W | alt+w | Alt+W | alt+[KeyW] | | -| Ctrl+Alt+KeyW | ∑ | Ctrl+Alt+W | | Ctrl+Option+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | -| Shift+Alt+KeyW | W | Shift+Alt+W | | Shift+Option+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | -| Ctrl+Shift+Alt+KeyW | „ | Ctrl+Shift+Alt+W | | Ctrl+Shift+Option+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyX | x | X | | X | x | X | [KeyX] | | -| Ctrl+KeyX | x | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | -| Shift+KeyX | X | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | -| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | -| Alt+KeyX | x | Alt+X | | Option+X | alt+x | Alt+X | alt+[KeyX] | | -| Ctrl+Alt+KeyX | ≈ | Ctrl+Alt+X | | Ctrl+Option+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | -| Shift+Alt+KeyX | X | Shift+Alt+X | | Shift+Option+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | -| Ctrl+Shift+Alt+KeyX | ˛ | Ctrl+Shift+Alt+X | | Ctrl+Shift+Option+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyY | y | Y | | Y | y | Y | [KeyY] | | -| Ctrl+KeyY | y | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyY] | | -| Shift+KeyY | Y | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyY] | | -| Ctrl+Shift+KeyY | Y | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyY] | | -| Alt+KeyY | y | Alt+Y | | Option+Y | alt+y | Alt+Y | alt+[KeyY] | | -| Ctrl+Alt+KeyY | ¥ | Ctrl+Alt+Y | | Ctrl+Option+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyY] | | -| Shift+Alt+KeyY | Y | Shift+Alt+Y | | Shift+Option+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyY] | | -| Ctrl+Shift+Alt+KeyY | Á | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Option+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyY] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyZ | z | Z | | Z | z | Z | [KeyZ] | | -| Ctrl+KeyZ | z | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyZ] | | -| Shift+KeyZ | Z | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyZ] | | -| Ctrl+Shift+KeyZ | Z | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyZ] | | -| Alt+KeyZ | z | Alt+Z | | Option+Z | alt+z | Alt+Z | alt+[KeyZ] | | -| Ctrl+Alt+KeyZ | Ω | Ctrl+Alt+Z | | Ctrl+Option+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyZ] | | -| Shift+Alt+KeyZ | Z | Shift+Alt+Z | | Shift+Option+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyZ] | | -| Ctrl+Shift+Alt+KeyZ | ¸ | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Option+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyZ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit1 | 1 | 1 | | 1 | 1 | 1 | [Digit1] | | -| Ctrl+Digit1 | 1 | Ctrl+1 | | Ctrl+1 | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | | -| Shift+Digit1 | ! | Shift+1 | | Shift+1 | shift+1 | Shift+1 | shift+[Digit1] | | -| Ctrl+Shift+Digit1 | ! | Ctrl+Shift+1 | | Ctrl+Shift+1 | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | | -| Alt+Digit1 | 1 | Alt+1 | | Option+1 | alt+1 | Alt+1 | alt+[Digit1] | | -| Ctrl+Alt+Digit1 | ¡ | Ctrl+Alt+1 | | Ctrl+Option+1 | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | | -| Shift+Alt+Digit1 | ! | Shift+Alt+1 | | Shift+Option+1 | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | | -| Ctrl+Shift+Alt+Digit1 | ⁄ | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Option+1 | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit2 | 2 | 2 | | 2 | 2 | 2 | [Digit2] | | -| Ctrl+Digit2 | 2 | Ctrl+2 | | Ctrl+2 | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | | -| Shift+Digit2 | @ | Shift+2 | | Shift+2 | shift+2 | Shift+2 | shift+[Digit2] | | -| Ctrl+Shift+Digit2 | @ | Ctrl+Shift+2 | | Ctrl+Shift+2 | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | | -| Alt+Digit2 | 2 | Alt+2 | | Option+2 | alt+2 | Alt+2 | alt+[Digit2] | | -| Ctrl+Alt+Digit2 | ™ | Ctrl+Alt+2 | | Ctrl+Option+2 | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | | -| Shift+Alt+Digit2 | @ | Shift+Alt+2 | | Shift+Option+2 | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | | -| Ctrl+Shift+Alt+Digit2 | € | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Option+2 | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit3 | 3 | 3 | | 3 | 3 | 3 | [Digit3] | | -| Ctrl+Digit3 | 3 | Ctrl+3 | | Ctrl+3 | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | | -| Shift+Digit3 | # | Shift+3 | | Shift+3 | shift+3 | Shift+3 | shift+[Digit3] | | -| Ctrl+Shift+Digit3 | # | Ctrl+Shift+3 | | Ctrl+Shift+3 | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | | -| Alt+Digit3 | 3 | Alt+3 | | Option+3 | alt+3 | Alt+3 | alt+[Digit3] | | -| Ctrl+Alt+Digit3 | £ | Ctrl+Alt+3 | | Ctrl+Option+3 | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | | -| Shift+Alt+Digit3 | # | Shift+Alt+3 | | Shift+Option+3 | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | | -| Ctrl+Shift+Alt+Digit3 | ‹ | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Option+3 | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit4 | 4 | 4 | | 4 | 4 | 4 | [Digit4] | | -| Ctrl+Digit4 | 4 | Ctrl+4 | | Ctrl+4 | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | | -| Shift+Digit4 | $ | Shift+4 | | Shift+4 | shift+4 | Shift+4 | shift+[Digit4] | | -| Ctrl+Shift+Digit4 | $ | Ctrl+Shift+4 | | Ctrl+Shift+4 | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | | -| Alt+Digit4 | 4 | Alt+4 | | Option+4 | alt+4 | Alt+4 | alt+[Digit4] | | -| Ctrl+Alt+Digit4 | ¢ | Ctrl+Alt+4 | | Ctrl+Option+4 | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | | -| Shift+Alt+Digit4 | $ | Shift+Alt+4 | | Shift+Option+4 | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | | -| Ctrl+Shift+Alt+Digit4 | › | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Option+4 | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit5 | 5 | 5 | | 5 | 5 | 5 | [Digit5] | | -| Ctrl+Digit5 | 5 | Ctrl+5 | | Ctrl+5 | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | | -| Shift+Digit5 | % | Shift+5 | | Shift+5 | shift+5 | Shift+5 | shift+[Digit5] | | -| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+5 | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | | -| Alt+Digit5 | 5 | Alt+5 | | Option+5 | alt+5 | Alt+5 | alt+[Digit5] | | -| Ctrl+Alt+Digit5 | ∞ | Ctrl+Alt+5 | | Ctrl+Option+5 | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | | -| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Option+5 | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | | -| Ctrl+Shift+Alt+Digit5 | fi | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Option+5 | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit6 | 6 | 6 | | 6 | 6 | 6 | [Digit6] | | -| Ctrl+Digit6 | 6 | Ctrl+6 | | Ctrl+6 | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | | -| Shift+Digit6 | ^ | Shift+6 | | Shift+6 | shift+6 | Shift+6 | shift+[Digit6] | | -| Ctrl+Shift+Digit6 | ^ | Ctrl+Shift+6 | | Ctrl+Shift+6 | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | | -| Alt+Digit6 | 6 | Alt+6 | | Option+6 | alt+6 | Alt+6 | alt+[Digit6] | | -| Ctrl+Alt+Digit6 | § | Ctrl+Alt+6 | | Ctrl+Option+6 | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | | -| Shift+Alt+Digit6 | ^ | Shift+Alt+6 | | Shift+Option+6 | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | | -| Ctrl+Shift+Alt+Digit6 | fl | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Option+6 | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit7 | 7 | 7 | | 7 | 7 | 7 | [Digit7] | | -| Ctrl+Digit7 | 7 | Ctrl+7 | | Ctrl+7 | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | | -| Shift+Digit7 | & | Shift+7 | | Shift+7 | shift+7 | Shift+7 | shift+[Digit7] | | -| Ctrl+Shift+Digit7 | & | Ctrl+Shift+7 | | Ctrl+Shift+7 | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | | -| Alt+Digit7 | 7 | Alt+7 | | Option+7 | alt+7 | Alt+7 | alt+[Digit7] | | -| Ctrl+Alt+Digit7 | ¶ | Ctrl+Alt+7 | | Ctrl+Option+7 | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | | -| Shift+Alt+Digit7 | & | Shift+Alt+7 | | Shift+Option+7 | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | | -| Ctrl+Shift+Alt+Digit7 | ‡ | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Option+7 | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit8 | 8 | 8 | | 8 | 8 | 8 | [Digit8] | | -| Ctrl+Digit8 | 8 | Ctrl+8 | | Ctrl+8 | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | | -| Shift+Digit8 | * | Shift+8 | | Shift+8 | shift+8 | Shift+8 | shift+[Digit8] | | -| Ctrl+Shift+Digit8 | * | Ctrl+Shift+8 | | Ctrl+Shift+8 | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | | -| Alt+Digit8 | 8 | Alt+8 | | Option+8 | alt+8 | Alt+8 | alt+[Digit8] | | -| Ctrl+Alt+Digit8 | • | Ctrl+Alt+8 | | Ctrl+Option+8 | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | | -| Shift+Alt+Digit8 | * | Shift+Alt+8 | | Shift+Option+8 | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | | -| Ctrl+Shift+Alt+Digit8 | ° | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Option+8 | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit9 | 9 | 9 | | 9 | 9 | 9 | [Digit9] | | -| Ctrl+Digit9 | 9 | Ctrl+9 | | Ctrl+9 | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | | -| Shift+Digit9 | ( | Shift+9 | | Shift+9 | shift+9 | Shift+9 | shift+[Digit9] | | -| Ctrl+Shift+Digit9 | ( | Ctrl+Shift+9 | | Ctrl+Shift+9 | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | | -| Alt+Digit9 | 9 | Alt+9 | | Option+9 | alt+9 | Alt+9 | alt+[Digit9] | | -| Ctrl+Alt+Digit9 | ª | Ctrl+Alt+9 | | Ctrl+Option+9 | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | | -| Shift+Alt+Digit9 | ( | Shift+Alt+9 | | Shift+Option+9 | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | | -| Ctrl+Shift+Alt+Digit9 | · | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Option+9 | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit0 | 0 | 0 | | 0 | 0 | 0 | [Digit0] | | -| Ctrl+Digit0 | 0 | Ctrl+0 | | Ctrl+0 | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | | -| Shift+Digit0 | ) | Shift+0 | | Shift+0 | shift+0 | Shift+0 | shift+[Digit0] | | -| Ctrl+Shift+Digit0 | ) | Ctrl+Shift+0 | | Ctrl+Shift+0 | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | | -| Alt+Digit0 | 0 | Alt+0 | | Option+0 | alt+0 | Alt+0 | alt+[Digit0] | | -| Ctrl+Alt+Digit0 | º | Ctrl+Alt+0 | | Ctrl+Option+0 | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | | -| Shift+Alt+Digit0 | ) | Shift+Alt+0 | | Shift+Option+0 | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | | -| Ctrl+Shift+Alt+Digit0 | ‚ | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Option+0 | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Minus | - | - | | - | - | - | [Minus] | | -| Ctrl+Minus | - | Ctrl+- | | Ctrl+- | ctrl+- | Ctrl+- | ctrl+[Minus] | | -| Shift+Minus | _ | Shift+- | | Shift+- | shift+- | Shift+- | shift+[Minus] | | -| Ctrl+Shift+Minus | _ | Ctrl+Shift+- | | Ctrl+Shift+- | ctrl+shift+- | Ctrl+Shift+- | ctrl+shift+[Minus] | | -| Alt+Minus | - | Alt+- | | Option+- | alt+- | Alt+- | alt+[Minus] | | -| Ctrl+Alt+Minus | – | Ctrl+Alt+- | | Ctrl+Option+- | ctrl+alt+- | Ctrl+Alt+- | ctrl+alt+[Minus] | | -| Shift+Alt+Minus | _ | Shift+Alt+- | | Shift+Option+- | shift+alt+- | Shift+Alt+- | shift+alt+[Minus] | | -| Ctrl+Shift+Alt+Minus | — | Ctrl+Shift+Alt+- | | Ctrl+Shift+Option+- | ctrl+shift+alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+[Minus] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Equal | = | = | | = | = | = | [Equal] | | -| Ctrl+Equal | = | Ctrl+= | | Ctrl+= | ctrl+= | Ctrl+= | ctrl+[Equal] | | -| Shift+Equal | + | Shift+= | | Shift+= | shift+= | Shift+= | shift+[Equal] | | -| Ctrl+Shift+Equal | + | Ctrl+Shift+= | | Ctrl+Shift+= | ctrl+shift+= | Ctrl+Shift+= | ctrl+shift+[Equal] | | -| Alt+Equal | = | Alt+= | | Option+= | alt+= | Alt+= | alt+[Equal] | | -| Ctrl+Alt+Equal | ≠ | Ctrl+Alt+= | | Ctrl+Option+= | ctrl+alt+= | Ctrl+Alt+= | ctrl+alt+[Equal] | | -| Shift+Alt+Equal | + | Shift+Alt+= | | Shift+Option+= | shift+alt+= | Shift+Alt+= | shift+alt+[Equal] | | -| Ctrl+Shift+Alt+Equal | ± | Ctrl+Shift+Alt+= | | Ctrl+Shift+Option+= | ctrl+shift+alt+= | Ctrl+Shift+Alt+= | ctrl+shift+alt+[Equal] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketLeft | [ | [ | | [ | [ | [ | [BracketLeft] | | -| Ctrl+BracketLeft | [ | Ctrl+[ | | Ctrl+[ | ctrl+[ | Ctrl+[ | ctrl+[BracketLeft] | | -| Shift+BracketLeft | { | Shift+[ | | Shift+[ | shift+[ | Shift+[ | shift+[BracketLeft] | | -| Ctrl+Shift+BracketLeft | { | Ctrl+Shift+[ | | Ctrl+Shift+[ | ctrl+shift+[ | Ctrl+Shift+[ | ctrl+shift+[BracketLeft] | | -| Alt+BracketLeft | [ | Alt+[ | | Option+[ | alt+[ | Alt+[ | alt+[BracketLeft] | | -| Ctrl+Alt+BracketLeft | “ | Ctrl+Alt+[ | | Ctrl+Option+[ | ctrl+alt+[ | Ctrl+Alt+[ | ctrl+alt+[BracketLeft] | | -| Shift+Alt+BracketLeft | { | Shift+Alt+[ | | Shift+Option+[ | shift+alt+[ | Shift+Alt+[ | shift+alt+[BracketLeft] | | -| Ctrl+Shift+Alt+BracketLeft | ” | Ctrl+Shift+Alt+[ | | Ctrl+Shift+Option+[ | ctrl+shift+alt+[ | Ctrl+Shift+Alt+[ | ctrl+shift+alt+[BracketLeft] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketRight | ] | ] | | ] | ] | ] | [BracketRight] | | -| Ctrl+BracketRight | ] | Ctrl+] | | Ctrl+] | ctrl+] | Ctrl+] | ctrl+[BracketRight] | | -| Shift+BracketRight | } | Shift+] | | Shift+] | shift+] | Shift+] | shift+[BracketRight] | | -| Ctrl+Shift+BracketRight | } | Ctrl+Shift+] | | Ctrl+Shift+] | ctrl+shift+] | Ctrl+Shift+] | ctrl+shift+[BracketRight] | | -| Alt+BracketRight | ] | Alt+] | | Option+] | alt+] | Alt+] | alt+[BracketRight] | | -| Ctrl+Alt+BracketRight | ‘ | Ctrl+Alt+] | | Ctrl+Option+] | ctrl+alt+] | Ctrl+Alt+] | ctrl+alt+[BracketRight] | | -| Shift+Alt+BracketRight | } | Shift+Alt+] | | Shift+Option+] | shift+alt+] | Shift+Alt+] | shift+alt+[BracketRight] | | -| Ctrl+Shift+Alt+BracketRight | ’ | Ctrl+Shift+Alt+] | | Ctrl+Shift+Option+] | ctrl+shift+alt+] | Ctrl+Shift+Alt+] | ctrl+shift+alt+[BracketRight] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backslash | \ | \ | | \ | \ | \ | [Backslash] | | -| Ctrl+Backslash | \ | Ctrl+\ | | Ctrl+\ | ctrl+\ | Ctrl+\ | ctrl+[Backslash] | | -| Shift+Backslash | | | Shift+\ | | Shift+\ | shift+\ | Shift+\ | shift+[Backslash] | | -| Ctrl+Shift+Backslash | | | Ctrl+Shift+\ | | Ctrl+Shift+\ | ctrl+shift+\ | Ctrl+Shift+\ | ctrl+shift+[Backslash] | | -| Alt+Backslash | \ | Alt+\ | | Option+\ | alt+\ | Alt+\ | alt+[Backslash] | | -| Ctrl+Alt+Backslash | « | Ctrl+Alt+\ | | Ctrl+Option+\ | ctrl+alt+\ | Ctrl+Alt+\ | ctrl+alt+[Backslash] | | -| Shift+Alt+Backslash | | | Shift+Alt+\ | | Shift+Option+\ | shift+alt+\ | Shift+Alt+\ | shift+alt+[Backslash] | | -| Ctrl+Shift+Alt+Backslash | » | Ctrl+Shift+Alt+\ | | Ctrl+Shift+Option+\ | ctrl+shift+alt+\ | Ctrl+Shift+Alt+\ | ctrl+shift+alt+[Backslash] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlHash | --- | | | null | null | null | null | | -| Ctrl+IntlHash | --- | | | null | null | null | null | | -| Shift+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | -| Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | -| Shift+Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Semicolon | ; | ; | | ; | ; | ; | [Semicolon] | | -| Ctrl+Semicolon | ; | Ctrl+; | | Ctrl+; | ctrl+; | Ctrl+; | ctrl+[Semicolon] | | -| Shift+Semicolon | : | Shift+; | | Shift+; | shift+; | Shift+; | shift+[Semicolon] | | -| Ctrl+Shift+Semicolon | : | Ctrl+Shift+; | | Ctrl+Shift+; | ctrl+shift+; | Ctrl+Shift+; | ctrl+shift+[Semicolon] | | -| Alt+Semicolon | ; | Alt+; | | Option+; | alt+; | Alt+; | alt+[Semicolon] | | -| Ctrl+Alt+Semicolon | … | Ctrl+Alt+; | | Ctrl+Option+; | ctrl+alt+; | Ctrl+Alt+; | ctrl+alt+[Semicolon] | | -| Shift+Alt+Semicolon | : | Shift+Alt+; | | Shift+Option+; | shift+alt+; | Shift+Alt+; | shift+alt+[Semicolon] | | -| Ctrl+Shift+Alt+Semicolon | Ú | Ctrl+Shift+Alt+; | | Ctrl+Shift+Option+; | ctrl+shift+alt+; | Ctrl+Shift+Alt+; | ctrl+shift+alt+[Semicolon] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Quote | ' | ' | | ' | ' | ' | [Quote] | | -| Ctrl+Quote | ' | Ctrl+' | | Ctrl+' | ctrl+' | Ctrl+' | ctrl+[Quote] | | -| Shift+Quote | " | Shift+' | | Shift+' | shift+' | Shift+' | shift+[Quote] | | -| Ctrl+Shift+Quote | " | Ctrl+Shift+' | | Ctrl+Shift+' | ctrl+shift+' | Ctrl+Shift+' | ctrl+shift+[Quote] | | -| Alt+Quote | ' | Alt+' | | Option+' | alt+' | Alt+' | alt+[Quote] | | -| Ctrl+Alt+Quote | æ | Ctrl+Alt+' | | Ctrl+Option+' | ctrl+alt+' | Ctrl+Alt+' | ctrl+alt+[Quote] | | -| Shift+Alt+Quote | " | Shift+Alt+' | | Shift+Option+' | shift+alt+' | Shift+Alt+' | shift+alt+[Quote] | | -| Ctrl+Shift+Alt+Quote | Æ | Ctrl+Shift+Alt+' | | Ctrl+Shift+Option+' | ctrl+shift+alt+' | Ctrl+Shift+Alt+' | ctrl+shift+alt+[Quote] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backquote | ` | ` | | ` | ` | ` | [Backquote] | | -| Ctrl+Backquote | ` | Ctrl+` | | Ctrl+` | ctrl+` | Ctrl+` | ctrl+[Backquote] | | -| Shift+Backquote | ~ | Shift+` | | Shift+` | shift+` | Shift+` | shift+[Backquote] | | -| Ctrl+Shift+Backquote | ~ | Ctrl+Shift+` | | Ctrl+Shift+` | ctrl+shift+` | Ctrl+Shift+` | ctrl+shift+[Backquote] | | -| Alt+Backquote | ` | Alt+` | | Option+` | alt+` | Alt+` | alt+[Backquote] | | -| Ctrl+Alt+Backquote | ` | Ctrl+Alt+` | | Ctrl+Option+` | ctrl+alt+` | Ctrl+Alt+` | ctrl+alt+[Backquote] | | -| Shift+Alt+Backquote | ~ | Shift+Alt+` | | Shift+Option+` | shift+alt+` | Shift+Alt+` | shift+alt+[Backquote] | | -| Ctrl+Shift+Alt+Backquote | ` | Ctrl+Shift+Alt+` | | Ctrl+Shift+Option+` | ctrl+shift+alt+` | Ctrl+Shift+Alt+` | ctrl+shift+alt+[Backquote] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Comma | , | , | | , | , | , | [Comma] | | -| Ctrl+Comma | , | Ctrl+, | | Ctrl+, | ctrl+, | Ctrl+, | ctrl+[Comma] | | -| Shift+Comma | < | Shift+, | | Shift+, | shift+, | Shift+, | shift+[Comma] | | -| Ctrl+Shift+Comma | < | Ctrl+Shift+, | | Ctrl+Shift+, | ctrl+shift+, | Ctrl+Shift+, | ctrl+shift+[Comma] | | -| Alt+Comma | , | Alt+, | | Option+, | alt+, | Alt+, | alt+[Comma] | | -| Ctrl+Alt+Comma | ≤ | Ctrl+Alt+, | | Ctrl+Option+, | ctrl+alt+, | Ctrl+Alt+, | ctrl+alt+[Comma] | | -| Shift+Alt+Comma | < | Shift+Alt+, | | Shift+Option+, | shift+alt+, | Shift+Alt+, | shift+alt+[Comma] | | -| Ctrl+Shift+Alt+Comma | ¯ | Ctrl+Shift+Alt+, | | Ctrl+Shift+Option+, | ctrl+shift+alt+, | Ctrl+Shift+Alt+, | ctrl+shift+alt+[Comma] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Period | . | . | | . | . | . | [Period] | | -| Ctrl+Period | . | Ctrl+. | | Ctrl+. | ctrl+. | Ctrl+. | ctrl+[Period] | | -| Shift+Period | > | Shift+. | | Shift+. | shift+. | Shift+. | shift+[Period] | | -| Ctrl+Shift+Period | > | Ctrl+Shift+. | | Ctrl+Shift+. | ctrl+shift+. | Ctrl+Shift+. | ctrl+shift+[Period] | | -| Alt+Period | . | Alt+. | | Option+. | alt+. | Alt+. | alt+[Period] | | -| Ctrl+Alt+Period | ≥ | Ctrl+Alt+. | | Ctrl+Option+. | ctrl+alt+. | Ctrl+Alt+. | ctrl+alt+[Period] | | -| Shift+Alt+Period | > | Shift+Alt+. | | Shift+Option+. | shift+alt+. | Shift+Alt+. | shift+alt+[Period] | | -| Ctrl+Shift+Alt+Period | ˘ | Ctrl+Shift+Alt+. | | Ctrl+Shift+Option+. | ctrl+shift+alt+. | Ctrl+Shift+Alt+. | ctrl+shift+alt+[Period] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Slash | / | / | | / | / | / | [Slash] | | -| Ctrl+Slash | / | Ctrl+/ | | Ctrl+/ | ctrl+/ | Ctrl+/ | ctrl+[Slash] | | -| Shift+Slash | ? | Shift+/ | | Shift+/ | shift+/ | Shift+/ | shift+[Slash] | | -| Ctrl+Shift+Slash | ? | Ctrl+Shift+/ | | Ctrl+Shift+/ | ctrl+shift+/ | Ctrl+Shift+/ | ctrl+shift+[Slash] | | -| Alt+Slash | / | Alt+/ | | Option+/ | alt+/ | Alt+/ | alt+[Slash] | | -| Ctrl+Alt+Slash | ÷ | Ctrl+Alt+/ | | Ctrl+Option+/ | ctrl+alt+/ | Ctrl+Alt+/ | ctrl+alt+[Slash] | | -| Shift+Alt+Slash | ? | Shift+Alt+/ | | Shift+Option+/ | shift+alt+/ | Shift+Alt+/ | shift+alt+[Slash] | | -| Ctrl+Shift+Alt+Slash | ¿ | Ctrl+Shift+Alt+/ | | Ctrl+Shift+Option+/ | ctrl+shift+alt+/ | Ctrl+Shift+Alt+/ | ctrl+shift+alt+[Slash] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | -| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | -| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | -| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | -| Alt+ArrowUp | --- | Alt+UpArrow | | Option+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | -| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Option+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | -| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Option+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | -| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Option+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | -| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | -| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | -| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | -| Alt+Numpad0 | --- | Alt+NumPad0 | | Option+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | -| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Option+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | -| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Option+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | -| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Option+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlBackslash | § | | | § | [IntlBackslash] | null | [IntlBackslash] | NO | -| Ctrl+IntlBackslash | § | | | Ctrl+§ | ctrl+[IntlBackslash] | null | ctrl+[IntlBackslash] | NO | -| Shift+IntlBackslash | ± | | | Shift+§ | shift+[IntlBackslash] | null | shift+[IntlBackslash] | NO | -| Ctrl+Shift+IntlBackslash | ± | | | Ctrl+Shift+§ | ctrl+shift+[IntlBackslash] | null | ctrl+shift+[IntlBackslash] | NO | -| Alt+IntlBackslash | § | | | Option+§ | alt+[IntlBackslash] | null | alt+[IntlBackslash] | NO | -| Ctrl+Alt+IntlBackslash | § | | | Ctrl+Option+§ | ctrl+alt+[IntlBackslash] | null | ctrl+alt+[IntlBackslash] | NO | -| Shift+Alt+IntlBackslash | ± | | | Shift+Option+§ | shift+alt+[IntlBackslash] | null | shift+alt+[IntlBackslash] | NO | -| Ctrl+Shift+Alt+IntlBackslash | ± | | | Ctrl+Shift+Option+§ | ctrl+shift+alt+[IntlBackslash] | null | ctrl+shift+alt+[IntlBackslash] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | -| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | -| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | -| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | -| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | -| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | -| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | -| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | -| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | -| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | -| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | -| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | -| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | -| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | -| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant.js b/src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant.js deleted file mode 100644 index 7a3fd205cc5..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant.js +++ /dev/null @@ -1,1188 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -define({ - KeyA: { - value: 'ㄇ', - valueIsDeadKey: false, - withShift: 'A', - withShiftIsDeadKey: false, - withAltGr: 'a', - withAltGrIsDeadKey: false, - withShiftAltGr: 'A', - withShiftAltGrIsDeadKey: false - }, - KeyB: { - value: 'ㄖ', - valueIsDeadKey: false, - withShift: 'B', - withShiftIsDeadKey: false, - withAltGr: 'b', - withAltGrIsDeadKey: false, - withShiftAltGr: 'B', - withShiftAltGrIsDeadKey: false - }, - KeyC: { - value: 'ㄏ', - valueIsDeadKey: false, - withShift: 'C', - withShiftIsDeadKey: false, - withAltGr: 'c', - withAltGrIsDeadKey: false, - withShiftAltGr: 'C', - withShiftAltGrIsDeadKey: false - }, - KeyD: { - value: 'ㄎ', - valueIsDeadKey: false, - withShift: 'D', - withShiftIsDeadKey: false, - withAltGr: 'd', - withAltGrIsDeadKey: false, - withShiftAltGr: 'D', - withShiftAltGrIsDeadKey: false - }, - KeyE: { - value: 'ㄍ', - valueIsDeadKey: false, - withShift: 'E', - withShiftIsDeadKey: false, - withAltGr: 'e', - withAltGrIsDeadKey: false, - withShiftAltGr: 'E', - withShiftAltGrIsDeadKey: false - }, - KeyF: { - value: 'ㄑ', - valueIsDeadKey: false, - withShift: 'F', - withShiftIsDeadKey: false, - withAltGr: 'f', - withAltGrIsDeadKey: false, - withShiftAltGr: 'F', - withShiftAltGrIsDeadKey: false - }, - KeyG: { - value: 'ㄕ', - valueIsDeadKey: false, - withShift: 'G', - withShiftIsDeadKey: false, - withAltGr: 'g', - withAltGrIsDeadKey: false, - withShiftAltGr: 'G', - withShiftAltGrIsDeadKey: false - }, - KeyH: { - value: 'ㄘ', - valueIsDeadKey: false, - withShift: 'H', - withShiftIsDeadKey: false, - withAltGr: 'h', - withAltGrIsDeadKey: false, - withShiftAltGr: 'H', - withShiftAltGrIsDeadKey: false - }, - KeyI: { - value: 'ㄛ', - valueIsDeadKey: false, - withShift: 'I', - withShiftIsDeadKey: false, - withAltGr: 'i', - withAltGrIsDeadKey: false, - withShiftAltGr: 'I', - withShiftAltGrIsDeadKey: false - }, - KeyJ: { - value: 'ㄨ', - valueIsDeadKey: false, - withShift: 'J', - withShiftIsDeadKey: false, - withAltGr: 'j', - withAltGrIsDeadKey: false, - withShiftAltGr: 'J', - withShiftAltGrIsDeadKey: false - }, - KeyK: { - value: 'ㄜ', - valueIsDeadKey: false, - withShift: 'K', - withShiftIsDeadKey: false, - withAltGr: 'k', - withAltGrIsDeadKey: false, - withShiftAltGr: 'K', - withShiftAltGrIsDeadKey: false - }, - KeyL: { - value: 'ㄠ', - valueIsDeadKey: false, - withShift: 'L', - withShiftIsDeadKey: false, - withAltGr: 'l', - withAltGrIsDeadKey: false, - withShiftAltGr: 'L', - withShiftAltGrIsDeadKey: false - }, - KeyM: { - value: 'ㄩ', - valueIsDeadKey: false, - withShift: 'M', - withShiftIsDeadKey: false, - withAltGr: 'm', - withAltGrIsDeadKey: false, - withShiftAltGr: 'M', - withShiftAltGrIsDeadKey: false - }, - KeyN: { - value: 'ㄙ', - valueIsDeadKey: false, - withShift: 'N', - withShiftIsDeadKey: false, - withAltGr: 'n', - withAltGrIsDeadKey: false, - withShiftAltGr: 'N', - withShiftAltGrIsDeadKey: false - }, - KeyO: { - value: 'ㄟ', - valueIsDeadKey: false, - withShift: 'O', - withShiftIsDeadKey: false, - withAltGr: 'o', - withAltGrIsDeadKey: false, - withShiftAltGr: 'O', - withShiftAltGrIsDeadKey: false - }, - KeyP: { - value: 'ㄣ', - valueIsDeadKey: false, - withShift: 'P', - withShiftIsDeadKey: false, - withAltGr: 'p', - withAltGrIsDeadKey: false, - withShiftAltGr: 'P', - withShiftAltGrIsDeadKey: false - }, - KeyQ: { - value: 'ㄆ', - valueIsDeadKey: false, - withShift: 'Q', - withShiftIsDeadKey: false, - withAltGr: 'q', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Q', - withShiftAltGrIsDeadKey: false - }, - KeyR: { - value: 'ㄐ', - valueIsDeadKey: false, - withShift: 'R', - withShiftIsDeadKey: false, - withAltGr: 'r', - withAltGrIsDeadKey: false, - withShiftAltGr: 'R', - withShiftAltGrIsDeadKey: false - }, - KeyS: { - value: 'ㄋ', - valueIsDeadKey: false, - withShift: 'S', - withShiftIsDeadKey: false, - withAltGr: 's', - withAltGrIsDeadKey: false, - withShiftAltGr: 'S', - withShiftAltGrIsDeadKey: false - }, - KeyT: { - value: 'ㄔ', - valueIsDeadKey: false, - withShift: 'T', - withShiftIsDeadKey: false, - withAltGr: 't', - withAltGrIsDeadKey: false, - withShiftAltGr: 'T', - withShiftAltGrIsDeadKey: false - }, - KeyU: { - value: 'ㄧ', - valueIsDeadKey: false, - withShift: 'U', - withShiftIsDeadKey: false, - withAltGr: 'u', - withAltGrIsDeadKey: false, - withShiftAltGr: 'U', - withShiftAltGrIsDeadKey: false - }, - KeyV: { - value: 'ㄒ', - valueIsDeadKey: false, - withShift: 'V', - withShiftIsDeadKey: false, - withAltGr: 'v', - withAltGrIsDeadKey: false, - withShiftAltGr: 'V', - withShiftAltGrIsDeadKey: false - }, - KeyW: { - value: 'ㄊ', - valueIsDeadKey: false, - withShift: 'W', - withShiftIsDeadKey: false, - withAltGr: 'w', - withAltGrIsDeadKey: false, - withShiftAltGr: 'W', - withShiftAltGrIsDeadKey: false - }, - KeyX: { - value: 'ㄌ', - valueIsDeadKey: false, - withShift: 'X', - withShiftIsDeadKey: false, - withAltGr: 'x', - withAltGrIsDeadKey: false, - withShiftAltGr: 'X', - withShiftAltGrIsDeadKey: false - }, - KeyY: { - value: 'ㄗ', - valueIsDeadKey: false, - withShift: 'Y', - withShiftIsDeadKey: false, - withAltGr: 'y', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Y', - withShiftAltGrIsDeadKey: false - }, - KeyZ: { - value: 'ㄈ', - valueIsDeadKey: false, - withShift: 'Z', - withShiftIsDeadKey: false, - withAltGr: 'z', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Z', - withShiftAltGrIsDeadKey: false - }, - Digit1: { - value: 'ㄅ', - valueIsDeadKey: false, - withShift: '!', - withShiftIsDeadKey: false, - withAltGr: '1', - withAltGrIsDeadKey: false, - withShiftAltGr: '!', - withShiftAltGrIsDeadKey: false - }, - Digit2: { - value: 'ㄉ', - valueIsDeadKey: false, - withShift: '@', - withShiftIsDeadKey: false, - withAltGr: '2', - withAltGrIsDeadKey: false, - withShiftAltGr: '@', - withShiftAltGrIsDeadKey: false - }, - Digit3: { - value: 'ˇ', - valueIsDeadKey: false, - withShift: '#', - withShiftIsDeadKey: false, - withAltGr: '3', - withAltGrIsDeadKey: false, - withShiftAltGr: '#', - withShiftAltGrIsDeadKey: false - }, - Digit4: { - value: 'ˋ', - valueIsDeadKey: false, - withShift: '$', - withShiftIsDeadKey: false, - withAltGr: '4', - withAltGrIsDeadKey: false, - withShiftAltGr: '$', - withShiftAltGrIsDeadKey: false - }, - Digit5: { - value: 'ㄓ', - valueIsDeadKey: false, - withShift: '%', - withShiftIsDeadKey: false, - withAltGr: '5', - withAltGrIsDeadKey: false, - withShiftAltGr: '%', - withShiftAltGrIsDeadKey: false - }, - Digit6: { - value: 'ˊ', - valueIsDeadKey: false, - withShift: '^', - withShiftIsDeadKey: false, - withAltGr: '6', - withAltGrIsDeadKey: false, - withShiftAltGr: '^', - withShiftAltGrIsDeadKey: false - }, - Digit7: { - value: '˙', - valueIsDeadKey: false, - withShift: '&', - withShiftIsDeadKey: false, - withAltGr: '7', - withAltGrIsDeadKey: false, - withShiftAltGr: '&', - withShiftAltGrIsDeadKey: false - }, - Digit8: { - value: 'ㄚ', - valueIsDeadKey: false, - withShift: '*', - withShiftIsDeadKey: false, - withAltGr: '8', - withAltGrIsDeadKey: false, - withShiftAltGr: '*', - withShiftAltGrIsDeadKey: false - }, - Digit9: { - value: 'ㄞ', - valueIsDeadKey: false, - withShift: '(', - withShiftIsDeadKey: false, - withAltGr: '9', - withAltGrIsDeadKey: false, - withShiftAltGr: '(', - withShiftAltGrIsDeadKey: false - }, - Digit0: { - value: 'ㄢ', - valueIsDeadKey: false, - withShift: ')', - withShiftIsDeadKey: false, - withAltGr: '0', - withAltGrIsDeadKey: false, - withShiftAltGr: ')', - withShiftAltGrIsDeadKey: false - }, - Enter: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Escape: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '‍', - withAltGrIsDeadKey: false, - withShiftAltGr: '‌', - withShiftAltGrIsDeadKey: false - }, - Backspace: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Tab: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Space: { - value: ' ', - valueIsDeadKey: false, - withShift: ' ', - withShiftIsDeadKey: false, - withAltGr: ' ', - withAltGrIsDeadKey: false, - withShiftAltGr: ' ', - withShiftAltGrIsDeadKey: false - }, - Minus: { - value: 'ㄦ', - valueIsDeadKey: false, - withShift: '_', - withShiftIsDeadKey: false, - withAltGr: '—', - withAltGrIsDeadKey: false, - withShiftAltGr: '_', - withShiftAltGrIsDeadKey: false - }, - Equal: { - value: '=', - valueIsDeadKey: false, - withShift: '+', - withShiftIsDeadKey: false, - withAltGr: '=', - withAltGrIsDeadKey: false, - withShiftAltGr: '+', - withShiftAltGrIsDeadKey: false - }, - BracketLeft: { - value: '「', - valueIsDeadKey: false, - withShift: '『', - withShiftIsDeadKey: false, - withAltGr: '[', - withAltGrIsDeadKey: false, - withShiftAltGr: '{', - withShiftAltGrIsDeadKey: false - }, - BracketRight: { - value: '」', - valueIsDeadKey: false, - withShift: '』', - withShiftIsDeadKey: false, - withAltGr: ']', - withAltGrIsDeadKey: false, - withShiftAltGr: '}', - withShiftAltGrIsDeadKey: false - }, - Backslash: { - value: '、', - valueIsDeadKey: false, - withShift: '|', - withShiftIsDeadKey: false, - withAltGr: '\\', - withAltGrIsDeadKey: false, - withShiftAltGr: '|', - withShiftAltGrIsDeadKey: false - }, - Semicolon: { - value: 'ㄤ', - valueIsDeadKey: false, - withShift: ':', - withShiftIsDeadKey: false, - withAltGr: ';', - withAltGrIsDeadKey: false, - withShiftAltGr: ':', - withShiftAltGrIsDeadKey: false - }, - Quote: { - value: '\'', - valueIsDeadKey: false, - withShift: '"', - withShiftIsDeadKey: false, - withAltGr: '\'', - withAltGrIsDeadKey: false, - withShiftAltGr: '"', - withShiftAltGrIsDeadKey: false - }, - Backquote: { - value: '·', - valueIsDeadKey: false, - withShift: '~', - withShiftIsDeadKey: false, - withAltGr: '`', - withAltGrIsDeadKey: false, - withShiftAltGr: '~', - withShiftAltGrIsDeadKey: false - }, - Comma: { - value: 'ㄝ', - valueIsDeadKey: false, - withShift: ',', - withShiftIsDeadKey: false, - withAltGr: ',', - withAltGrIsDeadKey: false, - withShiftAltGr: '<', - withShiftAltGrIsDeadKey: false - }, - Period: { - value: 'ㄡ', - valueIsDeadKey: false, - withShift: '。', - withShiftIsDeadKey: false, - withAltGr: '.', - withAltGrIsDeadKey: false, - withShiftAltGr: '>', - withShiftAltGrIsDeadKey: false - }, - Slash: { - value: 'ㄥ', - valueIsDeadKey: false, - withShift: '?', - withShiftIsDeadKey: false, - withAltGr: '/', - withAltGrIsDeadKey: false, - withShiftAltGr: '?', - withShiftAltGrIsDeadKey: false - }, - CapsLock: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F1: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F2: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F3: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F4: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F5: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F6: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F7: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F8: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F9: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F10: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F11: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F12: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Insert: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Home: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - PageUp: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Delete: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - End: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - PageDown: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowDown: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowUp: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumLock: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumpadDivide: { - value: '/', - valueIsDeadKey: false, - withShift: '/', - withShiftIsDeadKey: false, - withAltGr: '/', - withAltGrIsDeadKey: false, - withShiftAltGr: '/', - withShiftAltGrIsDeadKey: false - }, - NumpadMultiply: { - value: '*', - valueIsDeadKey: false, - withShift: '*', - withShiftIsDeadKey: false, - withAltGr: '*', - withAltGrIsDeadKey: false, - withShiftAltGr: '*', - withShiftAltGrIsDeadKey: false - }, - NumpadSubtract: { - value: '-', - valueIsDeadKey: false, - withShift: '-', - withShiftIsDeadKey: false, - withAltGr: '-', - withAltGrIsDeadKey: false, - withShiftAltGr: '-', - withShiftAltGrIsDeadKey: false - }, - NumpadAdd: { - value: '+', - valueIsDeadKey: false, - withShift: '+', - withShiftIsDeadKey: false, - withAltGr: '+', - withAltGrIsDeadKey: false, - withShiftAltGr: '+', - withShiftAltGrIsDeadKey: false - }, - NumpadEnter: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Numpad1: { - value: '1', - valueIsDeadKey: false, - withShift: '1', - withShiftIsDeadKey: false, - withAltGr: '1', - withAltGrIsDeadKey: false, - withShiftAltGr: '1', - withShiftAltGrIsDeadKey: false - }, - Numpad2: { - value: '2', - valueIsDeadKey: false, - withShift: '2', - withShiftIsDeadKey: false, - withAltGr: '2', - withAltGrIsDeadKey: false, - withShiftAltGr: '2', - withShiftAltGrIsDeadKey: false - }, - Numpad3: { - value: '3', - valueIsDeadKey: false, - withShift: '3', - withShiftIsDeadKey: false, - withAltGr: '3', - withAltGrIsDeadKey: false, - withShiftAltGr: '3', - withShiftAltGrIsDeadKey: false - }, - Numpad4: { - value: '4', - valueIsDeadKey: false, - withShift: '4', - withShiftIsDeadKey: false, - withAltGr: '4', - withAltGrIsDeadKey: false, - withShiftAltGr: '4', - withShiftAltGrIsDeadKey: false - }, - Numpad5: { - value: '5', - valueIsDeadKey: false, - withShift: '5', - withShiftIsDeadKey: false, - withAltGr: '5', - withAltGrIsDeadKey: false, - withShiftAltGr: '5', - withShiftAltGrIsDeadKey: false - }, - Numpad6: { - value: '6', - valueIsDeadKey: false, - withShift: '6', - withShiftIsDeadKey: false, - withAltGr: '6', - withAltGrIsDeadKey: false, - withShiftAltGr: '6', - withShiftAltGrIsDeadKey: false - }, - Numpad7: { - value: '7', - valueIsDeadKey: false, - withShift: '7', - withShiftIsDeadKey: false, - withAltGr: '7', - withAltGrIsDeadKey: false, - withShiftAltGr: '7', - withShiftAltGrIsDeadKey: false - }, - Numpad8: { - value: '8', - valueIsDeadKey: false, - withShift: '8', - withShiftIsDeadKey: false, - withAltGr: '8', - withAltGrIsDeadKey: false, - withShiftAltGr: '8', - withShiftAltGrIsDeadKey: false - }, - Numpad9: { - value: '9', - valueIsDeadKey: false, - withShift: '9', - withShiftIsDeadKey: false, - withAltGr: '9', - withAltGrIsDeadKey: false, - withShiftAltGr: '9', - withShiftAltGrIsDeadKey: false - }, - Numpad0: { - value: '0', - valueIsDeadKey: false, - withShift: '0', - withShiftIsDeadKey: false, - withAltGr: '0', - withAltGrIsDeadKey: false, - withShiftAltGr: '0', - withShiftAltGrIsDeadKey: false - }, - NumpadDecimal: { - value: '.', - valueIsDeadKey: false, - withShift: '.', - withShiftIsDeadKey: false, - withAltGr: '.', - withAltGrIsDeadKey: false, - withShiftAltGr: '.', - withShiftAltGrIsDeadKey: false - }, - IntlBackslash: { - value: '§', - valueIsDeadKey: false, - withShift: '±', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ContextMenu: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumpadEqual: { - value: '=', - valueIsDeadKey: false, - withShift: '=', - withShiftIsDeadKey: false, - withAltGr: '=', - withAltGrIsDeadKey: false, - withShiftAltGr: '=', - withShiftAltGrIsDeadKey: false - }, - F13: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F14: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F15: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F16: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F17: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F18: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F19: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F20: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AudioVolumeMute: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AudioVolumeUp: { - value: '', - valueIsDeadKey: false, - withShift: '=', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '=', - withShiftAltGrIsDeadKey: false - }, - AudioVolumeDown: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumpadComma: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - IntlRo: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - KanaMode: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - IntlYen: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ControlLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ShiftLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AltLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - MetaLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ControlRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ShiftRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AltRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - MetaRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - } -}); diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant.txt b/src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant.txt deleted file mode 100644 index 0d7b9b6bbd6..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant.txt +++ /dev/null @@ -1,507 +0,0 @@ -isUSStandard: false ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyA | ㄇ | A | | A | a | A | [KeyA] | | -| Ctrl+KeyA | ㄇ | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | -| Shift+KeyA | A | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | -| Ctrl+Shift+KeyA | A | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | -| Alt+KeyA | ㄇ | Alt+A | | Option+A | alt+a | Alt+A | alt+[KeyA] | | -| Ctrl+Alt+KeyA | a | Ctrl+Alt+A | | Ctrl+Option+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | -| Shift+Alt+KeyA | A | Shift+Alt+A | | Shift+Option+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | -| Ctrl+Shift+Alt+KeyA | A | Ctrl+Shift+Alt+A | | Ctrl+Shift+Option+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyB | ㄖ | B | | B | b | B | [KeyB] | | -| Ctrl+KeyB | ㄖ | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | -| Shift+KeyB | B | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | -| Ctrl+Shift+KeyB | B | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | -| Alt+KeyB | ㄖ | Alt+B | | Option+B | alt+b | Alt+B | alt+[KeyB] | | -| Ctrl+Alt+KeyB | b | Ctrl+Alt+B | | Ctrl+Option+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | -| Shift+Alt+KeyB | B | Shift+Alt+B | | Shift+Option+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | -| Ctrl+Shift+Alt+KeyB | B | Ctrl+Shift+Alt+B | | Ctrl+Shift+Option+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyC | ㄏ | C | | C | c | C | [KeyC] | | -| Ctrl+KeyC | ㄏ | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | -| Shift+KeyC | C | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | -| Ctrl+Shift+KeyC | C | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | -| Alt+KeyC | ㄏ | Alt+C | | Option+C | alt+c | Alt+C | alt+[KeyC] | | -| Ctrl+Alt+KeyC | c | Ctrl+Alt+C | | Ctrl+Option+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | -| Shift+Alt+KeyC | C | Shift+Alt+C | | Shift+Option+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | -| Ctrl+Shift+Alt+KeyC | C | Ctrl+Shift+Alt+C | | Ctrl+Shift+Option+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyD | ㄎ | D | | D | d | D | [KeyD] | | -| Ctrl+KeyD | ㄎ | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | -| Shift+KeyD | D | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | -| Ctrl+Shift+KeyD | D | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | -| Alt+KeyD | ㄎ | Alt+D | | Option+D | alt+d | Alt+D | alt+[KeyD] | | -| Ctrl+Alt+KeyD | d | Ctrl+Alt+D | | Ctrl+Option+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | -| Shift+Alt+KeyD | D | Shift+Alt+D | | Shift+Option+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | -| Ctrl+Shift+Alt+KeyD | D | Ctrl+Shift+Alt+D | | Ctrl+Shift+Option+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyE | ㄍ | E | | E | e | E | [KeyE] | | -| Ctrl+KeyE | ㄍ | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | -| Shift+KeyE | E | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | -| Ctrl+Shift+KeyE | E | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | -| Alt+KeyE | ㄍ | Alt+E | | Option+E | alt+e | Alt+E | alt+[KeyE] | | -| Ctrl+Alt+KeyE | e | Ctrl+Alt+E | | Ctrl+Option+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | -| Shift+Alt+KeyE | E | Shift+Alt+E | | Shift+Option+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | -| Ctrl+Shift+Alt+KeyE | E | Ctrl+Shift+Alt+E | | Ctrl+Shift+Option+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyF | ㄑ | F | | F | f | F | [KeyF] | | -| Ctrl+KeyF | ㄑ | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | -| Shift+KeyF | F | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | -| Ctrl+Shift+KeyF | F | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | -| Alt+KeyF | ㄑ | Alt+F | | Option+F | alt+f | Alt+F | alt+[KeyF] | | -| Ctrl+Alt+KeyF | f | Ctrl+Alt+F | | Ctrl+Option+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | -| Shift+Alt+KeyF | F | Shift+Alt+F | | Shift+Option+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | -| Ctrl+Shift+Alt+KeyF | F | Ctrl+Shift+Alt+F | | Ctrl+Shift+Option+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyG | ㄕ | G | | G | g | G | [KeyG] | | -| Ctrl+KeyG | ㄕ | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | -| Shift+KeyG | G | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | -| Ctrl+Shift+KeyG | G | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | -| Alt+KeyG | ㄕ | Alt+G | | Option+G | alt+g | Alt+G | alt+[KeyG] | | -| Ctrl+Alt+KeyG | g | Ctrl+Alt+G | | Ctrl+Option+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | -| Shift+Alt+KeyG | G | Shift+Alt+G | | Shift+Option+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | -| Ctrl+Shift+Alt+KeyG | G | Ctrl+Shift+Alt+G | | Ctrl+Shift+Option+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyH | ㄘ | H | | H | h | H | [KeyH] | | -| Ctrl+KeyH | ㄘ | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | -| Shift+KeyH | H | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | -| Ctrl+Shift+KeyH | H | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | -| Alt+KeyH | ㄘ | Alt+H | | Option+H | alt+h | Alt+H | alt+[KeyH] | | -| Ctrl+Alt+KeyH | h | Ctrl+Alt+H | | Ctrl+Option+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | -| Shift+Alt+KeyH | H | Shift+Alt+H | | Shift+Option+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | -| Ctrl+Shift+Alt+KeyH | H | Ctrl+Shift+Alt+H | | Ctrl+Shift+Option+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyI | ㄛ | I | | I | i | I | [KeyI] | | -| Ctrl+KeyI | ㄛ | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | -| Shift+KeyI | I | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | -| Ctrl+Shift+KeyI | I | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | -| Alt+KeyI | ㄛ | Alt+I | | Option+I | alt+i | Alt+I | alt+[KeyI] | | -| Ctrl+Alt+KeyI | i | Ctrl+Alt+I | | Ctrl+Option+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | -| Shift+Alt+KeyI | I | Shift+Alt+I | | Shift+Option+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | -| Ctrl+Shift+Alt+KeyI | I | Ctrl+Shift+Alt+I | | Ctrl+Shift+Option+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyJ | ㄨ | J | | J | j | J | [KeyJ] | | -| Ctrl+KeyJ | ㄨ | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | -| Shift+KeyJ | J | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | -| Ctrl+Shift+KeyJ | J | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | -| Alt+KeyJ | ㄨ | Alt+J | | Option+J | alt+j | Alt+J | alt+[KeyJ] | | -| Ctrl+Alt+KeyJ | j | Ctrl+Alt+J | | Ctrl+Option+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | -| Shift+Alt+KeyJ | J | Shift+Alt+J | | Shift+Option+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | -| Ctrl+Shift+Alt+KeyJ | J | Ctrl+Shift+Alt+J | | Ctrl+Shift+Option+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyK | ㄜ | K | | K | k | K | [KeyK] | | -| Ctrl+KeyK | ㄜ | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | -| Shift+KeyK | K | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | -| Ctrl+Shift+KeyK | K | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | -| Alt+KeyK | ㄜ | Alt+K | | Option+K | alt+k | Alt+K | alt+[KeyK] | | -| Ctrl+Alt+KeyK | k | Ctrl+Alt+K | | Ctrl+Option+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | -| Shift+Alt+KeyK | K | Shift+Alt+K | | Shift+Option+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | -| Ctrl+Shift+Alt+KeyK | K | Ctrl+Shift+Alt+K | | Ctrl+Shift+Option+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyL | ㄠ | L | | L | l | L | [KeyL] | | -| Ctrl+KeyL | ㄠ | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | -| Shift+KeyL | L | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | -| Ctrl+Shift+KeyL | L | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | -| Alt+KeyL | ㄠ | Alt+L | | Option+L | alt+l | Alt+L | alt+[KeyL] | | -| Ctrl+Alt+KeyL | l | Ctrl+Alt+L | | Ctrl+Option+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | -| Shift+Alt+KeyL | L | Shift+Alt+L | | Shift+Option+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | -| Ctrl+Shift+Alt+KeyL | L | Ctrl+Shift+Alt+L | | Ctrl+Shift+Option+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyM | ㄩ | M | | M | m | M | [KeyM] | | -| Ctrl+KeyM | ㄩ | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | -| Shift+KeyM | M | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | -| Ctrl+Shift+KeyM | M | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | -| Alt+KeyM | ㄩ | Alt+M | | Option+M | alt+m | Alt+M | alt+[KeyM] | | -| Ctrl+Alt+KeyM | m | Ctrl+Alt+M | | Ctrl+Option+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | -| Shift+Alt+KeyM | M | Shift+Alt+M | | Shift+Option+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | -| Ctrl+Shift+Alt+KeyM | M | Ctrl+Shift+Alt+M | | Ctrl+Shift+Option+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyN | ㄙ | N | | N | n | N | [KeyN] | | -| Ctrl+KeyN | ㄙ | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | -| Shift+KeyN | N | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | -| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | -| Alt+KeyN | ㄙ | Alt+N | | Option+N | alt+n | Alt+N | alt+[KeyN] | | -| Ctrl+Alt+KeyN | n | Ctrl+Alt+N | | Ctrl+Option+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | -| Shift+Alt+KeyN | N | Shift+Alt+N | | Shift+Option+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | -| Ctrl+Shift+Alt+KeyN | N | Ctrl+Shift+Alt+N | | Ctrl+Shift+Option+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyO | ㄟ | O | | O | o | O | [KeyO] | | -| Ctrl+KeyO | ㄟ | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | -| Shift+KeyO | O | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | -| Ctrl+Shift+KeyO | O | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | -| Alt+KeyO | ㄟ | Alt+O | | Option+O | alt+o | Alt+O | alt+[KeyO] | | -| Ctrl+Alt+KeyO | o | Ctrl+Alt+O | | Ctrl+Option+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | -| Shift+Alt+KeyO | O | Shift+Alt+O | | Shift+Option+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | -| Ctrl+Shift+Alt+KeyO | O | Ctrl+Shift+Alt+O | | Ctrl+Shift+Option+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyP | ㄣ | P | | P | p | P | [KeyP] | | -| Ctrl+KeyP | ㄣ | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | -| Shift+KeyP | P | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | -| Ctrl+Shift+KeyP | P | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | -| Alt+KeyP | ㄣ | Alt+P | | Option+P | alt+p | Alt+P | alt+[KeyP] | | -| Ctrl+Alt+KeyP | p | Ctrl+Alt+P | | Ctrl+Option+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | -| Shift+Alt+KeyP | P | Shift+Alt+P | | Shift+Option+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | -| Ctrl+Shift+Alt+KeyP | P | Ctrl+Shift+Alt+P | | Ctrl+Shift+Option+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyQ | ㄆ | Q | | Q | q | Q | [KeyQ] | | -| Ctrl+KeyQ | ㄆ | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | -| Shift+KeyQ | Q | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | -| Ctrl+Shift+KeyQ | Q | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | -| Alt+KeyQ | ㄆ | Alt+Q | | Option+Q | alt+q | Alt+Q | alt+[KeyQ] | | -| Ctrl+Alt+KeyQ | q | Ctrl+Alt+Q | | Ctrl+Option+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | -| Shift+Alt+KeyQ | Q | Shift+Alt+Q | | Shift+Option+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | -| Ctrl+Shift+Alt+KeyQ | Q | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Option+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyR | ㄐ | R | | R | r | R | [KeyR] | | -| Ctrl+KeyR | ㄐ | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | -| Shift+KeyR | R | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | -| Ctrl+Shift+KeyR | R | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | -| Alt+KeyR | ㄐ | Alt+R | | Option+R | alt+r | Alt+R | alt+[KeyR] | | -| Ctrl+Alt+KeyR | r | Ctrl+Alt+R | | Ctrl+Option+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | -| Shift+Alt+KeyR | R | Shift+Alt+R | | Shift+Option+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | -| Ctrl+Shift+Alt+KeyR | R | Ctrl+Shift+Alt+R | | Ctrl+Shift+Option+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyS | ㄋ | S | | S | s | S | [KeyS] | | -| Ctrl+KeyS | ㄋ | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | -| Shift+KeyS | S | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | -| Ctrl+Shift+KeyS | S | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | -| Alt+KeyS | ㄋ | Alt+S | | Option+S | alt+s | Alt+S | alt+[KeyS] | | -| Ctrl+Alt+KeyS | s | Ctrl+Alt+S | | Ctrl+Option+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | -| Shift+Alt+KeyS | S | Shift+Alt+S | | Shift+Option+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | -| Ctrl+Shift+Alt+KeyS | S | Ctrl+Shift+Alt+S | | Ctrl+Shift+Option+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyT | ㄔ | T | | T | t | T | [KeyT] | | -| Ctrl+KeyT | ㄔ | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | -| Shift+KeyT | T | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | -| Ctrl+Shift+KeyT | T | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | -| Alt+KeyT | ㄔ | Alt+T | | Option+T | alt+t | Alt+T | alt+[KeyT] | | -| Ctrl+Alt+KeyT | t | Ctrl+Alt+T | | Ctrl+Option+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | -| Shift+Alt+KeyT | T | Shift+Alt+T | | Shift+Option+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | -| Ctrl+Shift+Alt+KeyT | T | Ctrl+Shift+Alt+T | | Ctrl+Shift+Option+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyU | ㄧ | U | | U | u | U | [KeyU] | | -| Ctrl+KeyU | ㄧ | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | -| Shift+KeyU | U | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | -| Ctrl+Shift+KeyU | U | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | -| Alt+KeyU | ㄧ | Alt+U | | Option+U | alt+u | Alt+U | alt+[KeyU] | | -| Ctrl+Alt+KeyU | u | Ctrl+Alt+U | | Ctrl+Option+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | -| Shift+Alt+KeyU | U | Shift+Alt+U | | Shift+Option+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | -| Ctrl+Shift+Alt+KeyU | U | Ctrl+Shift+Alt+U | | Ctrl+Shift+Option+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyV | ㄒ | V | | V | v | V | [KeyV] | | -| Ctrl+KeyV | ㄒ | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | -| Shift+KeyV | V | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | -| Ctrl+Shift+KeyV | V | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | -| Alt+KeyV | ㄒ | Alt+V | | Option+V | alt+v | Alt+V | alt+[KeyV] | | -| Ctrl+Alt+KeyV | v | Ctrl+Alt+V | | Ctrl+Option+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | -| Shift+Alt+KeyV | V | Shift+Alt+V | | Shift+Option+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | -| Ctrl+Shift+Alt+KeyV | V | Ctrl+Shift+Alt+V | | Ctrl+Shift+Option+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyW | ㄊ | W | | W | w | W | [KeyW] | | -| Ctrl+KeyW | ㄊ | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | -| Shift+KeyW | W | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | -| Ctrl+Shift+KeyW | W | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | -| Alt+KeyW | ㄊ | Alt+W | | Option+W | alt+w | Alt+W | alt+[KeyW] | | -| Ctrl+Alt+KeyW | w | Ctrl+Alt+W | | Ctrl+Option+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | -| Shift+Alt+KeyW | W | Shift+Alt+W | | Shift+Option+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | -| Ctrl+Shift+Alt+KeyW | W | Ctrl+Shift+Alt+W | | Ctrl+Shift+Option+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyX | ㄌ | X | | X | x | X | [KeyX] | | -| Ctrl+KeyX | ㄌ | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | -| Shift+KeyX | X | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | -| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | -| Alt+KeyX | ㄌ | Alt+X | | Option+X | alt+x | Alt+X | alt+[KeyX] | | -| Ctrl+Alt+KeyX | x | Ctrl+Alt+X | | Ctrl+Option+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | -| Shift+Alt+KeyX | X | Shift+Alt+X | | Shift+Option+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | -| Ctrl+Shift+Alt+KeyX | X | Ctrl+Shift+Alt+X | | Ctrl+Shift+Option+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyY | ㄗ | Y | | Y | y | Y | [KeyY] | | -| Ctrl+KeyY | ㄗ | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyY] | | -| Shift+KeyY | Y | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyY] | | -| Ctrl+Shift+KeyY | Y | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyY] | | -| Alt+KeyY | ㄗ | Alt+Y | | Option+Y | alt+y | Alt+Y | alt+[KeyY] | | -| Ctrl+Alt+KeyY | y | Ctrl+Alt+Y | | Ctrl+Option+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyY] | | -| Shift+Alt+KeyY | Y | Shift+Alt+Y | | Shift+Option+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyY] | | -| Ctrl+Shift+Alt+KeyY | Y | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Option+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyY] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyZ | ㄈ | Z | | Z | z | Z | [KeyZ] | | -| Ctrl+KeyZ | ㄈ | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyZ] | | -| Shift+KeyZ | Z | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyZ] | | -| Ctrl+Shift+KeyZ | Z | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyZ] | | -| Alt+KeyZ | ㄈ | Alt+Z | | Option+Z | alt+z | Alt+Z | alt+[KeyZ] | | -| Ctrl+Alt+KeyZ | z | Ctrl+Alt+Z | | Ctrl+Option+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyZ] | | -| Shift+Alt+KeyZ | Z | Shift+Alt+Z | | Shift+Option+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyZ] | | -| Ctrl+Shift+Alt+KeyZ | Z | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Option+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyZ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit1 | ㄅ | 1 | | ㄅ | 1 | 1 | [Digit1] | NO | -| Ctrl+Digit1 | ㄅ | Ctrl+1 | | Ctrl+ㄅ | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | NO | -| Shift+Digit1 | ! | Shift+1 | | Shift+ㄅ | shift+1 | Shift+1 | shift+[Digit1] | NO | -| Ctrl+Shift+Digit1 | ! | Ctrl+Shift+1 | | Ctrl+Shift+ㄅ | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | NO | -| Alt+Digit1 | ㄅ | Alt+1 | | Option+ㄅ | alt+1 | Alt+1 | alt+[Digit1] | NO | -| Ctrl+Alt+Digit1 | 1 | Ctrl+Alt+1 | | Ctrl+Option+ㄅ | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | NO | -| Shift+Alt+Digit1 | ! | Shift+Alt+1 | | Shift+Option+ㄅ | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | NO | -| Ctrl+Shift+Alt+Digit1 | ! | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Option+ㄅ | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit2 | ㄉ | 2 | | ㄉ | 2 | 2 | [Digit2] | NO | -| Ctrl+Digit2 | ㄉ | Ctrl+2 | | Ctrl+ㄉ | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | NO | -| Shift+Digit2 | @ | Shift+2 | | Shift+ㄉ | shift+2 | Shift+2 | shift+[Digit2] | NO | -| Ctrl+Shift+Digit2 | @ | Ctrl+Shift+2 | | Ctrl+Shift+ㄉ | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | NO | -| Alt+Digit2 | ㄉ | Alt+2 | | Option+ㄉ | alt+2 | Alt+2 | alt+[Digit2] | NO | -| Ctrl+Alt+Digit2 | 2 | Ctrl+Alt+2 | | Ctrl+Option+ㄉ | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | NO | -| Shift+Alt+Digit2 | @ | Shift+Alt+2 | | Shift+Option+ㄉ | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | NO | -| Ctrl+Shift+Alt+Digit2 | @ | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Option+ㄉ | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit3 | ˇ | 3 | | ˇ | 3 | 3 | [Digit3] | NO | -| Ctrl+Digit3 | ˇ | Ctrl+3 | | Ctrl+ˇ | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | NO | -| Shift+Digit3 | # | Shift+3 | | Shift+ˇ | shift+3 | Shift+3 | shift+[Digit3] | NO | -| Ctrl+Shift+Digit3 | # | Ctrl+Shift+3 | | Ctrl+Shift+ˇ | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | NO | -| Alt+Digit3 | ˇ | Alt+3 | | Option+ˇ | alt+3 | Alt+3 | alt+[Digit3] | NO | -| Ctrl+Alt+Digit3 | 3 | Ctrl+Alt+3 | | Ctrl+Option+ˇ | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | NO | -| Shift+Alt+Digit3 | # | Shift+Alt+3 | | Shift+Option+ˇ | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | NO | -| Ctrl+Shift+Alt+Digit3 | # | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Option+ˇ | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit4 | ˋ | 4 | | ˋ | 4 | 4 | [Digit4] | NO | -| Ctrl+Digit4 | ˋ | Ctrl+4 | | Ctrl+ˋ | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | NO | -| Shift+Digit4 | $ | Shift+4 | | Shift+ˋ | shift+4 | Shift+4 | shift+[Digit4] | NO | -| Ctrl+Shift+Digit4 | $ | Ctrl+Shift+4 | | Ctrl+Shift+ˋ | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | NO | -| Alt+Digit4 | ˋ | Alt+4 | | Option+ˋ | alt+4 | Alt+4 | alt+[Digit4] | NO | -| Ctrl+Alt+Digit4 | 4 | Ctrl+Alt+4 | | Ctrl+Option+ˋ | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | NO | -| Shift+Alt+Digit4 | $ | Shift+Alt+4 | | Shift+Option+ˋ | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | NO | -| Ctrl+Shift+Alt+Digit4 | $ | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Option+ˋ | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit5 | ㄓ | 5 | | ㄓ | 5 | 5 | [Digit5] | NO | -| Ctrl+Digit5 | ㄓ | Ctrl+5 | | Ctrl+ㄓ | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | NO | -| Shift+Digit5 | % | Shift+5 | | Shift+ㄓ | shift+5 | Shift+5 | shift+[Digit5] | NO | -| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+ㄓ | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | NO | -| Alt+Digit5 | ㄓ | Alt+5 | | Option+ㄓ | alt+5 | Alt+5 | alt+[Digit5] | NO | -| Ctrl+Alt+Digit5 | 5 | Ctrl+Alt+5 | | Ctrl+Option+ㄓ | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | NO | -| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Option+ㄓ | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | NO | -| Ctrl+Shift+Alt+Digit5 | % | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Option+ㄓ | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit6 | ˊ | 6 | | ˊ | 6 | 6 | [Digit6] | NO | -| Ctrl+Digit6 | ˊ | Ctrl+6 | | Ctrl+ˊ | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | NO | -| Shift+Digit6 | ^ | Shift+6 | | Shift+ˊ | shift+6 | Shift+6 | shift+[Digit6] | NO | -| Ctrl+Shift+Digit6 | ^ | Ctrl+Shift+6 | | Ctrl+Shift+ˊ | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | NO | -| Alt+Digit6 | ˊ | Alt+6 | | Option+ˊ | alt+6 | Alt+6 | alt+[Digit6] | NO | -| Ctrl+Alt+Digit6 | 6 | Ctrl+Alt+6 | | Ctrl+Option+ˊ | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | NO | -| Shift+Alt+Digit6 | ^ | Shift+Alt+6 | | Shift+Option+ˊ | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | NO | -| Ctrl+Shift+Alt+Digit6 | ^ | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Option+ˊ | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit7 | ˙ | 7 | | ˙ | 7 | 7 | [Digit7] | NO | -| Ctrl+Digit7 | ˙ | Ctrl+7 | | Ctrl+˙ | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | NO | -| Shift+Digit7 | & | Shift+7 | | Shift+˙ | shift+7 | Shift+7 | shift+[Digit7] | NO | -| Ctrl+Shift+Digit7 | & | Ctrl+Shift+7 | | Ctrl+Shift+˙ | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | NO | -| Alt+Digit7 | ˙ | Alt+7 | | Option+˙ | alt+7 | Alt+7 | alt+[Digit7] | NO | -| Ctrl+Alt+Digit7 | 7 | Ctrl+Alt+7 | | Ctrl+Option+˙ | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | NO | -| Shift+Alt+Digit7 | & | Shift+Alt+7 | | Shift+Option+˙ | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | NO | -| Ctrl+Shift+Alt+Digit7 | & | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Option+˙ | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit8 | ㄚ | 8 | | ㄚ | 8 | 8 | [Digit8] | NO | -| Ctrl+Digit8 | ㄚ | Ctrl+8 | | Ctrl+ㄚ | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | NO | -| Shift+Digit8 | * | Shift+8 | | Shift+ㄚ | shift+8 | Shift+8 | shift+[Digit8] | NO | -| Ctrl+Shift+Digit8 | * | Ctrl+Shift+8 | | Ctrl+Shift+ㄚ | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | NO | -| Alt+Digit8 | ㄚ | Alt+8 | | Option+ㄚ | alt+8 | Alt+8 | alt+[Digit8] | NO | -| Ctrl+Alt+Digit8 | 8 | Ctrl+Alt+8 | | Ctrl+Option+ㄚ | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | NO | -| Shift+Alt+Digit8 | * | Shift+Alt+8 | | Shift+Option+ㄚ | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | NO | -| Ctrl+Shift+Alt+Digit8 | * | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Option+ㄚ | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit9 | ㄞ | 9 | | ㄞ | 9 | 9 | [Digit9] | NO | -| Ctrl+Digit9 | ㄞ | Ctrl+9 | | Ctrl+ㄞ | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | NO | -| Shift+Digit9 | ( | Shift+9 | | Shift+ㄞ | shift+9 | Shift+9 | shift+[Digit9] | NO | -| Ctrl+Shift+Digit9 | ( | Ctrl+Shift+9 | | Ctrl+Shift+ㄞ | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | NO | -| Alt+Digit9 | ㄞ | Alt+9 | | Option+ㄞ | alt+9 | Alt+9 | alt+[Digit9] | NO | -| Ctrl+Alt+Digit9 | 9 | Ctrl+Alt+9 | | Ctrl+Option+ㄞ | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | NO | -| Shift+Alt+Digit9 | ( | Shift+Alt+9 | | Shift+Option+ㄞ | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | NO | -| Ctrl+Shift+Alt+Digit9 | ( | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Option+ㄞ | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit0 | ㄢ | 0 | | ㄢ | 0 | 0 | [Digit0] | NO | -| Ctrl+Digit0 | ㄢ | Ctrl+0 | | Ctrl+ㄢ | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | NO | -| Shift+Digit0 | ) | Shift+0 | | Shift+ㄢ | shift+0 | Shift+0 | shift+[Digit0] | NO | -| Ctrl+Shift+Digit0 | ) | Ctrl+Shift+0 | | Ctrl+Shift+ㄢ | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | NO | -| Alt+Digit0 | ㄢ | Alt+0 | | Option+ㄢ | alt+0 | Alt+0 | alt+[Digit0] | NO | -| Ctrl+Alt+Digit0 | 0 | Ctrl+Alt+0 | | Ctrl+Option+ㄢ | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | NO | -| Shift+Alt+Digit0 | ) | Shift+Alt+0 | | Shift+Option+ㄢ | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | NO | -| Ctrl+Shift+Alt+Digit0 | ) | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Option+ㄢ | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Minus | ㄦ | | | ㄦ | [Minus] | null | [Minus] | NO | -| Ctrl+Minus | ㄦ | | | Ctrl+ㄦ | ctrl+[Minus] | null | ctrl+[Minus] | NO | -| Shift+Minus | _ | Shift+- | | Shift+ㄦ | shift+[Minus] | null | shift+[Minus] | NO | -| Ctrl+Shift+Minus | _ | Ctrl+Shift+- | | Ctrl+Shift+ㄦ | ctrl+shift+[Minus] | null | ctrl+shift+[Minus] | NO | -| Alt+Minus | ㄦ | | | Option+ㄦ | alt+[Minus] | null | alt+[Minus] | NO | -| Ctrl+Alt+Minus | — | | | Ctrl+Option+ㄦ | ctrl+alt+[Minus] | null | ctrl+alt+[Minus] | NO | -| Shift+Alt+Minus | _ | Shift+Alt+- | | Shift+Option+ㄦ | shift+alt+[Minus] | null | shift+alt+[Minus] | NO | -| Ctrl+Shift+Alt+Minus | _ | Ctrl+Shift+Alt+- | | Ctrl+Shift+Option+ㄦ | ctrl+shift+alt+[Minus] | null | ctrl+shift+alt+[Minus] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Equal | = | = | | = | = | = | [Equal] | | -| Ctrl+Equal | = | Ctrl+= | | Ctrl+= | ctrl+= | Ctrl+= | ctrl+[Equal] | | -| Shift+Equal | + | Shift+= | | Shift+= | shift+= | Shift+= | shift+[Equal] | | -| Ctrl+Shift+Equal | + | Ctrl+Shift+= | | Ctrl+Shift+= | ctrl+shift+= | Ctrl+Shift+= | ctrl+shift+[Equal] | | -| Alt+Equal | = | Alt+= | | Option+= | alt+= | Alt+= | alt+[Equal] | | -| Ctrl+Alt+Equal | = | Ctrl+Alt+= | | Ctrl+Option+= | ctrl+alt+= | Ctrl+Alt+= | ctrl+alt+[Equal] | | -| Shift+Alt+Equal | + | Shift+Alt+= | | Shift+Option+= | shift+alt+= | Shift+Alt+= | shift+alt+[Equal] | | -| Ctrl+Shift+Alt+Equal | + | Ctrl+Shift+Alt+= | | Ctrl+Shift+Option+= | ctrl+shift+alt+= | Ctrl+Shift+Alt+= | ctrl+shift+alt+[Equal] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketLeft | 「 | [ | 1 | 「 | [ | [ | [BracketLeft] | NO | -| Ctrl+BracketLeft | 「 | Ctrl+[ | | Ctrl+「 | ctrl+[ | Ctrl+[ | ctrl+[BracketLeft] | NO | -| Shift+BracketLeft | 『 | Shift+[ | 1 | Shift+「 | shift+[ | Shift+[ | shift+[BracketLeft] | NO | -| Ctrl+Shift+BracketLeft | 『 | Ctrl+Shift+[ | | Ctrl+Shift+「 | ctrl+shift+[ | Ctrl+Shift+[ | ctrl+shift+[BracketLeft] | NO | -| Alt+BracketLeft | 「 | Alt+[ | | Option+「 | alt+[ | Alt+[ | alt+[BracketLeft] | NO | -| Ctrl+Alt+BracketLeft | [ | [ | 2 | Ctrl+Option+「 | ctrl+alt+[BracketLeft] | Ctrl+Alt+[ | ctrl+alt+[BracketLeft] | NO | -| Shift+Alt+BracketLeft | 『 | Shift+Alt+[ | | Shift+Option+「 | shift+alt+[ | Shift+Alt+[ | shift+alt+[BracketLeft] | NO | -| Ctrl+Shift+Alt+BracketLeft | { | Shift+[ | 2 | Ctrl+Shift+Option+「 | ctrl+shift+alt+[BracketLeft] | Ctrl+Shift+Alt+[ | ctrl+shift+alt+[BracketLeft] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketRight | 」 | ] | 1 | 」 | ] | ] | [BracketRight] | NO | -| Ctrl+BracketRight | 」 | Ctrl+] | | Ctrl+」 | ctrl+] | Ctrl+] | ctrl+[BracketRight] | NO | -| Shift+BracketRight | 』 | Shift+] | 1 | Shift+」 | shift+] | Shift+] | shift+[BracketRight] | NO | -| Ctrl+Shift+BracketRight | 』 | Ctrl+Shift+] | | Ctrl+Shift+」 | ctrl+shift+] | Ctrl+Shift+] | ctrl+shift+[BracketRight] | NO | -| Alt+BracketRight | 」 | Alt+] | | Option+」 | alt+] | Alt+] | alt+[BracketRight] | NO | -| Ctrl+Alt+BracketRight | ] | ] | 2 | Ctrl+Option+」 | ctrl+alt+[BracketRight] | Ctrl+Alt+] | ctrl+alt+[BracketRight] | NO | -| Shift+Alt+BracketRight | 』 | Shift+Alt+] | | Shift+Option+」 | shift+alt+] | Shift+Alt+] | shift+alt+[BracketRight] | NO | -| Ctrl+Shift+Alt+BracketRight | } | Shift+] | 2 | Ctrl+Shift+Option+」 | ctrl+shift+alt+[BracketRight] | Ctrl+Shift+Alt+] | ctrl+shift+alt+[BracketRight] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backslash | 、 | | | 、 | [Backslash] | null | [Backslash] | NO | -| Ctrl+Backslash | 、 | | | Ctrl+、 | ctrl+[Backslash] | null | ctrl+[Backslash] | NO | -| Shift+Backslash | | | Shift+\ | | Shift+、 | shift+[Backslash] | null | shift+[Backslash] | NO | -| Ctrl+Shift+Backslash | | | Ctrl+Shift+\ | | Ctrl+Shift+、 | ctrl+shift+[Backslash] | null | ctrl+shift+[Backslash] | NO | -| Alt+Backslash | 、 | | | Option+、 | alt+[Backslash] | null | alt+[Backslash] | NO | -| Ctrl+Alt+Backslash | \ | \ | | Ctrl+Option+、 | ctrl+alt+[Backslash] | null | ctrl+alt+[Backslash] | NO | -| Shift+Alt+Backslash | | | Shift+Alt+\ | | Shift+Option+、 | shift+alt+[Backslash] | null | shift+alt+[Backslash] | NO | -| Ctrl+Shift+Alt+Backslash | | | Ctrl+Shift+Alt+\ | | Ctrl+Shift+Option+、 | ctrl+shift+alt+[Backslash] | null | ctrl+shift+alt+[Backslash] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlHash | --- | | | null | null | null | null | | -| Ctrl+IntlHash | --- | | | null | null | null | null | | -| Shift+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | -| Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | -| Shift+Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Semicolon | ㄤ | | | ㄤ | [Semicolon] | null | [Semicolon] | NO | -| Ctrl+Semicolon | ㄤ | | | Ctrl+ㄤ | ctrl+[Semicolon] | null | ctrl+[Semicolon] | NO | -| Shift+Semicolon | : | Shift+; | | Shift+ㄤ | shift+[Semicolon] | null | shift+[Semicolon] | NO | -| Ctrl+Shift+Semicolon | : | Ctrl+Shift+; | | Ctrl+Shift+ㄤ | ctrl+shift+[Semicolon] | null | ctrl+shift+[Semicolon] | NO | -| Alt+Semicolon | ㄤ | | | Option+ㄤ | alt+[Semicolon] | null | alt+[Semicolon] | NO | -| Ctrl+Alt+Semicolon | ; | ; | | Ctrl+Option+ㄤ | ctrl+alt+[Semicolon] | null | ctrl+alt+[Semicolon] | NO | -| Shift+Alt+Semicolon | : | Shift+Alt+; | | Shift+Option+ㄤ | shift+alt+[Semicolon] | null | shift+alt+[Semicolon] | NO | -| Ctrl+Shift+Alt+Semicolon | : | Ctrl+Shift+Alt+; | | Ctrl+Shift+Option+ㄤ | ctrl+shift+alt+[Semicolon] | null | ctrl+shift+alt+[Semicolon] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Quote | ' | ' | | ' | ' | ' | [Quote] | | -| Ctrl+Quote | ' | Ctrl+' | | Ctrl+' | ctrl+' | Ctrl+' | ctrl+[Quote] | | -| Shift+Quote | " | Shift+' | | Shift+' | shift+' | Shift+' | shift+[Quote] | | -| Ctrl+Shift+Quote | " | Ctrl+Shift+' | | Ctrl+Shift+' | ctrl+shift+' | Ctrl+Shift+' | ctrl+shift+[Quote] | | -| Alt+Quote | ' | Alt+' | | Option+' | alt+' | Alt+' | alt+[Quote] | | -| Ctrl+Alt+Quote | ' | Ctrl+Alt+' | | Ctrl+Option+' | ctrl+alt+' | Ctrl+Alt+' | ctrl+alt+[Quote] | | -| Shift+Alt+Quote | " | Shift+Alt+' | | Shift+Option+' | shift+alt+' | Shift+Alt+' | shift+alt+[Quote] | | -| Ctrl+Shift+Alt+Quote | " | Ctrl+Shift+Alt+' | | Ctrl+Shift+Option+' | ctrl+shift+alt+' | Ctrl+Shift+Alt+' | ctrl+shift+alt+[Quote] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backquote | · | | | · | [Backquote] | null | [Backquote] | NO | -| Ctrl+Backquote | · | | | Ctrl+· | ctrl+[Backquote] | null | ctrl+[Backquote] | NO | -| Shift+Backquote | ~ | Shift+` | | Shift+· | shift+[Backquote] | null | shift+[Backquote] | NO | -| Ctrl+Shift+Backquote | ~ | Ctrl+Shift+` | | Ctrl+Shift+· | ctrl+shift+[Backquote] | null | ctrl+shift+[Backquote] | NO | -| Alt+Backquote | · | | | Option+· | alt+[Backquote] | null | alt+[Backquote] | NO | -| Ctrl+Alt+Backquote | ` | ` | | Ctrl+Option+· | ctrl+alt+[Backquote] | null | ctrl+alt+[Backquote] | NO | -| Shift+Alt+Backquote | ~ | Shift+Alt+` | | Shift+Option+· | shift+alt+[Backquote] | null | shift+alt+[Backquote] | NO | -| Ctrl+Shift+Alt+Backquote | ~ | Ctrl+Shift+Alt+` | | Ctrl+Shift+Option+· | ctrl+shift+alt+[Backquote] | null | ctrl+shift+alt+[Backquote] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Comma | ㄝ | | | ㄝ | [Comma] | null | [Comma] | NO | -| Ctrl+Comma | ㄝ | | | Ctrl+ㄝ | ctrl+[Comma] | null | ctrl+[Comma] | NO | -| Shift+Comma | , | , | 1 | Shift+ㄝ | shift+[Comma] | null | shift+[Comma] | NO | -| Ctrl+Shift+Comma | , | Ctrl+, | | Ctrl+Shift+ㄝ | ctrl+shift+[Comma] | null | ctrl+shift+[Comma] | NO | -| Alt+Comma | ㄝ | | | Option+ㄝ | alt+[Comma] | null | alt+[Comma] | NO | -| Ctrl+Alt+Comma | , | , | 2 | Ctrl+Option+ㄝ | ctrl+alt+[Comma] | null | ctrl+alt+[Comma] | NO | -| Shift+Alt+Comma | , | Alt+, | | Shift+Option+ㄝ | shift+alt+[Comma] | null | shift+alt+[Comma] | NO | -| Ctrl+Shift+Alt+Comma | < | Shift+, | | Ctrl+Shift+Option+ㄝ | ctrl+shift+alt+[Comma] | null | ctrl+shift+alt+[Comma] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Period | ㄡ | | | ㄡ | [Period] | null | [Period] | NO | -| Ctrl+Period | ㄡ | | | Ctrl+ㄡ | ctrl+[Period] | null | ctrl+[Period] | NO | -| Shift+Period | 。 | . | 1 | Shift+ㄡ | shift+[Period] | null | shift+[Period] | NO | -| Ctrl+Shift+Period | 。 | Ctrl+. | | Ctrl+Shift+ㄡ | ctrl+shift+[Period] | null | ctrl+shift+[Period] | NO | -| Alt+Period | ㄡ | | | Option+ㄡ | alt+[Period] | null | alt+[Period] | NO | -| Ctrl+Alt+Period | . | . | 2 | Ctrl+Option+ㄡ | ctrl+alt+[Period] | null | ctrl+alt+[Period] | NO | -| Shift+Alt+Period | 。 | Alt+. | | Shift+Option+ㄡ | shift+alt+[Period] | null | shift+alt+[Period] | NO | -| Ctrl+Shift+Alt+Period | > | Shift+. | | Ctrl+Shift+Option+ㄡ | ctrl+shift+alt+[Period] | null | ctrl+shift+alt+[Period] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Slash | ㄥ | | | ㄥ | [Slash] | null | [Slash] | NO | -| Ctrl+Slash | ㄥ | | | Ctrl+ㄥ | ctrl+[Slash] | null | ctrl+[Slash] | NO | -| Shift+Slash | ? | Shift+/ | | Shift+ㄥ | shift+[Slash] | null | shift+[Slash] | NO | -| Ctrl+Shift+Slash | ? | Ctrl+Shift+/ | | Ctrl+Shift+ㄥ | ctrl+shift+[Slash] | null | ctrl+shift+[Slash] | NO | -| Alt+Slash | ㄥ | | | Option+ㄥ | alt+[Slash] | null | alt+[Slash] | NO | -| Ctrl+Alt+Slash | / | / | | Ctrl+Option+ㄥ | ctrl+alt+[Slash] | null | ctrl+alt+[Slash] | NO | -| Shift+Alt+Slash | ? | Shift+Alt+/ | | Shift+Option+ㄥ | shift+alt+[Slash] | null | shift+alt+[Slash] | NO | -| Ctrl+Shift+Alt+Slash | ? | Ctrl+Shift+Alt+/ | | Ctrl+Shift+Option+ㄥ | ctrl+shift+alt+[Slash] | null | ctrl+shift+alt+[Slash] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | -| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | -| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | -| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | -| Alt+ArrowUp | --- | Alt+UpArrow | | Option+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | -| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Option+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | -| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Option+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | -| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Option+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | -| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | -| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | -| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | -| Alt+Numpad0 | --- | Alt+NumPad0 | | Option+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | -| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Option+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | -| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Option+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | -| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Option+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlBackslash | § | | | § | [IntlBackslash] | null | [IntlBackslash] | NO | -| Ctrl+IntlBackslash | § | | | Ctrl+§ | ctrl+[IntlBackslash] | null | ctrl+[IntlBackslash] | NO | -| Shift+IntlBackslash | ± | | | Shift+§ | shift+[IntlBackslash] | null | shift+[IntlBackslash] | NO | -| Ctrl+Shift+IntlBackslash | ± | | | Ctrl+Shift+§ | ctrl+shift+[IntlBackslash] | null | ctrl+shift+[IntlBackslash] | NO | -| Alt+IntlBackslash | § | | | Option+§ | alt+[IntlBackslash] | null | alt+[IntlBackslash] | NO | -| Ctrl+Alt+IntlBackslash | --- | | | Ctrl+Option+§ | ctrl+alt+[IntlBackslash] | null | ctrl+alt+[IntlBackslash] | NO | -| Shift+Alt+IntlBackslash | ± | | | Shift+Option+§ | shift+alt+[IntlBackslash] | null | shift+alt+[IntlBackslash] | NO | -| Ctrl+Shift+Alt+IntlBackslash | --- | | | Ctrl+Shift+Option+§ | ctrl+shift+alt+[IntlBackslash] | null | ctrl+shift+alt+[IntlBackslash] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | -| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | -| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | -| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | -| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | -| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | -| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | -| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | -| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | -| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | -| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | -| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | -| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | -| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | -| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant2.js b/src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant2.js deleted file mode 100644 index 5ad77d35f34..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant2.js +++ /dev/null @@ -1,1188 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -define({ - KeyA: { - value: 'a', - valueIsDeadKey: false, - withShift: 'A', - withShiftIsDeadKey: false, - withAltGr: 'å', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Å', - withShiftAltGrIsDeadKey: false - }, - KeyB: { - value: 'b', - valueIsDeadKey: false, - withShift: 'B', - withShiftIsDeadKey: false, - withAltGr: '∫', - withAltGrIsDeadKey: false, - withShiftAltGr: '符', - withShiftAltGrIsDeadKey: false - }, - KeyC: { - value: 'c', - valueIsDeadKey: false, - withShift: 'C', - withShiftIsDeadKey: false, - withAltGr: 'ç', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ç', - withShiftAltGrIsDeadKey: false - }, - KeyD: { - value: 'd', - valueIsDeadKey: false, - withShift: 'D', - withShiftIsDeadKey: false, - withAltGr: '∂', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Î', - withShiftAltGrIsDeadKey: false - }, - KeyE: { - value: 'e', - valueIsDeadKey: false, - withShift: 'E', - withShiftIsDeadKey: false, - withAltGr: '´', - withAltGrIsDeadKey: true, - withShiftAltGr: '助', - withShiftAltGrIsDeadKey: false - }, - KeyF: { - value: 'f', - valueIsDeadKey: false, - withShift: 'F', - withShiftIsDeadKey: false, - withAltGr: 'ƒ', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ï', - withShiftAltGrIsDeadKey: false - }, - KeyG: { - value: 'g', - valueIsDeadKey: false, - withShift: 'G', - withShiftIsDeadKey: false, - withAltGr: '©', - withAltGrIsDeadKey: false, - withShiftAltGr: '˝', - withShiftAltGrIsDeadKey: false - }, - KeyH: { - value: 'h', - valueIsDeadKey: false, - withShift: 'H', - withShiftIsDeadKey: false, - withAltGr: '˙', - withAltGrIsDeadKey: false, - withShiftAltGr: '半', - withShiftAltGrIsDeadKey: false - }, - KeyI: { - value: 'i', - valueIsDeadKey: false, - withShift: 'I', - withShiftIsDeadKey: false, - withAltGr: 'ˆ', - withAltGrIsDeadKey: true, - withShiftAltGr: 'ˆ', - withShiftAltGrIsDeadKey: false - }, - KeyJ: { - value: 'j', - valueIsDeadKey: false, - withShift: 'J', - withShiftIsDeadKey: false, - withAltGr: '∆', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ô', - withShiftAltGrIsDeadKey: false - }, - KeyK: { - value: 'k', - valueIsDeadKey: false, - withShift: 'K', - withShiftIsDeadKey: false, - withAltGr: '˚', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - KeyL: { - value: 'l', - valueIsDeadKey: false, - withShift: 'L', - withShiftIsDeadKey: false, - withAltGr: '¬', - withAltGrIsDeadKey: false, - withShiftAltGr: '查', - withShiftAltGrIsDeadKey: false - }, - KeyM: { - value: 'm', - valueIsDeadKey: false, - withShift: 'M', - withShiftIsDeadKey: false, - withAltGr: 'µ', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Â', - withShiftAltGrIsDeadKey: false - }, - KeyN: { - value: 'n', - valueIsDeadKey: false, - withShift: 'N', - withShiftIsDeadKey: false, - withAltGr: '˜', - withAltGrIsDeadKey: true, - withShiftAltGr: '˜', - withShiftAltGrIsDeadKey: false - }, - KeyO: { - value: 'o', - valueIsDeadKey: false, - withShift: 'O', - withShiftIsDeadKey: false, - withAltGr: 'ø', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ø', - withShiftAltGrIsDeadKey: false - }, - KeyP: { - value: 'p', - valueIsDeadKey: false, - withShift: 'P', - withShiftIsDeadKey: false, - withAltGr: 'π', - withAltGrIsDeadKey: false, - withShiftAltGr: '∏', - withShiftAltGrIsDeadKey: false - }, - KeyQ: { - value: 'q', - valueIsDeadKey: false, - withShift: 'Q', - withShiftIsDeadKey: false, - withAltGr: 'œ', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Œ', - withShiftAltGrIsDeadKey: false - }, - KeyR: { - value: 'r', - valueIsDeadKey: false, - withShift: 'R', - withShiftIsDeadKey: false, - withAltGr: '®', - withAltGrIsDeadKey: false, - withShiftAltGr: '‰', - withShiftAltGrIsDeadKey: false - }, - KeyS: { - value: 's', - valueIsDeadKey: false, - withShift: 'S', - withShiftIsDeadKey: false, - withAltGr: 'ß', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Í', - withShiftAltGrIsDeadKey: false - }, - KeyT: { - value: 't', - valueIsDeadKey: false, - withShift: 'T', - withShiftIsDeadKey: false, - withAltGr: '†', - withAltGrIsDeadKey: false, - withShiftAltGr: 'ˇ', - withShiftAltGrIsDeadKey: false - }, - KeyU: { - value: 'u', - valueIsDeadKey: false, - withShift: 'U', - withShiftIsDeadKey: false, - withAltGr: '¨', - withAltGrIsDeadKey: true, - withShiftAltGr: '¨', - withShiftAltGrIsDeadKey: false - }, - KeyV: { - value: 'v', - valueIsDeadKey: false, - withShift: 'V', - withShiftIsDeadKey: false, - withAltGr: '√', - withAltGrIsDeadKey: false, - withShiftAltGr: '◊', - withShiftAltGrIsDeadKey: false - }, - KeyW: { - value: 'w', - valueIsDeadKey: false, - withShift: 'W', - withShiftIsDeadKey: false, - withAltGr: '∑', - withAltGrIsDeadKey: false, - withShiftAltGr: '„', - withShiftAltGrIsDeadKey: false - }, - KeyX: { - value: 'x', - valueIsDeadKey: false, - withShift: 'X', - withShiftIsDeadKey: false, - withAltGr: '≈', - withAltGrIsDeadKey: false, - withShiftAltGr: '˛', - withShiftAltGrIsDeadKey: false - }, - KeyY: { - value: 'y', - valueIsDeadKey: false, - withShift: 'Y', - withShiftIsDeadKey: false, - withAltGr: '¥', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Á', - withShiftAltGrIsDeadKey: false - }, - KeyZ: { - value: 'z', - valueIsDeadKey: false, - withShift: 'Z', - withShiftIsDeadKey: false, - withAltGr: 'Ω', - withAltGrIsDeadKey: false, - withShiftAltGr: '¸', - withShiftAltGrIsDeadKey: false - }, - Digit1: { - value: '1', - valueIsDeadKey: false, - withShift: '!', - withShiftIsDeadKey: false, - withAltGr: '1', - withAltGrIsDeadKey: false, - withShiftAltGr: '⁄', - withShiftAltGrIsDeadKey: false - }, - Digit2: { - value: '2', - valueIsDeadKey: false, - withShift: '@', - withShiftIsDeadKey: false, - withAltGr: '2', - withAltGrIsDeadKey: false, - withShiftAltGr: '€', - withShiftAltGrIsDeadKey: false - }, - Digit3: { - value: '3', - valueIsDeadKey: false, - withShift: '#', - withShiftIsDeadKey: false, - withAltGr: '3', - withAltGrIsDeadKey: false, - withShiftAltGr: '‹', - withShiftAltGrIsDeadKey: false - }, - Digit4: { - value: '4', - valueIsDeadKey: false, - withShift: '$', - withShiftIsDeadKey: false, - withAltGr: '4', - withAltGrIsDeadKey: false, - withShiftAltGr: '›', - withShiftAltGrIsDeadKey: false - }, - Digit5: { - value: '5', - valueIsDeadKey: false, - withShift: '%', - withShiftIsDeadKey: false, - withAltGr: '5', - withAltGrIsDeadKey: false, - withShiftAltGr: 'fi', - withShiftAltGrIsDeadKey: false - }, - Digit6: { - value: '6', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '6', - withAltGrIsDeadKey: false, - withShiftAltGr: 'fl', - withShiftAltGrIsDeadKey: false - }, - Digit7: { - value: '7', - valueIsDeadKey: false, - withShift: '&', - withShiftIsDeadKey: false, - withAltGr: '7', - withAltGrIsDeadKey: false, - withShiftAltGr: '‡', - withShiftAltGrIsDeadKey: false - }, - Digit8: { - value: '8', - valueIsDeadKey: false, - withShift: '*', - withShiftIsDeadKey: false, - withAltGr: '8', - withAltGrIsDeadKey: false, - withShiftAltGr: '°', - withShiftAltGrIsDeadKey: false - }, - Digit9: { - value: '9', - valueIsDeadKey: false, - withShift: '(', - withShiftIsDeadKey: false, - withAltGr: '9', - withAltGrIsDeadKey: false, - withShiftAltGr: '·', - withShiftAltGrIsDeadKey: false - }, - Digit0: { - value: '0', - valueIsDeadKey: false, - withShift: ')', - withShiftIsDeadKey: false, - withAltGr: '0', - withAltGrIsDeadKey: false, - withShiftAltGr: '‚', - withShiftAltGrIsDeadKey: false - }, - Enter: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Escape: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Backspace: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Tab: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Space: { - value: ' ', - valueIsDeadKey: false, - withShift: ' ', - withShiftIsDeadKey: false, - withAltGr: ' ', - withAltGrIsDeadKey: false, - withShiftAltGr: ' ', - withShiftAltGrIsDeadKey: false - }, - Minus: { - value: '-', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '–', - withAltGrIsDeadKey: false, - withShiftAltGr: '—', - withShiftAltGrIsDeadKey: false - }, - Equal: { - value: '=', - valueIsDeadKey: false, - withShift: '+', - withShiftIsDeadKey: false, - withAltGr: '≠', - withAltGrIsDeadKey: false, - withShiftAltGr: '±', - withShiftAltGrIsDeadKey: false - }, - BracketLeft: { - value: '【', - valueIsDeadKey: false, - withShift: '「', - withShiftIsDeadKey: false, - withAltGr: '“', - withAltGrIsDeadKey: false, - withShiftAltGr: '”', - withShiftAltGrIsDeadKey: false - }, - BracketRight: { - value: '】', - valueIsDeadKey: false, - withShift: '」', - withShiftIsDeadKey: false, - withAltGr: '‘', - withAltGrIsDeadKey: false, - withShiftAltGr: '’', - withShiftAltGrIsDeadKey: false - }, - Backslash: { - value: '、', - valueIsDeadKey: false, - withShift: '|', - withShiftIsDeadKey: false, - withAltGr: '«', - withAltGrIsDeadKey: false, - withShiftAltGr: '»', - withShiftAltGrIsDeadKey: false - }, - Semicolon: { - value: ';', - valueIsDeadKey: false, - withShift: ':', - withShiftIsDeadKey: false, - withAltGr: '…', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Ú', - withShiftAltGrIsDeadKey: false - }, - Quote: { - value: '\'', - valueIsDeadKey: false, - withShift: '"', - withShiftIsDeadKey: false, - withAltGr: 'æ', - withAltGrIsDeadKey: false, - withShiftAltGr: 'Æ', - withShiftAltGrIsDeadKey: false - }, - Backquote: { - value: '·', - valueIsDeadKey: false, - withShift: '~', - withShiftIsDeadKey: false, - withAltGr: '·', - withAltGrIsDeadKey: false, - withShiftAltGr: '·', - withShiftAltGrIsDeadKey: false - }, - Comma: { - value: ',', - valueIsDeadKey: false, - withShift: '《', - withShiftIsDeadKey: false, - withAltGr: '≤', - withAltGrIsDeadKey: false, - withShiftAltGr: '¯', - withShiftAltGrIsDeadKey: false - }, - Period: { - value: '。', - valueIsDeadKey: false, - withShift: '》', - withShiftIsDeadKey: false, - withAltGr: '≥', - withAltGrIsDeadKey: false, - withShiftAltGr: '˘', - withShiftAltGrIsDeadKey: false - }, - Slash: { - value: '/', - valueIsDeadKey: false, - withShift: '?', - withShiftIsDeadKey: false, - withAltGr: '÷', - withAltGrIsDeadKey: false, - withShiftAltGr: '¿', - withShiftAltGrIsDeadKey: false - }, - CapsLock: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F1: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F2: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F3: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F4: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F5: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F6: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F7: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F8: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F9: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F10: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F11: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F12: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Insert: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Home: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - PageUp: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Delete: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - End: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - PageDown: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowDown: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ArrowUp: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumLock: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumpadDivide: { - value: '/', - valueIsDeadKey: false, - withShift: '/', - withShiftIsDeadKey: false, - withAltGr: '/', - withAltGrIsDeadKey: false, - withShiftAltGr: '/', - withShiftAltGrIsDeadKey: false - }, - NumpadMultiply: { - value: '*', - valueIsDeadKey: false, - withShift: '*', - withShiftIsDeadKey: false, - withAltGr: '*', - withAltGrIsDeadKey: false, - withShiftAltGr: '*', - withShiftAltGrIsDeadKey: false - }, - NumpadSubtract: { - value: '-', - valueIsDeadKey: false, - withShift: '-', - withShiftIsDeadKey: false, - withAltGr: '-', - withAltGrIsDeadKey: false, - withShiftAltGr: '-', - withShiftAltGrIsDeadKey: false - }, - NumpadAdd: { - value: '+', - valueIsDeadKey: false, - withShift: '+', - withShiftIsDeadKey: false, - withAltGr: '+', - withAltGrIsDeadKey: false, - withShiftAltGr: '+', - withShiftAltGrIsDeadKey: false - }, - NumpadEnter: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - Numpad1: { - value: '1', - valueIsDeadKey: false, - withShift: '1', - withShiftIsDeadKey: false, - withAltGr: '1', - withAltGrIsDeadKey: false, - withShiftAltGr: '1', - withShiftAltGrIsDeadKey: false - }, - Numpad2: { - value: '2', - valueIsDeadKey: false, - withShift: '2', - withShiftIsDeadKey: false, - withAltGr: '2', - withAltGrIsDeadKey: false, - withShiftAltGr: '2', - withShiftAltGrIsDeadKey: false - }, - Numpad3: { - value: '3', - valueIsDeadKey: false, - withShift: '3', - withShiftIsDeadKey: false, - withAltGr: '3', - withAltGrIsDeadKey: false, - withShiftAltGr: '3', - withShiftAltGrIsDeadKey: false - }, - Numpad4: { - value: '4', - valueIsDeadKey: false, - withShift: '4', - withShiftIsDeadKey: false, - withAltGr: '4', - withAltGrIsDeadKey: false, - withShiftAltGr: '4', - withShiftAltGrIsDeadKey: false - }, - Numpad5: { - value: '5', - valueIsDeadKey: false, - withShift: '5', - withShiftIsDeadKey: false, - withAltGr: '5', - withAltGrIsDeadKey: false, - withShiftAltGr: '5', - withShiftAltGrIsDeadKey: false - }, - Numpad6: { - value: '6', - valueIsDeadKey: false, - withShift: '6', - withShiftIsDeadKey: false, - withAltGr: '6', - withAltGrIsDeadKey: false, - withShiftAltGr: '6', - withShiftAltGrIsDeadKey: false - }, - Numpad7: { - value: '7', - valueIsDeadKey: false, - withShift: '7', - withShiftIsDeadKey: false, - withAltGr: '7', - withAltGrIsDeadKey: false, - withShiftAltGr: '7', - withShiftAltGrIsDeadKey: false - }, - Numpad8: { - value: '8', - valueIsDeadKey: false, - withShift: '8', - withShiftIsDeadKey: false, - withAltGr: '8', - withAltGrIsDeadKey: false, - withShiftAltGr: '8', - withShiftAltGrIsDeadKey: false - }, - Numpad9: { - value: '9', - valueIsDeadKey: false, - withShift: '9', - withShiftIsDeadKey: false, - withAltGr: '9', - withAltGrIsDeadKey: false, - withShiftAltGr: '9', - withShiftAltGrIsDeadKey: false - }, - Numpad0: { - value: '0', - valueIsDeadKey: false, - withShift: '0', - withShiftIsDeadKey: false, - withAltGr: '0', - withAltGrIsDeadKey: false, - withShiftAltGr: '0', - withShiftAltGrIsDeadKey: false - }, - NumpadDecimal: { - value: '.', - valueIsDeadKey: false, - withShift: '.', - withShiftIsDeadKey: false, - withAltGr: '.', - withAltGrIsDeadKey: false, - withShiftAltGr: '.', - withShiftAltGrIsDeadKey: false - }, - IntlBackslash: { - value: '§', - valueIsDeadKey: false, - withShift: '±', - withShiftIsDeadKey: false, - withAltGr: '§', - withAltGrIsDeadKey: false, - withShiftAltGr: '±', - withShiftAltGrIsDeadKey: false - }, - ContextMenu: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumpadEqual: { - value: '=', - valueIsDeadKey: false, - withShift: '=', - withShiftIsDeadKey: false, - withAltGr: '=', - withAltGrIsDeadKey: false, - withShiftAltGr: '=', - withShiftAltGrIsDeadKey: false - }, - F13: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F14: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F15: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F16: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F17: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F18: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F19: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - F20: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AudioVolumeMute: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AudioVolumeUp: { - value: '', - valueIsDeadKey: false, - withShift: '=', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '=', - withShiftAltGrIsDeadKey: false - }, - AudioVolumeDown: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - NumpadComma: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - IntlRo: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - KanaMode: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - IntlYen: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ControlLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ShiftLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AltLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - MetaLeft: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ControlRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - ShiftRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - AltRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - }, - MetaRight: { - value: '', - valueIsDeadKey: false, - withShift: '', - withShiftIsDeadKey: false, - withAltGr: '', - withAltGrIsDeadKey: false, - withShiftAltGr: '', - withShiftAltGrIsDeadKey: false - } -}); diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant2.txt b/src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant2.txt deleted file mode 100644 index 17b24363b35..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/mac_zh_hant2.txt +++ /dev/null @@ -1,507 +0,0 @@ -isUSStandard: false ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyA | a | A | | A | a | A | [KeyA] | | -| Ctrl+KeyA | a | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | -| Shift+KeyA | A | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | -| Ctrl+Shift+KeyA | A | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | -| Alt+KeyA | a | Alt+A | | Option+A | alt+a | Alt+A | alt+[KeyA] | | -| Ctrl+Alt+KeyA | å | Ctrl+Alt+A | | Ctrl+Option+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | -| Shift+Alt+KeyA | A | Shift+Alt+A | | Shift+Option+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | -| Ctrl+Shift+Alt+KeyA | Å | Ctrl+Shift+Alt+A | | Ctrl+Shift+Option+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyB | b | B | | B | b | B | [KeyB] | | -| Ctrl+KeyB | b | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | -| Shift+KeyB | B | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | -| Ctrl+Shift+KeyB | B | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | -| Alt+KeyB | b | Alt+B | | Option+B | alt+b | Alt+B | alt+[KeyB] | | -| Ctrl+Alt+KeyB | ∫ | Ctrl+Alt+B | | Ctrl+Option+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | -| Shift+Alt+KeyB | B | Shift+Alt+B | | Shift+Option+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | -| Ctrl+Shift+Alt+KeyB | 符 | Ctrl+Shift+Alt+B | | Ctrl+Shift+Option+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyC | c | C | | C | c | C | [KeyC] | | -| Ctrl+KeyC | c | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | -| Shift+KeyC | C | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | -| Ctrl+Shift+KeyC | C | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | -| Alt+KeyC | c | Alt+C | | Option+C | alt+c | Alt+C | alt+[KeyC] | | -| Ctrl+Alt+KeyC | ç | Ctrl+Alt+C | | Ctrl+Option+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | -| Shift+Alt+KeyC | C | Shift+Alt+C | | Shift+Option+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | -| Ctrl+Shift+Alt+KeyC | Ç | Ctrl+Shift+Alt+C | | Ctrl+Shift+Option+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyD | d | D | | D | d | D | [KeyD] | | -| Ctrl+KeyD | d | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | -| Shift+KeyD | D | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | -| Ctrl+Shift+KeyD | D | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | -| Alt+KeyD | d | Alt+D | | Option+D | alt+d | Alt+D | alt+[KeyD] | | -| Ctrl+Alt+KeyD | ∂ | Ctrl+Alt+D | | Ctrl+Option+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | -| Shift+Alt+KeyD | D | Shift+Alt+D | | Shift+Option+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | -| Ctrl+Shift+Alt+KeyD | Î | Ctrl+Shift+Alt+D | | Ctrl+Shift+Option+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyE | e | E | | E | e | E | [KeyE] | | -| Ctrl+KeyE | e | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | -| Shift+KeyE | E | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | -| Ctrl+Shift+KeyE | E | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | -| Alt+KeyE | e | Alt+E | | Option+E | alt+e | Alt+E | alt+[KeyE] | | -| Ctrl+Alt+KeyE | ´ | Ctrl+Alt+E | | Ctrl+Option+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | -| Shift+Alt+KeyE | E | Shift+Alt+E | | Shift+Option+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | -| Ctrl+Shift+Alt+KeyE | 助 | Ctrl+Shift+Alt+E | | Ctrl+Shift+Option+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyF | f | F | | F | f | F | [KeyF] | | -| Ctrl+KeyF | f | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | -| Shift+KeyF | F | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | -| Ctrl+Shift+KeyF | F | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | -| Alt+KeyF | f | Alt+F | | Option+F | alt+f | Alt+F | alt+[KeyF] | | -| Ctrl+Alt+KeyF | ƒ | Ctrl+Alt+F | | Ctrl+Option+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | -| Shift+Alt+KeyF | F | Shift+Alt+F | | Shift+Option+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | -| Ctrl+Shift+Alt+KeyF | Ï | Ctrl+Shift+Alt+F | | Ctrl+Shift+Option+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyG | g | G | | G | g | G | [KeyG] | | -| Ctrl+KeyG | g | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | -| Shift+KeyG | G | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | -| Ctrl+Shift+KeyG | G | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | -| Alt+KeyG | g | Alt+G | | Option+G | alt+g | Alt+G | alt+[KeyG] | | -| Ctrl+Alt+KeyG | © | Ctrl+Alt+G | | Ctrl+Option+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | -| Shift+Alt+KeyG | G | Shift+Alt+G | | Shift+Option+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | -| Ctrl+Shift+Alt+KeyG | ˝ | Ctrl+Shift+Alt+G | | Ctrl+Shift+Option+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyH | h | H | | H | h | H | [KeyH] | | -| Ctrl+KeyH | h | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | -| Shift+KeyH | H | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | -| Ctrl+Shift+KeyH | H | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | -| Alt+KeyH | h | Alt+H | | Option+H | alt+h | Alt+H | alt+[KeyH] | | -| Ctrl+Alt+KeyH | ˙ | Ctrl+Alt+H | | Ctrl+Option+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | -| Shift+Alt+KeyH | H | Shift+Alt+H | | Shift+Option+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | -| Ctrl+Shift+Alt+KeyH | 半 | Ctrl+Shift+Alt+H | | Ctrl+Shift+Option+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyI | i | I | | I | i | I | [KeyI] | | -| Ctrl+KeyI | i | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | -| Shift+KeyI | I | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | -| Ctrl+Shift+KeyI | I | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | -| Alt+KeyI | i | Alt+I | | Option+I | alt+i | Alt+I | alt+[KeyI] | | -| Ctrl+Alt+KeyI | ˆ | Ctrl+Alt+I | | Ctrl+Option+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | -| Shift+Alt+KeyI | I | Shift+Alt+I | | Shift+Option+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | -| Ctrl+Shift+Alt+KeyI | ˆ | Ctrl+Shift+Alt+I | | Ctrl+Shift+Option+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyJ | j | J | | J | j | J | [KeyJ] | | -| Ctrl+KeyJ | j | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | -| Shift+KeyJ | J | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | -| Ctrl+Shift+KeyJ | J | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | -| Alt+KeyJ | j | Alt+J | | Option+J | alt+j | Alt+J | alt+[KeyJ] | | -| Ctrl+Alt+KeyJ | ∆ | Ctrl+Alt+J | | Ctrl+Option+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | -| Shift+Alt+KeyJ | J | Shift+Alt+J | | Shift+Option+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | -| Ctrl+Shift+Alt+KeyJ | Ô | Ctrl+Shift+Alt+J | | Ctrl+Shift+Option+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyK | k | K | | K | k | K | [KeyK] | | -| Ctrl+KeyK | k | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | -| Shift+KeyK | K | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | -| Ctrl+Shift+KeyK | K | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | -| Alt+KeyK | k | Alt+K | | Option+K | alt+k | Alt+K | alt+[KeyK] | | -| Ctrl+Alt+KeyK | ˚ | Ctrl+Alt+K | | Ctrl+Option+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | -| Shift+Alt+KeyK | K | Shift+Alt+K | | Shift+Option+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | -| Ctrl+Shift+Alt+KeyK |  | Ctrl+Shift+Alt+K | | Ctrl+Shift+Option+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyL | l | L | | L | l | L | [KeyL] | | -| Ctrl+KeyL | l | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | -| Shift+KeyL | L | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | -| Ctrl+Shift+KeyL | L | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | -| Alt+KeyL | l | Alt+L | | Option+L | alt+l | Alt+L | alt+[KeyL] | | -| Ctrl+Alt+KeyL | ¬ | Ctrl+Alt+L | | Ctrl+Option+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | -| Shift+Alt+KeyL | L | Shift+Alt+L | | Shift+Option+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | -| Ctrl+Shift+Alt+KeyL | 查 | Ctrl+Shift+Alt+L | | Ctrl+Shift+Option+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyM | m | M | | M | m | M | [KeyM] | | -| Ctrl+KeyM | m | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | -| Shift+KeyM | M | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | -| Ctrl+Shift+KeyM | M | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | -| Alt+KeyM | m | Alt+M | | Option+M | alt+m | Alt+M | alt+[KeyM] | | -| Ctrl+Alt+KeyM | µ | Ctrl+Alt+M | | Ctrl+Option+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | -| Shift+Alt+KeyM | M | Shift+Alt+M | | Shift+Option+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | -| Ctrl+Shift+Alt+KeyM |  | Ctrl+Shift+Alt+M | | Ctrl+Shift+Option+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyN | n | N | | N | n | N | [KeyN] | | -| Ctrl+KeyN | n | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | -| Shift+KeyN | N | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | -| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | -| Alt+KeyN | n | Alt+N | | Option+N | alt+n | Alt+N | alt+[KeyN] | | -| Ctrl+Alt+KeyN | ˜ | Ctrl+Alt+N | | Ctrl+Option+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | -| Shift+Alt+KeyN | N | Shift+Alt+N | | Shift+Option+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | -| Ctrl+Shift+Alt+KeyN | ˜ | Ctrl+Shift+Alt+N | | Ctrl+Shift+Option+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyO | o | O | | O | o | O | [KeyO] | | -| Ctrl+KeyO | o | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | -| Shift+KeyO | O | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | -| Ctrl+Shift+KeyO | O | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | -| Alt+KeyO | o | Alt+O | | Option+O | alt+o | Alt+O | alt+[KeyO] | | -| Ctrl+Alt+KeyO | ø | Ctrl+Alt+O | | Ctrl+Option+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | -| Shift+Alt+KeyO | O | Shift+Alt+O | | Shift+Option+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | -| Ctrl+Shift+Alt+KeyO | Ø | Ctrl+Shift+Alt+O | | Ctrl+Shift+Option+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyP | p | P | | P | p | P | [KeyP] | | -| Ctrl+KeyP | p | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | -| Shift+KeyP | P | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | -| Ctrl+Shift+KeyP | P | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | -| Alt+KeyP | p | Alt+P | | Option+P | alt+p | Alt+P | alt+[KeyP] | | -| Ctrl+Alt+KeyP | π | Ctrl+Alt+P | | Ctrl+Option+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | -| Shift+Alt+KeyP | P | Shift+Alt+P | | Shift+Option+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | -| Ctrl+Shift+Alt+KeyP | ∏ | Ctrl+Shift+Alt+P | | Ctrl+Shift+Option+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyQ | q | Q | | Q | q | Q | [KeyQ] | | -| Ctrl+KeyQ | q | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | -| Shift+KeyQ | Q | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | -| Ctrl+Shift+KeyQ | Q | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | -| Alt+KeyQ | q | Alt+Q | | Option+Q | alt+q | Alt+Q | alt+[KeyQ] | | -| Ctrl+Alt+KeyQ | œ | Ctrl+Alt+Q | | Ctrl+Option+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | -| Shift+Alt+KeyQ | Q | Shift+Alt+Q | | Shift+Option+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | -| Ctrl+Shift+Alt+KeyQ | Œ | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Option+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyR | r | R | | R | r | R | [KeyR] | | -| Ctrl+KeyR | r | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | -| Shift+KeyR | R | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | -| Ctrl+Shift+KeyR | R | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | -| Alt+KeyR | r | Alt+R | | Option+R | alt+r | Alt+R | alt+[KeyR] | | -| Ctrl+Alt+KeyR | ® | Ctrl+Alt+R | | Ctrl+Option+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | -| Shift+Alt+KeyR | R | Shift+Alt+R | | Shift+Option+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | -| Ctrl+Shift+Alt+KeyR | ‰ | Ctrl+Shift+Alt+R | | Ctrl+Shift+Option+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyS | s | S | | S | s | S | [KeyS] | | -| Ctrl+KeyS | s | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | -| Shift+KeyS | S | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | -| Ctrl+Shift+KeyS | S | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | -| Alt+KeyS | s | Alt+S | | Option+S | alt+s | Alt+S | alt+[KeyS] | | -| Ctrl+Alt+KeyS | ß | Ctrl+Alt+S | | Ctrl+Option+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | -| Shift+Alt+KeyS | S | Shift+Alt+S | | Shift+Option+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | -| Ctrl+Shift+Alt+KeyS | Í | Ctrl+Shift+Alt+S | | Ctrl+Shift+Option+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyT | t | T | | T | t | T | [KeyT] | | -| Ctrl+KeyT | t | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | -| Shift+KeyT | T | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | -| Ctrl+Shift+KeyT | T | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | -| Alt+KeyT | t | Alt+T | | Option+T | alt+t | Alt+T | alt+[KeyT] | | -| Ctrl+Alt+KeyT | † | Ctrl+Alt+T | | Ctrl+Option+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | -| Shift+Alt+KeyT | T | Shift+Alt+T | | Shift+Option+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | -| Ctrl+Shift+Alt+KeyT | ˇ | Ctrl+Shift+Alt+T | | Ctrl+Shift+Option+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyU | u | U | | U | u | U | [KeyU] | | -| Ctrl+KeyU | u | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | -| Shift+KeyU | U | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | -| Ctrl+Shift+KeyU | U | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | -| Alt+KeyU | u | Alt+U | | Option+U | alt+u | Alt+U | alt+[KeyU] | | -| Ctrl+Alt+KeyU | ¨ | Ctrl+Alt+U | | Ctrl+Option+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | -| Shift+Alt+KeyU | U | Shift+Alt+U | | Shift+Option+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | -| Ctrl+Shift+Alt+KeyU | ¨ | Ctrl+Shift+Alt+U | | Ctrl+Shift+Option+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyV | v | V | | V | v | V | [KeyV] | | -| Ctrl+KeyV | v | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | -| Shift+KeyV | V | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | -| Ctrl+Shift+KeyV | V | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | -| Alt+KeyV | v | Alt+V | | Option+V | alt+v | Alt+V | alt+[KeyV] | | -| Ctrl+Alt+KeyV | √ | Ctrl+Alt+V | | Ctrl+Option+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | -| Shift+Alt+KeyV | V | Shift+Alt+V | | Shift+Option+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | -| Ctrl+Shift+Alt+KeyV | ◊ | Ctrl+Shift+Alt+V | | Ctrl+Shift+Option+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyW | w | W | | W | w | W | [KeyW] | | -| Ctrl+KeyW | w | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | -| Shift+KeyW | W | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | -| Ctrl+Shift+KeyW | W | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | -| Alt+KeyW | w | Alt+W | | Option+W | alt+w | Alt+W | alt+[KeyW] | | -| Ctrl+Alt+KeyW | ∑ | Ctrl+Alt+W | | Ctrl+Option+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | -| Shift+Alt+KeyW | W | Shift+Alt+W | | Shift+Option+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | -| Ctrl+Shift+Alt+KeyW | „ | Ctrl+Shift+Alt+W | | Ctrl+Shift+Option+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyX | x | X | | X | x | X | [KeyX] | | -| Ctrl+KeyX | x | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | -| Shift+KeyX | X | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | -| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | -| Alt+KeyX | x | Alt+X | | Option+X | alt+x | Alt+X | alt+[KeyX] | | -| Ctrl+Alt+KeyX | ≈ | Ctrl+Alt+X | | Ctrl+Option+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | -| Shift+Alt+KeyX | X | Shift+Alt+X | | Shift+Option+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | -| Ctrl+Shift+Alt+KeyX | ˛ | Ctrl+Shift+Alt+X | | Ctrl+Shift+Option+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyY | y | Y | | Y | y | Y | [KeyY] | | -| Ctrl+KeyY | y | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyY] | | -| Shift+KeyY | Y | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyY] | | -| Ctrl+Shift+KeyY | Y | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyY] | | -| Alt+KeyY | y | Alt+Y | | Option+Y | alt+y | Alt+Y | alt+[KeyY] | | -| Ctrl+Alt+KeyY | ¥ | Ctrl+Alt+Y | | Ctrl+Option+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyY] | | -| Shift+Alt+KeyY | Y | Shift+Alt+Y | | Shift+Option+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyY] | | -| Ctrl+Shift+Alt+KeyY | Á | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Option+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyY] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| KeyZ | z | Z | | Z | z | Z | [KeyZ] | | -| Ctrl+KeyZ | z | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyZ] | | -| Shift+KeyZ | Z | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyZ] | | -| Ctrl+Shift+KeyZ | Z | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyZ] | | -| Alt+KeyZ | z | Alt+Z | | Option+Z | alt+z | Alt+Z | alt+[KeyZ] | | -| Ctrl+Alt+KeyZ | Ω | Ctrl+Alt+Z | | Ctrl+Option+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyZ] | | -| Shift+Alt+KeyZ | Z | Shift+Alt+Z | | Shift+Option+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyZ] | | -| Ctrl+Shift+Alt+KeyZ | ¸ | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Option+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyZ] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit1 | 1 | 1 | | 1 | 1 | 1 | [Digit1] | | -| Ctrl+Digit1 | 1 | Ctrl+1 | | Ctrl+1 | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | | -| Shift+Digit1 | ! | Shift+1 | | Shift+1 | shift+1 | Shift+1 | shift+[Digit1] | | -| Ctrl+Shift+Digit1 | ! | Ctrl+Shift+1 | | Ctrl+Shift+1 | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | | -| Alt+Digit1 | 1 | Alt+1 | | Option+1 | alt+1 | Alt+1 | alt+[Digit1] | | -| Ctrl+Alt+Digit1 | 1 | Ctrl+Alt+1 | | Ctrl+Option+1 | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | | -| Shift+Alt+Digit1 | ! | Shift+Alt+1 | | Shift+Option+1 | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | | -| Ctrl+Shift+Alt+Digit1 | ⁄ | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Option+1 | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit2 | 2 | 2 | | 2 | 2 | 2 | [Digit2] | | -| Ctrl+Digit2 | 2 | Ctrl+2 | | Ctrl+2 | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | | -| Shift+Digit2 | @ | Shift+2 | | Shift+2 | shift+2 | Shift+2 | shift+[Digit2] | | -| Ctrl+Shift+Digit2 | @ | Ctrl+Shift+2 | | Ctrl+Shift+2 | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | | -| Alt+Digit2 | 2 | Alt+2 | | Option+2 | alt+2 | Alt+2 | alt+[Digit2] | | -| Ctrl+Alt+Digit2 | 2 | Ctrl+Alt+2 | | Ctrl+Option+2 | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | | -| Shift+Alt+Digit2 | @ | Shift+Alt+2 | | Shift+Option+2 | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | | -| Ctrl+Shift+Alt+Digit2 | € | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Option+2 | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit3 | 3 | 3 | | 3 | 3 | 3 | [Digit3] | | -| Ctrl+Digit3 | 3 | Ctrl+3 | | Ctrl+3 | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | | -| Shift+Digit3 | # | Shift+3 | | Shift+3 | shift+3 | Shift+3 | shift+[Digit3] | | -| Ctrl+Shift+Digit3 | # | Ctrl+Shift+3 | | Ctrl+Shift+3 | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | | -| Alt+Digit3 | 3 | Alt+3 | | Option+3 | alt+3 | Alt+3 | alt+[Digit3] | | -| Ctrl+Alt+Digit3 | 3 | Ctrl+Alt+3 | | Ctrl+Option+3 | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | | -| Shift+Alt+Digit3 | # | Shift+Alt+3 | | Shift+Option+3 | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | | -| Ctrl+Shift+Alt+Digit3 | ‹ | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Option+3 | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit4 | 4 | 4 | | 4 | 4 | 4 | [Digit4] | | -| Ctrl+Digit4 | 4 | Ctrl+4 | | Ctrl+4 | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | | -| Shift+Digit4 | $ | Shift+4 | | Shift+4 | shift+4 | Shift+4 | shift+[Digit4] | | -| Ctrl+Shift+Digit4 | $ | Ctrl+Shift+4 | | Ctrl+Shift+4 | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | | -| Alt+Digit4 | 4 | Alt+4 | | Option+4 | alt+4 | Alt+4 | alt+[Digit4] | | -| Ctrl+Alt+Digit4 | 4 | Ctrl+Alt+4 | | Ctrl+Option+4 | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | | -| Shift+Alt+Digit4 | $ | Shift+Alt+4 | | Shift+Option+4 | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | | -| Ctrl+Shift+Alt+Digit4 | › | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Option+4 | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit5 | 5 | 5 | | 5 | 5 | 5 | [Digit5] | | -| Ctrl+Digit5 | 5 | Ctrl+5 | | Ctrl+5 | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | | -| Shift+Digit5 | % | Shift+5 | | Shift+5 | shift+5 | Shift+5 | shift+[Digit5] | | -| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+5 | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | | -| Alt+Digit5 | 5 | Alt+5 | | Option+5 | alt+5 | Alt+5 | alt+[Digit5] | | -| Ctrl+Alt+Digit5 | 5 | Ctrl+Alt+5 | | Ctrl+Option+5 | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | | -| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Option+5 | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | | -| Ctrl+Shift+Alt+Digit5 | fi | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Option+5 | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit6 | 6 | 6 | | 6 | 6 | 6 | [Digit6] | | -| Ctrl+Digit6 | 6 | Ctrl+6 | | Ctrl+6 | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | | -| Shift+Digit6 | --- | Shift+6 | | Shift+6 | shift+6 | Shift+6 | shift+[Digit6] | | -| Ctrl+Shift+Digit6 | --- | Ctrl+Shift+6 | | Ctrl+Shift+6 | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | | -| Alt+Digit6 | 6 | Alt+6 | | Option+6 | alt+6 | Alt+6 | alt+[Digit6] | | -| Ctrl+Alt+Digit6 | 6 | Ctrl+Alt+6 | | Ctrl+Option+6 | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | | -| Shift+Alt+Digit6 | --- | Shift+Alt+6 | | Shift+Option+6 | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | | -| Ctrl+Shift+Alt+Digit6 | fl | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Option+6 | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit7 | 7 | 7 | | 7 | 7 | 7 | [Digit7] | | -| Ctrl+Digit7 | 7 | Ctrl+7 | | Ctrl+7 | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | | -| Shift+Digit7 | & | Shift+7 | | Shift+7 | shift+7 | Shift+7 | shift+[Digit7] | | -| Ctrl+Shift+Digit7 | & | Ctrl+Shift+7 | | Ctrl+Shift+7 | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | | -| Alt+Digit7 | 7 | Alt+7 | | Option+7 | alt+7 | Alt+7 | alt+[Digit7] | | -| Ctrl+Alt+Digit7 | 7 | Ctrl+Alt+7 | | Ctrl+Option+7 | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | | -| Shift+Alt+Digit7 | & | Shift+Alt+7 | | Shift+Option+7 | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | | -| Ctrl+Shift+Alt+Digit7 | ‡ | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Option+7 | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit8 | 8 | 8 | | 8 | 8 | 8 | [Digit8] | | -| Ctrl+Digit8 | 8 | Ctrl+8 | | Ctrl+8 | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | | -| Shift+Digit8 | * | Shift+8 | | Shift+8 | shift+8 | Shift+8 | shift+[Digit8] | | -| Ctrl+Shift+Digit8 | * | Ctrl+Shift+8 | | Ctrl+Shift+8 | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | | -| Alt+Digit8 | 8 | Alt+8 | | Option+8 | alt+8 | Alt+8 | alt+[Digit8] | | -| Ctrl+Alt+Digit8 | 8 | Ctrl+Alt+8 | | Ctrl+Option+8 | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | | -| Shift+Alt+Digit8 | * | Shift+Alt+8 | | Shift+Option+8 | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | | -| Ctrl+Shift+Alt+Digit8 | ° | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Option+8 | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit9 | 9 | 9 | | 9 | 9 | 9 | [Digit9] | | -| Ctrl+Digit9 | 9 | Ctrl+9 | | Ctrl+9 | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | | -| Shift+Digit9 | ( | Shift+9 | | Shift+9 | shift+9 | Shift+9 | shift+[Digit9] | | -| Ctrl+Shift+Digit9 | ( | Ctrl+Shift+9 | | Ctrl+Shift+9 | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | | -| Alt+Digit9 | 9 | Alt+9 | | Option+9 | alt+9 | Alt+9 | alt+[Digit9] | | -| Ctrl+Alt+Digit9 | 9 | Ctrl+Alt+9 | | Ctrl+Option+9 | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | | -| Shift+Alt+Digit9 | ( | Shift+Alt+9 | | Shift+Option+9 | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | | -| Ctrl+Shift+Alt+Digit9 | · | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Option+9 | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Digit0 | 0 | 0 | | 0 | 0 | 0 | [Digit0] | | -| Ctrl+Digit0 | 0 | Ctrl+0 | | Ctrl+0 | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | | -| Shift+Digit0 | ) | Shift+0 | | Shift+0 | shift+0 | Shift+0 | shift+[Digit0] | | -| Ctrl+Shift+Digit0 | ) | Ctrl+Shift+0 | | Ctrl+Shift+0 | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | | -| Alt+Digit0 | 0 | Alt+0 | | Option+0 | alt+0 | Alt+0 | alt+[Digit0] | | -| Ctrl+Alt+Digit0 | 0 | Ctrl+Alt+0 | | Ctrl+Option+0 | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | | -| Shift+Alt+Digit0 | ) | Shift+Alt+0 | | Shift+Option+0 | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | | -| Ctrl+Shift+Alt+Digit0 | ‚ | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Option+0 | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Minus | - | - | | - | - | - | [Minus] | | -| Ctrl+Minus | - | Ctrl+- | | Ctrl+- | ctrl+- | Ctrl+- | ctrl+[Minus] | | -| Shift+Minus | --- | Shift+- | | Shift+- | shift+- | Shift+- | shift+[Minus] | | -| Ctrl+Shift+Minus | --- | Ctrl+Shift+- | | Ctrl+Shift+- | ctrl+shift+- | Ctrl+Shift+- | ctrl+shift+[Minus] | | -| Alt+Minus | - | Alt+- | | Option+- | alt+- | Alt+- | alt+[Minus] | | -| Ctrl+Alt+Minus | – | Ctrl+Alt+- | | Ctrl+Option+- | ctrl+alt+- | Ctrl+Alt+- | ctrl+alt+[Minus] | | -| Shift+Alt+Minus | --- | Shift+Alt+- | | Shift+Option+- | shift+alt+- | Shift+Alt+- | shift+alt+[Minus] | | -| Ctrl+Shift+Alt+Minus | — | Ctrl+Shift+Alt+- | | Ctrl+Shift+Option+- | ctrl+shift+alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+[Minus] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Equal | = | = | | = | = | = | [Equal] | | -| Ctrl+Equal | = | Ctrl+= | | Ctrl+= | ctrl+= | Ctrl+= | ctrl+[Equal] | | -| Shift+Equal | + | Shift+= | | Shift+= | shift+= | Shift+= | shift+[Equal] | | -| Ctrl+Shift+Equal | + | Ctrl+Shift+= | | Ctrl+Shift+= | ctrl+shift+= | Ctrl+Shift+= | ctrl+shift+[Equal] | | -| Alt+Equal | = | Alt+= | | Option+= | alt+= | Alt+= | alt+[Equal] | | -| Ctrl+Alt+Equal | ≠ | Ctrl+Alt+= | | Ctrl+Option+= | ctrl+alt+= | Ctrl+Alt+= | ctrl+alt+[Equal] | | -| Shift+Alt+Equal | + | Shift+Alt+= | | Shift+Option+= | shift+alt+= | Shift+Alt+= | shift+alt+[Equal] | | -| Ctrl+Shift+Alt+Equal | ± | Ctrl+Shift+Alt+= | | Ctrl+Shift+Option+= | ctrl+shift+alt+= | Ctrl+Shift+Alt+= | ctrl+shift+alt+[Equal] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketLeft | 【 | [ | 1 | 【 | [BracketLeft] | null | [BracketLeft] | NO | -| Ctrl+BracketLeft | 【 | Ctrl+[ | 1 | Ctrl+【 | ctrl+[BracketLeft] | null | ctrl+[BracketLeft] | NO | -| Shift+BracketLeft | 「 | [ | 2 | Shift+【 | shift+[BracketLeft] | null | shift+[BracketLeft] | NO | -| Ctrl+Shift+BracketLeft | 「 | Ctrl+[ | 2 | Ctrl+Shift+【 | ctrl+shift+[BracketLeft] | null | ctrl+shift+[BracketLeft] | NO | -| Alt+BracketLeft | 【 | Alt+[ | 1 | Option+【 | alt+[BracketLeft] | null | alt+[BracketLeft] | NO | -| Ctrl+Alt+BracketLeft | “ | Ctrl+Alt+[ | 1 | Ctrl+Option+【 | ctrl+alt+[BracketLeft] | null | ctrl+alt+[BracketLeft] | NO | -| Shift+Alt+BracketLeft | 「 | Alt+[ | 2 | Shift+Option+【 | shift+alt+[BracketLeft] | null | shift+alt+[BracketLeft] | NO | -| Ctrl+Shift+Alt+BracketLeft | ” | Ctrl+Alt+[ | 2 | Ctrl+Shift+Option+【 | ctrl+shift+alt+[BracketLeft] | null | ctrl+shift+alt+[BracketLeft] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| BracketRight | 】 | ] | 1 | 】 | [BracketRight] | null | [BracketRight] | NO | -| Ctrl+BracketRight | 】 | Ctrl+] | 1 | Ctrl+】 | ctrl+[BracketRight] | null | ctrl+[BracketRight] | NO | -| Shift+BracketRight | 」 | ] | 2 | Shift+】 | shift+[BracketRight] | null | shift+[BracketRight] | NO | -| Ctrl+Shift+BracketRight | 」 | Ctrl+] | 2 | Ctrl+Shift+】 | ctrl+shift+[BracketRight] | null | ctrl+shift+[BracketRight] | NO | -| Alt+BracketRight | 】 | Alt+] | 1 | Option+】 | alt+[BracketRight] | null | alt+[BracketRight] | NO | -| Ctrl+Alt+BracketRight | ‘ | Ctrl+Alt+] | 1 | Ctrl+Option+】 | ctrl+alt+[BracketRight] | null | ctrl+alt+[BracketRight] | NO | -| Shift+Alt+BracketRight | 」 | Alt+] | 2 | Shift+Option+】 | shift+alt+[BracketRight] | null | shift+alt+[BracketRight] | NO | -| Ctrl+Shift+Alt+BracketRight | ’ | Ctrl+Alt+] | 2 | Ctrl+Shift+Option+】 | ctrl+shift+alt+[BracketRight] | null | ctrl+shift+alt+[BracketRight] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backslash | 、 | | | 、 | [Backslash] | null | [Backslash] | NO | -| Ctrl+Backslash | 、 | | | Ctrl+、 | ctrl+[Backslash] | null | ctrl+[Backslash] | NO | -| Shift+Backslash | | | | | Shift+、 | shift+[Backslash] | null | shift+[Backslash] | NO | -| Ctrl+Shift+Backslash | | | | | Ctrl+Shift+、 | ctrl+shift+[Backslash] | null | ctrl+shift+[Backslash] | NO | -| Alt+Backslash | 、 | | | Option+、 | alt+[Backslash] | null | alt+[Backslash] | NO | -| Ctrl+Alt+Backslash | « | | | Ctrl+Option+、 | ctrl+alt+[Backslash] | null | ctrl+alt+[Backslash] | NO | -| Shift+Alt+Backslash | | | | | Shift+Option+、 | shift+alt+[Backslash] | null | shift+alt+[Backslash] | NO | -| Ctrl+Shift+Alt+Backslash | » | | | Ctrl+Shift+Option+、 | ctrl+shift+alt+[Backslash] | null | ctrl+shift+alt+[Backslash] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlHash | --- | | | null | null | null | null | | -| Ctrl+IntlHash | --- | | | null | null | null | null | | -| Shift+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | -| Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | -| Shift+Alt+IntlHash | --- | | | null | null | null | null | | -| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Semicolon | ; | ; | | ; | ; | ; | [Semicolon] | NO | -| Ctrl+Semicolon | ; | Ctrl+; | | Ctrl+; | ctrl+; | Ctrl+; | ctrl+[Semicolon] | NO | -| Shift+Semicolon | : | Shift+; | | Shift+; | shift+; | Shift+; | shift+[Semicolon] | NO | -| Ctrl+Shift+Semicolon | : | Ctrl+Shift+; | | Ctrl+Shift+; | ctrl+shift+; | Ctrl+Shift+; | ctrl+shift+[Semicolon] | NO | -| Alt+Semicolon | ; | Alt+; | | Option+; | alt+; | Alt+; | alt+[Semicolon] | NO | -| Ctrl+Alt+Semicolon | … | Ctrl+Alt+; | | Ctrl+Option+; | ctrl+alt+; | Ctrl+Alt+; | ctrl+alt+[Semicolon] | NO | -| Shift+Alt+Semicolon | : | Shift+Alt+; | | Shift+Option+; | shift+alt+; | Shift+Alt+; | shift+alt+[Semicolon] | NO | -| Ctrl+Shift+Alt+Semicolon | Ú | Ctrl+Shift+Alt+; | | Ctrl+Shift+Option+; | ctrl+shift+alt+; | Ctrl+Shift+Alt+; | ctrl+shift+alt+[Semicolon] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Quote | ' | ' | | ' | ' | ' | [Quote] | | -| Ctrl+Quote | ' | Ctrl+' | | Ctrl+' | ctrl+' | Ctrl+' | ctrl+[Quote] | | -| Shift+Quote | " | Shift+' | | Shift+' | shift+' | Shift+' | shift+[Quote] | | -| Ctrl+Shift+Quote | " | Ctrl+Shift+' | | Ctrl+Shift+' | ctrl+shift+' | Ctrl+Shift+' | ctrl+shift+[Quote] | | -| Alt+Quote | ' | Alt+' | | Option+' | alt+' | Alt+' | alt+[Quote] | | -| Ctrl+Alt+Quote | æ | Ctrl+Alt+' | | Ctrl+Option+' | ctrl+alt+' | Ctrl+Alt+' | ctrl+alt+[Quote] | | -| Shift+Alt+Quote | " | Shift+Alt+' | | Shift+Option+' | shift+alt+' | Shift+Alt+' | shift+alt+[Quote] | | -| Ctrl+Shift+Alt+Quote | Æ | Ctrl+Shift+Alt+' | | Ctrl+Shift+Option+' | ctrl+shift+alt+' | Ctrl+Shift+Alt+' | ctrl+shift+alt+[Quote] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Backquote | · | | | · | [Backquote] | null | [Backquote] | NO | -| Ctrl+Backquote | · | | | Ctrl+· | ctrl+[Backquote] | null | ctrl+[Backquote] | NO | -| Shift+Backquote | ~ | | | Shift+· | shift+[Backquote] | null | shift+[Backquote] | NO | -| Ctrl+Shift+Backquote | ~ | | | Ctrl+Shift+· | ctrl+shift+[Backquote] | null | ctrl+shift+[Backquote] | NO | -| Alt+Backquote | · | | | Option+· | alt+[Backquote] | null | alt+[Backquote] | NO | -| Ctrl+Alt+Backquote | · | | | Ctrl+Option+· | ctrl+alt+[Backquote] | null | ctrl+alt+[Backquote] | NO | -| Shift+Alt+Backquote | ~ | | | Shift+Option+· | shift+alt+[Backquote] | null | shift+alt+[Backquote] | NO | -| Ctrl+Shift+Alt+Backquote | · | | | Ctrl+Shift+Option+· | ctrl+shift+alt+[Backquote] | null | ctrl+shift+alt+[Backquote] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Comma | , | , | | , | , | , | [Comma] | NO | -| Ctrl+Comma | , | Ctrl+, | | Ctrl+, | ctrl+, | Ctrl+, | ctrl+[Comma] | NO | -| Shift+Comma | 《 | Shift+, | | Shift+, | shift+, | Shift+, | shift+[Comma] | NO | -| Ctrl+Shift+Comma | 《 | Ctrl+Shift+, | | Ctrl+Shift+, | ctrl+shift+, | Ctrl+Shift+, | ctrl+shift+[Comma] | NO | -| Alt+Comma | , | Alt+, | | Option+, | alt+, | Alt+, | alt+[Comma] | NO | -| Ctrl+Alt+Comma | ≤ | Ctrl+Alt+, | | Ctrl+Option+, | ctrl+alt+, | Ctrl+Alt+, | ctrl+alt+[Comma] | NO | -| Shift+Alt+Comma | 《 | Shift+Alt+, | | Shift+Option+, | shift+alt+, | Shift+Alt+, | shift+alt+[Comma] | NO | -| Ctrl+Shift+Alt+Comma | ¯ | Ctrl+Shift+Alt+, | | Ctrl+Shift+Option+, | ctrl+shift+alt+, | Ctrl+Shift+Alt+, | ctrl+shift+alt+[Comma] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Period | 。 | . | | 。 | . | . | [Period] | NO | -| Ctrl+Period | 。 | Ctrl+. | | Ctrl+。 | ctrl+. | Ctrl+. | ctrl+[Period] | NO | -| Shift+Period | 》 | Shift+. | | Shift+。 | shift+. | Shift+. | shift+[Period] | NO | -| Ctrl+Shift+Period | 》 | Ctrl+Shift+. | | Ctrl+Shift+。 | ctrl+shift+. | Ctrl+Shift+. | ctrl+shift+[Period] | NO | -| Alt+Period | 。 | Alt+. | | Option+。 | alt+. | Alt+. | alt+[Period] | NO | -| Ctrl+Alt+Period | ≥ | Ctrl+Alt+. | | Ctrl+Option+。 | ctrl+alt+. | Ctrl+Alt+. | ctrl+alt+[Period] | NO | -| Shift+Alt+Period | 》 | Shift+Alt+. | | Shift+Option+。 | shift+alt+. | Shift+Alt+. | shift+alt+[Period] | NO | -| Ctrl+Shift+Alt+Period | ˘ | Ctrl+Shift+Alt+. | | Ctrl+Shift+Option+。 | ctrl+shift+alt+. | Ctrl+Shift+Alt+. | ctrl+shift+alt+[Period] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Slash | / | / | | / | / | / | [Slash] | | -| Ctrl+Slash | / | Ctrl+/ | | Ctrl+/ | ctrl+/ | Ctrl+/ | ctrl+[Slash] | | -| Shift+Slash | ? | Shift+/ | | Shift+/ | shift+/ | Shift+/ | shift+[Slash] | | -| Ctrl+Shift+Slash | ? | Ctrl+Shift+/ | | Ctrl+Shift+/ | ctrl+shift+/ | Ctrl+Shift+/ | ctrl+shift+[Slash] | | -| Alt+Slash | / | Alt+/ | | Option+/ | alt+/ | Alt+/ | alt+[Slash] | | -| Ctrl+Alt+Slash | ÷ | Ctrl+Alt+/ | | Ctrl+Option+/ | ctrl+alt+/ | Ctrl+Alt+/ | ctrl+alt+[Slash] | | -| Shift+Alt+Slash | ? | Shift+Alt+/ | | Shift+Option+/ | shift+alt+/ | Shift+Alt+/ | shift+alt+[Slash] | | -| Ctrl+Shift+Alt+Slash | ¿ | Ctrl+Shift+Alt+/ | | Ctrl+Shift+Option+/ | ctrl+shift+alt+/ | Ctrl+Shift+Alt+/ | ctrl+shift+alt+[Slash] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | -| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | -| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | -| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | -| Alt+ArrowUp | --- | Alt+UpArrow | | Option+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | -| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Option+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | -| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Option+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | -| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Option+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | -| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | -| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | -| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | -| Alt+Numpad0 | --- | Alt+NumPad0 | | Option+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | -| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Option+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | -| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Option+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | -| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Option+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlBackslash | § | | | § | [IntlBackslash] | null | [IntlBackslash] | NO | -| Ctrl+IntlBackslash | § | | | Ctrl+§ | ctrl+[IntlBackslash] | null | ctrl+[IntlBackslash] | NO | -| Shift+IntlBackslash | ± | | | Shift+§ | shift+[IntlBackslash] | null | shift+[IntlBackslash] | NO | -| Ctrl+Shift+IntlBackslash | ± | | | Ctrl+Shift+§ | ctrl+shift+[IntlBackslash] | null | ctrl+shift+[IntlBackslash] | NO | -| Alt+IntlBackslash | § | | | Option+§ | alt+[IntlBackslash] | null | alt+[IntlBackslash] | NO | -| Ctrl+Alt+IntlBackslash | § | | | Ctrl+Option+§ | ctrl+alt+[IntlBackslash] | null | ctrl+alt+[IntlBackslash] | NO | -| Shift+Alt+IntlBackslash | ± | | | Shift+Option+§ | shift+alt+[IntlBackslash] | null | shift+alt+[IntlBackslash] | NO | -| Ctrl+Shift+Alt+IntlBackslash | ± | | | Ctrl+Shift+Option+§ | ctrl+shift+alt+[IntlBackslash] | null | ctrl+shift+alt+[IntlBackslash] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | -| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | -| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | -| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | -| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | -| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | -| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | -| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | -| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | -| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | -| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | -| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | -| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | -| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | -| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/win_de_ch.js b/src/vs/workbench/services/keybinding/test/electron-browser/win_de_ch.js deleted file mode 100644 index a0e38d675e2..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/win_de_ch.js +++ /dev/null @@ -1,1093 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -define({ - Sleep: { - vkey: 'VK_SLEEP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - WakeUp: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - KeyA: { - vkey: 'VK_A', - value: 'a', - withShift: 'A', - withAltGr: '', - withShiftAltGr: '' - }, - KeyB: { - vkey: 'VK_B', - value: 'b', - withShift: 'B', - withAltGr: '', - withShiftAltGr: '' - }, - KeyC: { - vkey: 'VK_C', - value: 'c', - withShift: 'C', - withAltGr: '', - withShiftAltGr: '' - }, - KeyD: { - vkey: 'VK_D', - value: 'd', - withShift: 'D', - withAltGr: '', - withShiftAltGr: '' - }, - KeyE: { - vkey: 'VK_E', - value: 'e', - withShift: 'E', - withAltGr: '€', - withShiftAltGr: '' - }, - KeyF: { - vkey: 'VK_F', - value: 'f', - withShift: 'F', - withAltGr: '', - withShiftAltGr: '' - }, - KeyG: { - vkey: 'VK_G', - value: 'g', - withShift: 'G', - withAltGr: '', - withShiftAltGr: '' - }, - KeyH: { - vkey: 'VK_H', - value: 'h', - withShift: 'H', - withAltGr: '', - withShiftAltGr: '' - }, - KeyI: { - vkey: 'VK_I', - value: 'i', - withShift: 'I', - withAltGr: '', - withShiftAltGr: '' - }, - KeyJ: { - vkey: 'VK_J', - value: 'j', - withShift: 'J', - withAltGr: '', - withShiftAltGr: '' - }, - KeyK: { - vkey: 'VK_K', - value: 'k', - withShift: 'K', - withAltGr: '', - withShiftAltGr: '' - }, - KeyL: { - vkey: 'VK_L', - value: 'l', - withShift: 'L', - withAltGr: '', - withShiftAltGr: '' - }, - KeyM: { - vkey: 'VK_M', - value: 'm', - withShift: 'M', - withAltGr: '', - withShiftAltGr: '' - }, - KeyN: { - vkey: 'VK_N', - value: 'n', - withShift: 'N', - withAltGr: '', - withShiftAltGr: '' - }, - KeyO: { - vkey: 'VK_O', - value: 'o', - withShift: 'O', - withAltGr: '', - withShiftAltGr: '' - }, - KeyP: { - vkey: 'VK_P', - value: 'p', - withShift: 'P', - withAltGr: '', - withShiftAltGr: '' - }, - KeyQ: { - vkey: 'VK_Q', - value: 'q', - withShift: 'Q', - withAltGr: '', - withShiftAltGr: '' - }, - KeyR: { - vkey: 'VK_R', - value: 'r', - withShift: 'R', - withAltGr: '', - withShiftAltGr: '' - }, - KeyS: { - vkey: 'VK_S', - value: 's', - withShift: 'S', - withAltGr: '', - withShiftAltGr: '' - }, - KeyT: { - vkey: 'VK_T', - value: 't', - withShift: 'T', - withAltGr: '', - withShiftAltGr: '' - }, - KeyU: { - vkey: 'VK_U', - value: 'u', - withShift: 'U', - withAltGr: '', - withShiftAltGr: '' - }, - KeyV: { - vkey: 'VK_V', - value: 'v', - withShift: 'V', - withAltGr: '', - withShiftAltGr: '' - }, - KeyW: { - vkey: 'VK_W', - value: 'w', - withShift: 'W', - withAltGr: '', - withShiftAltGr: '' - }, - KeyX: { - vkey: 'VK_X', - value: 'x', - withShift: 'X', - withAltGr: '', - withShiftAltGr: '' - }, - KeyY: { - vkey: 'VK_Z', - value: 'z', - withShift: 'Z', - withAltGr: '', - withShiftAltGr: '' - }, - KeyZ: { - vkey: 'VK_Y', - value: 'y', - withShift: 'Y', - withAltGr: '', - withShiftAltGr: '' - }, - Digit1: { - vkey: 'VK_1', - value: '1', - withShift: '+', - withAltGr: '¦', - withShiftAltGr: '' - }, - Digit2: { - vkey: 'VK_2', - value: '2', - withShift: '"', - withAltGr: '@', - withShiftAltGr: '' - }, - Digit3: { - vkey: 'VK_3', - value: '3', - withShift: '*', - withAltGr: '#', - withShiftAltGr: '' - }, - Digit4: { - vkey: 'VK_4', - value: '4', - withShift: 'ç', - withAltGr: '°', - withShiftAltGr: '' - }, - Digit5: { - vkey: 'VK_5', - value: '5', - withShift: '%', - withAltGr: '§', - withShiftAltGr: '' - }, - Digit6: { - vkey: 'VK_6', - value: '6', - withShift: '&', - withAltGr: '¬', - withShiftAltGr: '' - }, - Digit7: { - vkey: 'VK_7', - value: '7', - withShift: '/', - withAltGr: '|', - withShiftAltGr: '' - }, - Digit8: { - vkey: 'VK_8', - value: '8', - withShift: '(', - withAltGr: '¢', - withShiftAltGr: '' - }, - Digit9: { - vkey: 'VK_9', - value: '9', - withShift: ')', - withAltGr: '', - withShiftAltGr: '' - }, - Digit0: { - vkey: 'VK_0', - value: '0', - withShift: '=', - withAltGr: '', - withShiftAltGr: '' - }, - Enter: { - vkey: 'VK_RETURN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Escape: { - vkey: 'VK_ESCAPE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Backspace: { - vkey: 'VK_BACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Tab: { - vkey: 'VK_TAB', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Space: { - vkey: 'VK_SPACE', - value: ' ', - withShift: ' ', - withAltGr: '', - withShiftAltGr: '' - }, - Minus: { - vkey: 'VK_OEM_4', - value: '\'', - withShift: '?', - withAltGr: '´', - withShiftAltGr: '' - }, - Equal: { - vkey: 'VK_OEM_6', - value: '^', - withShift: '`', - withAltGr: '~', - withShiftAltGr: '' - }, - BracketLeft: { - vkey: 'VK_OEM_1', - value: 'ü', - withShift: 'è', - withAltGr: '[', - withShiftAltGr: '' - }, - BracketRight: { - vkey: 'VK_OEM_3', - value: '¨', - withShift: '!', - withAltGr: ']', - withShiftAltGr: '' - }, - Backslash: { - vkey: 'VK_OEM_8', - value: '$', - withShift: '£', - withAltGr: '}', - withShiftAltGr: '' - }, - Semicolon: { - vkey: 'VK_OEM_7', - value: 'ö', - withShift: 'é', - withAltGr: '', - withShiftAltGr: '' - }, - Quote: { - vkey: 'VK_OEM_5', - value: 'ä', - withShift: 'à', - withAltGr: '{', - withShiftAltGr: '' - }, - Backquote: { - vkey: 'VK_OEM_2', - value: '§', - withShift: '°', - withAltGr: '', - withShiftAltGr: '' - }, - Comma: { - vkey: 'VK_OEM_COMMA', - value: ',', - withShift: ';', - withAltGr: '', - withShiftAltGr: '' - }, - Period: { - vkey: 'VK_OEM_PERIOD', - value: '.', - withShift: ':', - withAltGr: '', - withShiftAltGr: '' - }, - Slash: { - vkey: 'VK_OEM_MINUS', - value: '-', - withShift: '_', - withAltGr: '', - withShiftAltGr: '' - }, - CapsLock: { - vkey: 'VK_CAPITAL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F1: { - vkey: 'VK_F1', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F2: { - vkey: 'VK_F2', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F3: { - vkey: 'VK_F3', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F4: { - vkey: 'VK_F4', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F5: { - vkey: 'VK_F5', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F6: { - vkey: 'VK_F6', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F7: { - vkey: 'VK_F7', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F8: { - vkey: 'VK_F8', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F9: { - vkey: 'VK_F9', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F10: { - vkey: 'VK_F10', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F11: { - vkey: 'VK_F11', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F12: { - vkey: 'VK_F12', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PrintScreen: { - vkey: 'VK_SNAPSHOT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ScrollLock: { - vkey: 'VK_SCROLL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Pause: { - vkey: 'VK_NUMLOCK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Insert: { - vkey: 'VK_INSERT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Home: { - vkey: 'VK_HOME', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PageUp: { - vkey: 'VK_PRIOR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Delete: { - vkey: 'VK_DELETE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - End: { - vkey: 'VK_END', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PageDown: { - vkey: 'VK_NEXT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowRight: { - vkey: 'VK_RIGHT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowLeft: { - vkey: 'VK_LEFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowDown: { - vkey: 'VK_DOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowUp: { - vkey: 'VK_UP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumLock: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadDivide: { - vkey: 'VK_DIVIDE', - value: '/', - withShift: '/', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadMultiply: { - vkey: 'VK_MULTIPLY', - value: '*', - withShift: '*', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadSubtract: { - vkey: 'VK_SUBTRACT', - value: '-', - withShift: '-', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadAdd: { - vkey: 'VK_ADD', - value: '+', - withShift: '+', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadEnter: { - vkey: 'VK_RETURN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad1: { - vkey: 'VK_END', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad2: { - vkey: 'VK_DOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad3: { - vkey: 'VK_NEXT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad4: { - vkey: 'VK_LEFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad5: { - vkey: 'VK_CLEAR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad6: { - vkey: 'VK_RIGHT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad7: { - vkey: 'VK_HOME', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad8: { - vkey: 'VK_UP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad9: { - vkey: 'VK_PRIOR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad0: { - vkey: 'VK_INSERT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadDecimal: { - vkey: 'VK_DELETE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - IntlBackslash: { - vkey: 'VK_OEM_102', - value: '<', - withShift: '>', - withAltGr: '\\', - withShiftAltGr: '' - }, - ContextMenu: { - vkey: 'VK_APPS', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Power: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadEqual: { - vkey: 'VK_CLEAR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F13: { - vkey: 'VK_F13', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F14: { - vkey: 'VK_F14', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F15: { - vkey: 'VK_F15', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F16: { - vkey: 'VK_F16', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F17: { - vkey: 'VK_F17', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F18: { - vkey: 'VK_F18', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F19: { - vkey: 'VK_F19', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F20: { - vkey: 'VK_F20', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F21: { - vkey: 'VK_F21', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F22: { - vkey: 'VK_F22', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F23: { - vkey: 'VK_F23', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F24: { - vkey: 'VK_F24', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Help: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Undo: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Cut: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Copy: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Paste: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeMute: { - vkey: 'VK_VOLUME_MUTE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeUp: { - vkey: 'VK_VOLUME_UP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeDown: { - vkey: 'VK_VOLUME_DOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadComma: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - IntlRo: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - KanaMode: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - IntlYen: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Convert: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NonConvert: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang1: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang2: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang3: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang4: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ControlLeft: { - vkey: 'VK_CONTROL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ShiftLeft: { - vkey: 'VK_SHIFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AltLeft: { - vkey: 'VK_MENU', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MetaLeft: { - vkey: 'VK_LWIN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ControlRight: { - vkey: 'VK_CONTROL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ShiftRight: { - vkey: 'VK_SHIFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AltRight: { - vkey: 'VK_MENU', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MetaRight: { - vkey: 'VK_RWIN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaTrackNext: { - vkey: 'VK_MEDIA_NEXT_TRACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaTrackPrevious: { - vkey: 'VK_MEDIA_PREV_TRACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaStop: { - vkey: 'VK_MEDIA_STOP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Eject: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaPlayPause: { - vkey: 'VK_MEDIA_PLAY_PAUSE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaSelect: { - vkey: 'VK_LAUNCH_MEDIA_SELECT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchMail: { - vkey: 'VK_LAUNCH_MAIL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchApp2: { - vkey: 'VK_LAUNCH_APP2', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchApp1: { - vkey: 'VK_LAUNCH_APP1', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserSearch: { - vkey: 'VK_BROWSER_SEARCH', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserHome: { - vkey: 'VK_BROWSER_HOME', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserBack: { - vkey: 'VK_BROWSER_BACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserForward: { - vkey: 'VK_BROWSER_FORWARD', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserStop: { - vkey: 'VK_BROWSER_STOP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserRefresh: { - vkey: 'VK_BROWSER_REFRESH', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserFavorites: { - vkey: 'VK_BROWSER_FAVORITES', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - } -}); diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/win_de_ch.txt b/src/vs/workbench/services/keybinding/test/electron-browser/win_de_ch.txt deleted file mode 100644 index ac0575e250e..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/win_de_ch.txt +++ /dev/null @@ -1,284 +0,0 @@ ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyA | a | A | A | a | | -| Shift+KeyA | A | Shift+A | Shift+A | shift+a | | -| Ctrl+Alt+KeyA | --- | Ctrl+Alt+A | Ctrl+Alt+A | ctrl+alt+a | | -| Ctrl+Shift+Alt+KeyA | --- | Ctrl+Shift+Alt+A | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyB | b | B | B | b | | -| Shift+KeyB | B | Shift+B | Shift+B | shift+b | | -| Ctrl+Alt+KeyB | --- | Ctrl+Alt+B | Ctrl+Alt+B | ctrl+alt+b | | -| Ctrl+Shift+Alt+KeyB | --- | Ctrl+Shift+Alt+B | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyC | c | C | C | c | | -| Shift+KeyC | C | Shift+C | Shift+C | shift+c | | -| Ctrl+Alt+KeyC | --- | Ctrl+Alt+C | Ctrl+Alt+C | ctrl+alt+c | | -| Ctrl+Shift+Alt+KeyC | --- | Ctrl+Shift+Alt+C | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyD | d | D | D | d | | -| Shift+KeyD | D | Shift+D | Shift+D | shift+d | | -| Ctrl+Alt+KeyD | --- | Ctrl+Alt+D | Ctrl+Alt+D | ctrl+alt+d | | -| Ctrl+Shift+Alt+KeyD | --- | Ctrl+Shift+Alt+D | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyE | e | E | E | e | | -| Shift+KeyE | E | Shift+E | Shift+E | shift+e | | -| Ctrl+Alt+KeyE | € | Ctrl+Alt+E | Ctrl+Alt+E | ctrl+alt+e | | -| Ctrl+Shift+Alt+KeyE | --- | Ctrl+Shift+Alt+E | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyF | f | F | F | f | | -| Shift+KeyF | F | Shift+F | Shift+F | shift+f | | -| Ctrl+Alt+KeyF | --- | Ctrl+Alt+F | Ctrl+Alt+F | ctrl+alt+f | | -| Ctrl+Shift+Alt+KeyF | --- | Ctrl+Shift+Alt+F | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyG | g | G | G | g | | -| Shift+KeyG | G | Shift+G | Shift+G | shift+g | | -| Ctrl+Alt+KeyG | --- | Ctrl+Alt+G | Ctrl+Alt+G | ctrl+alt+g | | -| Ctrl+Shift+Alt+KeyG | --- | Ctrl+Shift+Alt+G | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyH | h | H | H | h | | -| Shift+KeyH | H | Shift+H | Shift+H | shift+h | | -| Ctrl+Alt+KeyH | --- | Ctrl+Alt+H | Ctrl+Alt+H | ctrl+alt+h | | -| Ctrl+Shift+Alt+KeyH | --- | Ctrl+Shift+Alt+H | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyI | i | I | I | i | | -| Shift+KeyI | I | Shift+I | Shift+I | shift+i | | -| Ctrl+Alt+KeyI | --- | Ctrl+Alt+I | Ctrl+Alt+I | ctrl+alt+i | | -| Ctrl+Shift+Alt+KeyI | --- | Ctrl+Shift+Alt+I | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyJ | j | J | J | j | | -| Shift+KeyJ | J | Shift+J | Shift+J | shift+j | | -| Ctrl+Alt+KeyJ | --- | Ctrl+Alt+J | Ctrl+Alt+J | ctrl+alt+j | | -| Ctrl+Shift+Alt+KeyJ | --- | Ctrl+Shift+Alt+J | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyK | k | K | K | k | | -| Shift+KeyK | K | Shift+K | Shift+K | shift+k | | -| Ctrl+Alt+KeyK | --- | Ctrl+Alt+K | Ctrl+Alt+K | ctrl+alt+k | | -| Ctrl+Shift+Alt+KeyK | --- | Ctrl+Shift+Alt+K | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyL | l | L | L | l | | -| Shift+KeyL | L | Shift+L | Shift+L | shift+l | | -| Ctrl+Alt+KeyL | --- | Ctrl+Alt+L | Ctrl+Alt+L | ctrl+alt+l | | -| Ctrl+Shift+Alt+KeyL | --- | Ctrl+Shift+Alt+L | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyM | m | M | M | m | | -| Shift+KeyM | M | Shift+M | Shift+M | shift+m | | -| Ctrl+Alt+KeyM | --- | Ctrl+Alt+M | Ctrl+Alt+M | ctrl+alt+m | | -| Ctrl+Shift+Alt+KeyM | --- | Ctrl+Shift+Alt+M | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyN | n | N | N | n | | -| Shift+KeyN | N | Shift+N | Shift+N | shift+n | | -| Ctrl+Alt+KeyN | --- | Ctrl+Alt+N | Ctrl+Alt+N | ctrl+alt+n | | -| Ctrl+Shift+Alt+KeyN | --- | Ctrl+Shift+Alt+N | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyO | o | O | O | o | | -| Shift+KeyO | O | Shift+O | Shift+O | shift+o | | -| Ctrl+Alt+KeyO | --- | Ctrl+Alt+O | Ctrl+Alt+O | ctrl+alt+o | | -| Ctrl+Shift+Alt+KeyO | --- | Ctrl+Shift+Alt+O | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyP | p | P | P | p | | -| Shift+KeyP | P | Shift+P | Shift+P | shift+p | | -| Ctrl+Alt+KeyP | --- | Ctrl+Alt+P | Ctrl+Alt+P | ctrl+alt+p | | -| Ctrl+Shift+Alt+KeyP | --- | Ctrl+Shift+Alt+P | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyQ | q | Q | Q | q | | -| Shift+KeyQ | Q | Shift+Q | Shift+Q | shift+q | | -| Ctrl+Alt+KeyQ | --- | Ctrl+Alt+Q | Ctrl+Alt+Q | ctrl+alt+q | | -| Ctrl+Shift+Alt+KeyQ | --- | Ctrl+Shift+Alt+Q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyR | r | R | R | r | | -| Shift+KeyR | R | Shift+R | Shift+R | shift+r | | -| Ctrl+Alt+KeyR | --- | Ctrl+Alt+R | Ctrl+Alt+R | ctrl+alt+r | | -| Ctrl+Shift+Alt+KeyR | --- | Ctrl+Shift+Alt+R | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyS | s | S | S | s | | -| Shift+KeyS | S | Shift+S | Shift+S | shift+s | | -| Ctrl+Alt+KeyS | --- | Ctrl+Alt+S | Ctrl+Alt+S | ctrl+alt+s | | -| Ctrl+Shift+Alt+KeyS | --- | Ctrl+Shift+Alt+S | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyT | t | T | T | t | | -| Shift+KeyT | T | Shift+T | Shift+T | shift+t | | -| Ctrl+Alt+KeyT | --- | Ctrl+Alt+T | Ctrl+Alt+T | ctrl+alt+t | | -| Ctrl+Shift+Alt+KeyT | --- | Ctrl+Shift+Alt+T | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyU | u | U | U | u | | -| Shift+KeyU | U | Shift+U | Shift+U | shift+u | | -| Ctrl+Alt+KeyU | --- | Ctrl+Alt+U | Ctrl+Alt+U | ctrl+alt+u | | -| Ctrl+Shift+Alt+KeyU | --- | Ctrl+Shift+Alt+U | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyV | v | V | V | v | | -| Shift+KeyV | V | Shift+V | Shift+V | shift+v | | -| Ctrl+Alt+KeyV | --- | Ctrl+Alt+V | Ctrl+Alt+V | ctrl+alt+v | | -| Ctrl+Shift+Alt+KeyV | --- | Ctrl+Shift+Alt+V | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyW | w | W | W | w | | -| Shift+KeyW | W | Shift+W | Shift+W | shift+w | | -| Ctrl+Alt+KeyW | --- | Ctrl+Alt+W | Ctrl+Alt+W | ctrl+alt+w | | -| Ctrl+Shift+Alt+KeyW | --- | Ctrl+Shift+Alt+W | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyX | x | X | X | x | | -| Shift+KeyX | X | Shift+X | Shift+X | shift+x | | -| Ctrl+Alt+KeyX | --- | Ctrl+Alt+X | Ctrl+Alt+X | ctrl+alt+x | | -| Ctrl+Shift+Alt+KeyX | --- | Ctrl+Shift+Alt+X | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyY | z | Z | Z | z | | -| Shift+KeyY | Z | Shift+Z | Shift+Z | shift+z | | -| Ctrl+Alt+KeyY | --- | Ctrl+Alt+Z | Ctrl+Alt+Z | ctrl+alt+z | | -| Ctrl+Shift+Alt+KeyY | --- | Ctrl+Shift+Alt+Z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyZ | y | Y | Y | y | | -| Shift+KeyZ | Y | Shift+Y | Shift+Y | shift+y | | -| Ctrl+Alt+KeyZ | --- | Ctrl+Alt+Y | Ctrl+Alt+Y | ctrl+alt+y | | -| Ctrl+Shift+Alt+KeyZ | --- | Ctrl+Shift+Alt+Y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit1 | 1 | 1 | 1 | 1 | | -| Shift+Digit1 | + | Shift+1 | Shift+1 | shift+1 | | -| Ctrl+Alt+Digit1 | ¦ | Ctrl+Alt+1 | Ctrl+Alt+1 | ctrl+alt+1 | | -| Ctrl+Shift+Alt+Digit1 | --- | Ctrl+Shift+Alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit2 | 2 | 2 | 2 | 2 | | -| Shift+Digit2 | " | Shift+2 | Shift+2 | shift+2 | | -| Ctrl+Alt+Digit2 | @ | Ctrl+Alt+2 | Ctrl+Alt+2 | ctrl+alt+2 | | -| Ctrl+Shift+Alt+Digit2 | --- | Ctrl+Shift+Alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit3 | 3 | 3 | 3 | 3 | | -| Shift+Digit3 | * | Shift+3 | Shift+3 | shift+3 | | -| Ctrl+Alt+Digit3 | # | Ctrl+Alt+3 | Ctrl+Alt+3 | ctrl+alt+3 | | -| Ctrl+Shift+Alt+Digit3 | --- | Ctrl+Shift+Alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit4 | 4 | 4 | 4 | 4 | | -| Shift+Digit4 | ç | Shift+4 | Shift+4 | shift+4 | | -| Ctrl+Alt+Digit4 | ° | Ctrl+Alt+4 | Ctrl+Alt+4 | ctrl+alt+4 | | -| Ctrl+Shift+Alt+Digit4 | --- | Ctrl+Shift+Alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit5 | 5 | 5 | 5 | 5 | | -| Shift+Digit5 | % | Shift+5 | Shift+5 | shift+5 | | -| Ctrl+Alt+Digit5 | § | Ctrl+Alt+5 | Ctrl+Alt+5 | ctrl+alt+5 | | -| Ctrl+Shift+Alt+Digit5 | --- | Ctrl+Shift+Alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit6 | 6 | 6 | 6 | 6 | | -| Shift+Digit6 | & | Shift+6 | Shift+6 | shift+6 | | -| Ctrl+Alt+Digit6 | ¬ | Ctrl+Alt+6 | Ctrl+Alt+6 | ctrl+alt+6 | | -| Ctrl+Shift+Alt+Digit6 | --- | Ctrl+Shift+Alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit7 | 7 | 7 | 7 | 7 | | -| Shift+Digit7 | / | Shift+7 | Shift+7 | shift+7 | | -| Ctrl+Alt+Digit7 | | | Ctrl+Alt+7 | Ctrl+Alt+7 | ctrl+alt+7 | | -| Ctrl+Shift+Alt+Digit7 | --- | Ctrl+Shift+Alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit8 | 8 | 8 | 8 | 8 | | -| Shift+Digit8 | ( | Shift+8 | Shift+8 | shift+8 | | -| Ctrl+Alt+Digit8 | ¢ | Ctrl+Alt+8 | Ctrl+Alt+8 | ctrl+alt+8 | | -| Ctrl+Shift+Alt+Digit8 | --- | Ctrl+Shift+Alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit9 | 9 | 9 | 9 | 9 | | -| Shift+Digit9 | ) | Shift+9 | Shift+9 | shift+9 | | -| Ctrl+Alt+Digit9 | --- | Ctrl+Alt+9 | Ctrl+Alt+9 | ctrl+alt+9 | | -| Ctrl+Shift+Alt+Digit9 | --- | Ctrl+Shift+Alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit0 | 0 | 0 | 0 | 0 | | -| Shift+Digit0 | = | Shift+0 | Shift+0 | shift+0 | | -| Ctrl+Alt+Digit0 | --- | Ctrl+Alt+0 | Ctrl+Alt+0 | ctrl+alt+0 | | -| Ctrl+Shift+Alt+Digit0 | --- | Ctrl+Shift+Alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| Minus | ' | [ | ' | oem_4 | NO | -| Shift+Minus | ? | Shift+[ | Shift+' | shift+oem_4 | NO | -| Ctrl+Alt+Minus | ´ | Ctrl+Alt+[ | Ctrl+Alt+' | ctrl+alt+oem_4 | NO | -| Ctrl+Shift+Alt+Minus | --- | Ctrl+Shift+Alt+[ | Ctrl+Shift+Alt+' | ctrl+shift+alt+oem_4 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Equal | ^ | ] | ^ | oem_6 | NO | -| Shift+Equal | ` | Shift+] | Shift+^ | shift+oem_6 | NO | -| Ctrl+Alt+Equal | ~ | Ctrl+Alt+] | Ctrl+Alt+^ | ctrl+alt+oem_6 | NO | -| Ctrl+Shift+Alt+Equal | --- | Ctrl+Shift+Alt+] | Ctrl+Shift+Alt+^ | ctrl+shift+alt+oem_6 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| BracketLeft | ü | ; | ü | oem_1 | NO | -| Shift+BracketLeft | è | Shift+; | Shift+ü | shift+oem_1 | NO | -| Ctrl+Alt+BracketLeft | [ | Ctrl+Alt+; | Ctrl+Alt+ü | ctrl+alt+oem_1 | NO | -| Ctrl+Shift+Alt+BracketLeft | --- | Ctrl+Shift+Alt+; | Ctrl+Shift+Alt+ü | ctrl+shift+alt+oem_1 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| BracketRight | ¨ | ` | ¨ | oem_3 | NO | -| Shift+BracketRight | ! | Shift+` | Shift+¨ | shift+oem_3 | NO | -| Ctrl+Alt+BracketRight | ] | Ctrl+Alt+` | Ctrl+Alt+¨ | ctrl+alt+oem_3 | NO | -| Ctrl+Shift+Alt+BracketRight | --- | Ctrl+Shift+Alt+` | Ctrl+Shift+Alt+¨ | ctrl+shift+alt+oem_3 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Backslash | $ | OEM_8 | $ | oem_8 | NO | -| Shift+Backslash | £ | Shift+OEM_8 | Shift+$ | shift+oem_8 | NO | -| Ctrl+Alt+Backslash | } | Ctrl+Alt+OEM_8 | Ctrl+Alt+$ | ctrl+alt+oem_8 | NO | -| Ctrl+Shift+Alt+Backslash | --- | Ctrl+Shift+Alt+OEM_8 | Ctrl+Shift+Alt+$ | ctrl+shift+alt+oem_8 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlHash | --- | null | null | null | NO | -| Shift+IntlHash | --- | null | null | null | NO | -| Ctrl+Alt+IntlHash | --- | null | null | null | NO | -| Ctrl+Shift+Alt+IntlHash | --- | null | null | null | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| Semicolon | ö | ' | ö | oem_7 | NO | -| Shift+Semicolon | é | Shift+' | Shift+ö | shift+oem_7 | NO | -| Ctrl+Alt+Semicolon | --- | Ctrl+Alt+' | Ctrl+Alt+ö | ctrl+alt+oem_7 | NO | -| Ctrl+Shift+Alt+Semicolon | --- | Ctrl+Shift+Alt+' | Ctrl+Shift+Alt+ö | ctrl+shift+alt+oem_7 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Quote | ä | \ | ä | oem_5 | NO | -| Shift+Quote | à | Shift+\ | Shift+ä | shift+oem_5 | NO | -| Ctrl+Alt+Quote | { | Ctrl+Alt+\ | Ctrl+Alt+ä | ctrl+alt+oem_5 | NO | -| Ctrl+Shift+Alt+Quote | --- | Ctrl+Shift+Alt+\ | Ctrl+Shift+Alt+ä | ctrl+shift+alt+oem_5 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Backquote | § | / | § | oem_2 | NO | -| Shift+Backquote | ° | Shift+/ | Shift+§ | shift+oem_2 | NO | -| Ctrl+Alt+Backquote | --- | Ctrl+Alt+/ | Ctrl+Alt+§ | ctrl+alt+oem_2 | NO | -| Ctrl+Shift+Alt+Backquote | --- | Ctrl+Shift+Alt+/ | Ctrl+Shift+Alt+§ | ctrl+shift+alt+oem_2 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Comma | , | , | , | oem_comma | NO | -| Shift+Comma | ; | Shift+, | Shift+, | shift+oem_comma | NO | -| Ctrl+Alt+Comma | --- | Ctrl+Alt+, | Ctrl+Alt+, | ctrl+alt+oem_comma | NO | -| Ctrl+Shift+Alt+Comma | --- | Ctrl+Shift+Alt+, | Ctrl+Shift+Alt+, | ctrl+shift+alt+oem_comma | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Period | . | . | . | oem_period | NO | -| Shift+Period | : | Shift+. | Shift+. | shift+oem_period | NO | -| Ctrl+Alt+Period | --- | Ctrl+Alt+. | Ctrl+Alt+. | ctrl+alt+oem_period | NO | -| Ctrl+Shift+Alt+Period | --- | Ctrl+Shift+Alt+. | Ctrl+Shift+Alt+. | ctrl+shift+alt+oem_period | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Slash | - | - | - | oem_minus | NO | -| Shift+Slash | _ | Shift+- | Shift+- | shift+oem_minus | NO | -| Ctrl+Alt+Slash | --- | Ctrl+Alt+- | Ctrl+Alt+- | ctrl+alt+oem_minus | NO | -| Ctrl+Shift+Alt+Slash | --- | Ctrl+Shift+Alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+oem_minus | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| ArrowUp | --- | UpArrow | UpArrow | up | | -| Shift+ArrowUp | --- | Shift+UpArrow | Shift+UpArrow | shift+up | | -| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | Ctrl+Alt+UpArrow | ctrl+alt+up | | -| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Numpad0 | --- | NumPad0 | NumPad0 | numpad0 | | -| Shift+Numpad0 | --- | Shift+NumPad0 | Shift+NumPad0 | shift+numpad0 | | -| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | | -| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlBackslash | < | OEM_102 | < | oem_102 | NO | -| Shift+IntlBackslash | > | Shift+OEM_102 | Shift+< | shift+oem_102 | NO | -| Ctrl+Alt+IntlBackslash | \ | Ctrl+Alt+OEM_102 | Ctrl+Alt+< | ctrl+alt+oem_102 | NO | -| Ctrl+Shift+Alt+IntlBackslash | --- | Ctrl+Shift+Alt+OEM_102 | Ctrl+Shift+Alt+< | ctrl+shift+alt+oem_102 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlRo | --- | null | null | null | NO | -| Shift+IntlRo | --- | null | null | null | NO | -| Ctrl+Alt+IntlRo | --- | null | null | null | NO | -| Ctrl+Shift+Alt+IntlRo | --- | null | null | null | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlYen | --- | null | null | null | NO | -| Shift+IntlYen | --- | null | null | null | NO | -| Ctrl+Alt+IntlYen | --- | null | null | null | NO | -| Ctrl+Shift+Alt+IntlYen | --- | null | null | null | NO | ------------------------------------------------------------------------------------------------------------------------------------------ \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/win_en_us.js b/src/vs/workbench/services/keybinding/test/electron-browser/win_en_us.js deleted file mode 100644 index 6961ed286fe..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/win_en_us.js +++ /dev/null @@ -1,1093 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -define({ - Sleep: { - vkey: 'VK_SLEEP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - WakeUp: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - KeyA: { - vkey: 'VK_A', - value: 'a', - withShift: 'A', - withAltGr: '', - withShiftAltGr: '' - }, - KeyB: { - vkey: 'VK_B', - value: 'b', - withShift: 'B', - withAltGr: '', - withShiftAltGr: '' - }, - KeyC: { - vkey: 'VK_C', - value: 'c', - withShift: 'C', - withAltGr: '', - withShiftAltGr: '' - }, - KeyD: { - vkey: 'VK_D', - value: 'd', - withShift: 'D', - withAltGr: '', - withShiftAltGr: '' - }, - KeyE: { - vkey: 'VK_E', - value: 'e', - withShift: 'E', - withAltGr: '', - withShiftAltGr: '' - }, - KeyF: { - vkey: 'VK_F', - value: 'f', - withShift: 'F', - withAltGr: '', - withShiftAltGr: '' - }, - KeyG: { - vkey: 'VK_G', - value: 'g', - withShift: 'G', - withAltGr: '', - withShiftAltGr: '' - }, - KeyH: { - vkey: 'VK_H', - value: 'h', - withShift: 'H', - withAltGr: '', - withShiftAltGr: '' - }, - KeyI: { - vkey: 'VK_I', - value: 'i', - withShift: 'I', - withAltGr: '', - withShiftAltGr: '' - }, - KeyJ: { - vkey: 'VK_J', - value: 'j', - withShift: 'J', - withAltGr: '', - withShiftAltGr: '' - }, - KeyK: { - vkey: 'VK_K', - value: 'k', - withShift: 'K', - withAltGr: '', - withShiftAltGr: '' - }, - KeyL: { - vkey: 'VK_L', - value: 'l', - withShift: 'L', - withAltGr: '', - withShiftAltGr: '' - }, - KeyM: { - vkey: 'VK_M', - value: 'm', - withShift: 'M', - withAltGr: '', - withShiftAltGr: '' - }, - KeyN: { - vkey: 'VK_N', - value: 'n', - withShift: 'N', - withAltGr: '', - withShiftAltGr: '' - }, - KeyO: { - vkey: 'VK_O', - value: 'o', - withShift: 'O', - withAltGr: '', - withShiftAltGr: '' - }, - KeyP: { - vkey: 'VK_P', - value: 'p', - withShift: 'P', - withAltGr: '', - withShiftAltGr: '' - }, - KeyQ: { - vkey: 'VK_Q', - value: 'q', - withShift: 'Q', - withAltGr: '', - withShiftAltGr: '' - }, - KeyR: { - vkey: 'VK_R', - value: 'r', - withShift: 'R', - withAltGr: '', - withShiftAltGr: '' - }, - KeyS: { - vkey: 'VK_S', - value: 's', - withShift: 'S', - withAltGr: '', - withShiftAltGr: '' - }, - KeyT: { - vkey: 'VK_T', - value: 't', - withShift: 'T', - withAltGr: '', - withShiftAltGr: '' - }, - KeyU: { - vkey: 'VK_U', - value: 'u', - withShift: 'U', - withAltGr: '', - withShiftAltGr: '' - }, - KeyV: { - vkey: 'VK_V', - value: 'v', - withShift: 'V', - withAltGr: '', - withShiftAltGr: '' - }, - KeyW: { - vkey: 'VK_W', - value: 'w', - withShift: 'W', - withAltGr: '', - withShiftAltGr: '' - }, - KeyX: { - vkey: 'VK_X', - value: 'x', - withShift: 'X', - withAltGr: '', - withShiftAltGr: '' - }, - KeyY: { - vkey: 'VK_Y', - value: 'y', - withShift: 'Y', - withAltGr: '', - withShiftAltGr: '' - }, - KeyZ: { - vkey: 'VK_Z', - value: 'z', - withShift: 'Z', - withAltGr: '', - withShiftAltGr: '' - }, - Digit1: { - vkey: 'VK_1', - value: '1', - withShift: '!', - withAltGr: '', - withShiftAltGr: '' - }, - Digit2: { - vkey: 'VK_2', - value: '2', - withShift: '@', - withAltGr: '', - withShiftAltGr: '' - }, - Digit3: { - vkey: 'VK_3', - value: '3', - withShift: '#', - withAltGr: '', - withShiftAltGr: '' - }, - Digit4: { - vkey: 'VK_4', - value: '4', - withShift: '$', - withAltGr: '', - withShiftAltGr: '' - }, - Digit5: { - vkey: 'VK_5', - value: '5', - withShift: '%', - withAltGr: '', - withShiftAltGr: '' - }, - Digit6: { - vkey: 'VK_6', - value: '6', - withShift: '^', - withAltGr: '', - withShiftAltGr: '' - }, - Digit7: { - vkey: 'VK_7', - value: '7', - withShift: '&', - withAltGr: '', - withShiftAltGr: '' - }, - Digit8: { - vkey: 'VK_8', - value: '8', - withShift: '*', - withAltGr: '', - withShiftAltGr: '' - }, - Digit9: { - vkey: 'VK_9', - value: '9', - withShift: '(', - withAltGr: '', - withShiftAltGr: '' - }, - Digit0: { - vkey: 'VK_0', - value: '0', - withShift: ')', - withAltGr: '', - withShiftAltGr: '' - }, - Enter: { - vkey: 'VK_RETURN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Escape: { - vkey: 'VK_ESCAPE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Backspace: { - vkey: 'VK_BACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Tab: { - vkey: 'VK_TAB', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Space: { - vkey: 'VK_SPACE', - value: ' ', - withShift: ' ', - withAltGr: '', - withShiftAltGr: '' - }, - Minus: { - vkey: 'VK_OEM_MINUS', - value: '-', - withShift: '_', - withAltGr: '', - withShiftAltGr: '' - }, - Equal: { - vkey: 'VK_OEM_PLUS', - value: '=', - withShift: '+', - withAltGr: '', - withShiftAltGr: '' - }, - BracketLeft: { - vkey: 'VK_OEM_4', - value: '[', - withShift: '{', - withAltGr: '', - withShiftAltGr: '' - }, - BracketRight: { - vkey: 'VK_OEM_6', - value: ']', - withShift: '}', - withAltGr: '', - withShiftAltGr: '' - }, - Backslash: { - vkey: 'VK_OEM_5', - value: '\\', - withShift: '|', - withAltGr: '', - withShiftAltGr: '' - }, - Semicolon: { - vkey: 'VK_OEM_1', - value: ';', - withShift: ':', - withAltGr: '', - withShiftAltGr: '' - }, - Quote: { - vkey: 'VK_OEM_7', - value: '\'', - withShift: '"', - withAltGr: '', - withShiftAltGr: '' - }, - Backquote: { - vkey: 'VK_OEM_3', - value: '`', - withShift: '~', - withAltGr: '', - withShiftAltGr: '' - }, - Comma: { - vkey: 'VK_OEM_COMMA', - value: ',', - withShift: '<', - withAltGr: '', - withShiftAltGr: '' - }, - Period: { - vkey: 'VK_OEM_PERIOD', - value: '.', - withShift: '>', - withAltGr: '', - withShiftAltGr: '' - }, - Slash: { - vkey: 'VK_OEM_2', - value: '/', - withShift: '?', - withAltGr: '', - withShiftAltGr: '' - }, - CapsLock: { - vkey: 'VK_CAPITAL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F1: { - vkey: 'VK_F1', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F2: { - vkey: 'VK_F2', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F3: { - vkey: 'VK_F3', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F4: { - vkey: 'VK_F4', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F5: { - vkey: 'VK_F5', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F6: { - vkey: 'VK_F6', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F7: { - vkey: 'VK_F7', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F8: { - vkey: 'VK_F8', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F9: { - vkey: 'VK_F9', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F10: { - vkey: 'VK_F10', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F11: { - vkey: 'VK_F11', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F12: { - vkey: 'VK_F12', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PrintScreen: { - vkey: 'VK_SNAPSHOT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ScrollLock: { - vkey: 'VK_SCROLL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Pause: { - vkey: 'VK_NUMLOCK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Insert: { - vkey: 'VK_INSERT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Home: { - vkey: 'VK_HOME', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PageUp: { - vkey: 'VK_PRIOR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Delete: { - vkey: 'VK_DELETE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - End: { - vkey: 'VK_END', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PageDown: { - vkey: 'VK_NEXT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowRight: { - vkey: 'VK_RIGHT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowLeft: { - vkey: 'VK_LEFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowDown: { - vkey: 'VK_DOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowUp: { - vkey: 'VK_UP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumLock: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadDivide: { - vkey: 'VK_DIVIDE', - value: '/', - withShift: '/', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadMultiply: { - vkey: 'VK_MULTIPLY', - value: '*', - withShift: '*', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadSubtract: { - vkey: 'VK_SUBTRACT', - value: '-', - withShift: '-', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadAdd: { - vkey: 'VK_ADD', - value: '+', - withShift: '+', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadEnter: { - vkey: 'VK_RETURN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad1: { - vkey: 'VK_END', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad2: { - vkey: 'VK_DOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad3: { - vkey: 'VK_NEXT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad4: { - vkey: 'VK_LEFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad5: { - vkey: 'VK_CLEAR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad6: { - vkey: 'VK_RIGHT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad7: { - vkey: 'VK_HOME', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad8: { - vkey: 'VK_UP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad9: { - vkey: 'VK_PRIOR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad0: { - vkey: 'VK_INSERT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadDecimal: { - vkey: 'VK_DELETE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - IntlBackslash: { - vkey: 'VK_OEM_102', - value: '\\', - withShift: '|', - withAltGr: '', - withShiftAltGr: '' - }, - ContextMenu: { - vkey: 'VK_APPS', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Power: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadEqual: { - vkey: 'VK_CLEAR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F13: { - vkey: 'VK_F13', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F14: { - vkey: 'VK_F14', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F15: { - vkey: 'VK_F15', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F16: { - vkey: 'VK_F16', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F17: { - vkey: 'VK_F17', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F18: { - vkey: 'VK_F18', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F19: { - vkey: 'VK_F19', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F20: { - vkey: 'VK_F20', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F21: { - vkey: 'VK_F21', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F22: { - vkey: 'VK_F22', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F23: { - vkey: 'VK_F23', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F24: { - vkey: 'VK_F24', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Help: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Undo: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Cut: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Copy: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Paste: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeMute: { - vkey: 'VK_VOLUME_MUTE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeUp: { - vkey: 'VK_VOLUME_UP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeDown: { - vkey: 'VK_VOLUME_DOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadComma: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - IntlRo: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - KanaMode: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - IntlYen: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Convert: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NonConvert: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang1: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang2: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang3: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang4: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ControlLeft: { - vkey: 'VK_CONTROL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ShiftLeft: { - vkey: 'VK_SHIFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AltLeft: { - vkey: 'VK_MENU', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MetaLeft: { - vkey: 'VK_LWIN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ControlRight: { - vkey: 'VK_CONTROL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ShiftRight: { - vkey: 'VK_SHIFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AltRight: { - vkey: 'VK_MENU', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MetaRight: { - vkey: 'VK_RWIN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaTrackNext: { - vkey: 'VK_MEDIA_NEXT_TRACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaTrackPrevious: { - vkey: 'VK_MEDIA_PREV_TRACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaStop: { - vkey: 'VK_MEDIA_STOP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Eject: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaPlayPause: { - vkey: 'VK_MEDIA_PLAY_PAUSE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaSelect: { - vkey: 'VK_LAUNCH_MEDIA_SELECT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchMail: { - vkey: 'VK_LAUNCH_MAIL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchApp2: { - vkey: 'VK_LAUNCH_APP2', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchApp1: { - vkey: 'VK_LAUNCH_APP1', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserSearch: { - vkey: 'VK_BROWSER_SEARCH', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserHome: { - vkey: 'VK_BROWSER_HOME', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserBack: { - vkey: 'VK_BROWSER_BACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserForward: { - vkey: 'VK_BROWSER_FORWARD', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserStop: { - vkey: 'VK_BROWSER_STOP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserRefresh: { - vkey: 'VK_BROWSER_REFRESH', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserFavorites: { - vkey: 'VK_BROWSER_FAVORITES', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - } -}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/win_en_us.txt b/src/vs/workbench/services/keybinding/test/electron-browser/win_en_us.txt deleted file mode 100644 index b011bd0be56..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/win_en_us.txt +++ /dev/null @@ -1,284 +0,0 @@ ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyA | a | A | A | a | | -| Shift+KeyA | A | Shift+A | Shift+A | shift+a | | -| Ctrl+Alt+KeyA | --- | Ctrl+Alt+A | Ctrl+Alt+A | ctrl+alt+a | | -| Ctrl+Shift+Alt+KeyA | --- | Ctrl+Shift+Alt+A | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyB | b | B | B | b | | -| Shift+KeyB | B | Shift+B | Shift+B | shift+b | | -| Ctrl+Alt+KeyB | --- | Ctrl+Alt+B | Ctrl+Alt+B | ctrl+alt+b | | -| Ctrl+Shift+Alt+KeyB | --- | Ctrl+Shift+Alt+B | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyC | c | C | C | c | | -| Shift+KeyC | C | Shift+C | Shift+C | shift+c | | -| Ctrl+Alt+KeyC | --- | Ctrl+Alt+C | Ctrl+Alt+C | ctrl+alt+c | | -| Ctrl+Shift+Alt+KeyC | --- | Ctrl+Shift+Alt+C | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyD | d | D | D | d | | -| Shift+KeyD | D | Shift+D | Shift+D | shift+d | | -| Ctrl+Alt+KeyD | --- | Ctrl+Alt+D | Ctrl+Alt+D | ctrl+alt+d | | -| Ctrl+Shift+Alt+KeyD | --- | Ctrl+Shift+Alt+D | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyE | e | E | E | e | | -| Shift+KeyE | E | Shift+E | Shift+E | shift+e | | -| Ctrl+Alt+KeyE | --- | Ctrl+Alt+E | Ctrl+Alt+E | ctrl+alt+e | | -| Ctrl+Shift+Alt+KeyE | --- | Ctrl+Shift+Alt+E | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyF | f | F | F | f | | -| Shift+KeyF | F | Shift+F | Shift+F | shift+f | | -| Ctrl+Alt+KeyF | --- | Ctrl+Alt+F | Ctrl+Alt+F | ctrl+alt+f | | -| Ctrl+Shift+Alt+KeyF | --- | Ctrl+Shift+Alt+F | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyG | g | G | G | g | | -| Shift+KeyG | G | Shift+G | Shift+G | shift+g | | -| Ctrl+Alt+KeyG | --- | Ctrl+Alt+G | Ctrl+Alt+G | ctrl+alt+g | | -| Ctrl+Shift+Alt+KeyG | --- | Ctrl+Shift+Alt+G | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyH | h | H | H | h | | -| Shift+KeyH | H | Shift+H | Shift+H | shift+h | | -| Ctrl+Alt+KeyH | --- | Ctrl+Alt+H | Ctrl+Alt+H | ctrl+alt+h | | -| Ctrl+Shift+Alt+KeyH | --- | Ctrl+Shift+Alt+H | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyI | i | I | I | i | | -| Shift+KeyI | I | Shift+I | Shift+I | shift+i | | -| Ctrl+Alt+KeyI | --- | Ctrl+Alt+I | Ctrl+Alt+I | ctrl+alt+i | | -| Ctrl+Shift+Alt+KeyI | --- | Ctrl+Shift+Alt+I | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyJ | j | J | J | j | | -| Shift+KeyJ | J | Shift+J | Shift+J | shift+j | | -| Ctrl+Alt+KeyJ | --- | Ctrl+Alt+J | Ctrl+Alt+J | ctrl+alt+j | | -| Ctrl+Shift+Alt+KeyJ | --- | Ctrl+Shift+Alt+J | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyK | k | K | K | k | | -| Shift+KeyK | K | Shift+K | Shift+K | shift+k | | -| Ctrl+Alt+KeyK | --- | Ctrl+Alt+K | Ctrl+Alt+K | ctrl+alt+k | | -| Ctrl+Shift+Alt+KeyK | --- | Ctrl+Shift+Alt+K | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyL | l | L | L | l | | -| Shift+KeyL | L | Shift+L | Shift+L | shift+l | | -| Ctrl+Alt+KeyL | --- | Ctrl+Alt+L | Ctrl+Alt+L | ctrl+alt+l | | -| Ctrl+Shift+Alt+KeyL | --- | Ctrl+Shift+Alt+L | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyM | m | M | M | m | | -| Shift+KeyM | M | Shift+M | Shift+M | shift+m | | -| Ctrl+Alt+KeyM | --- | Ctrl+Alt+M | Ctrl+Alt+M | ctrl+alt+m | | -| Ctrl+Shift+Alt+KeyM | --- | Ctrl+Shift+Alt+M | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyN | n | N | N | n | | -| Shift+KeyN | N | Shift+N | Shift+N | shift+n | | -| Ctrl+Alt+KeyN | --- | Ctrl+Alt+N | Ctrl+Alt+N | ctrl+alt+n | | -| Ctrl+Shift+Alt+KeyN | --- | Ctrl+Shift+Alt+N | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyO | o | O | O | o | | -| Shift+KeyO | O | Shift+O | Shift+O | shift+o | | -| Ctrl+Alt+KeyO | --- | Ctrl+Alt+O | Ctrl+Alt+O | ctrl+alt+o | | -| Ctrl+Shift+Alt+KeyO | --- | Ctrl+Shift+Alt+O | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyP | p | P | P | p | | -| Shift+KeyP | P | Shift+P | Shift+P | shift+p | | -| Ctrl+Alt+KeyP | --- | Ctrl+Alt+P | Ctrl+Alt+P | ctrl+alt+p | | -| Ctrl+Shift+Alt+KeyP | --- | Ctrl+Shift+Alt+P | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyQ | q | Q | Q | q | | -| Shift+KeyQ | Q | Shift+Q | Shift+Q | shift+q | | -| Ctrl+Alt+KeyQ | --- | Ctrl+Alt+Q | Ctrl+Alt+Q | ctrl+alt+q | | -| Ctrl+Shift+Alt+KeyQ | --- | Ctrl+Shift+Alt+Q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyR | r | R | R | r | | -| Shift+KeyR | R | Shift+R | Shift+R | shift+r | | -| Ctrl+Alt+KeyR | --- | Ctrl+Alt+R | Ctrl+Alt+R | ctrl+alt+r | | -| Ctrl+Shift+Alt+KeyR | --- | Ctrl+Shift+Alt+R | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyS | s | S | S | s | | -| Shift+KeyS | S | Shift+S | Shift+S | shift+s | | -| Ctrl+Alt+KeyS | --- | Ctrl+Alt+S | Ctrl+Alt+S | ctrl+alt+s | | -| Ctrl+Shift+Alt+KeyS | --- | Ctrl+Shift+Alt+S | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyT | t | T | T | t | | -| Shift+KeyT | T | Shift+T | Shift+T | shift+t | | -| Ctrl+Alt+KeyT | --- | Ctrl+Alt+T | Ctrl+Alt+T | ctrl+alt+t | | -| Ctrl+Shift+Alt+KeyT | --- | Ctrl+Shift+Alt+T | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyU | u | U | U | u | | -| Shift+KeyU | U | Shift+U | Shift+U | shift+u | | -| Ctrl+Alt+KeyU | --- | Ctrl+Alt+U | Ctrl+Alt+U | ctrl+alt+u | | -| Ctrl+Shift+Alt+KeyU | --- | Ctrl+Shift+Alt+U | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyV | v | V | V | v | | -| Shift+KeyV | V | Shift+V | Shift+V | shift+v | | -| Ctrl+Alt+KeyV | --- | Ctrl+Alt+V | Ctrl+Alt+V | ctrl+alt+v | | -| Ctrl+Shift+Alt+KeyV | --- | Ctrl+Shift+Alt+V | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyW | w | W | W | w | | -| Shift+KeyW | W | Shift+W | Shift+W | shift+w | | -| Ctrl+Alt+KeyW | --- | Ctrl+Alt+W | Ctrl+Alt+W | ctrl+alt+w | | -| Ctrl+Shift+Alt+KeyW | --- | Ctrl+Shift+Alt+W | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyX | x | X | X | x | | -| Shift+KeyX | X | Shift+X | Shift+X | shift+x | | -| Ctrl+Alt+KeyX | --- | Ctrl+Alt+X | Ctrl+Alt+X | ctrl+alt+x | | -| Ctrl+Shift+Alt+KeyX | --- | Ctrl+Shift+Alt+X | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyY | y | Y | Y | y | | -| Shift+KeyY | Y | Shift+Y | Shift+Y | shift+y | | -| Ctrl+Alt+KeyY | --- | Ctrl+Alt+Y | Ctrl+Alt+Y | ctrl+alt+y | | -| Ctrl+Shift+Alt+KeyY | --- | Ctrl+Shift+Alt+Y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyZ | z | Z | Z | z | | -| Shift+KeyZ | Z | Shift+Z | Shift+Z | shift+z | | -| Ctrl+Alt+KeyZ | --- | Ctrl+Alt+Z | Ctrl+Alt+Z | ctrl+alt+z | | -| Ctrl+Shift+Alt+KeyZ | --- | Ctrl+Shift+Alt+Z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit1 | 1 | 1 | 1 | 1 | | -| Shift+Digit1 | ! | Shift+1 | Shift+1 | shift+1 | | -| Ctrl+Alt+Digit1 | --- | Ctrl+Alt+1 | Ctrl+Alt+1 | ctrl+alt+1 | | -| Ctrl+Shift+Alt+Digit1 | --- | Ctrl+Shift+Alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit2 | 2 | 2 | 2 | 2 | | -| Shift+Digit2 | @ | Shift+2 | Shift+2 | shift+2 | | -| Ctrl+Alt+Digit2 | --- | Ctrl+Alt+2 | Ctrl+Alt+2 | ctrl+alt+2 | | -| Ctrl+Shift+Alt+Digit2 | --- | Ctrl+Shift+Alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit3 | 3 | 3 | 3 | 3 | | -| Shift+Digit3 | # | Shift+3 | Shift+3 | shift+3 | | -| Ctrl+Alt+Digit3 | --- | Ctrl+Alt+3 | Ctrl+Alt+3 | ctrl+alt+3 | | -| Ctrl+Shift+Alt+Digit3 | --- | Ctrl+Shift+Alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit4 | 4 | 4 | 4 | 4 | | -| Shift+Digit4 | $ | Shift+4 | Shift+4 | shift+4 | | -| Ctrl+Alt+Digit4 | --- | Ctrl+Alt+4 | Ctrl+Alt+4 | ctrl+alt+4 | | -| Ctrl+Shift+Alt+Digit4 | --- | Ctrl+Shift+Alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit5 | 5 | 5 | 5 | 5 | | -| Shift+Digit5 | % | Shift+5 | Shift+5 | shift+5 | | -| Ctrl+Alt+Digit5 | --- | Ctrl+Alt+5 | Ctrl+Alt+5 | ctrl+alt+5 | | -| Ctrl+Shift+Alt+Digit5 | --- | Ctrl+Shift+Alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit6 | 6 | 6 | 6 | 6 | | -| Shift+Digit6 | ^ | Shift+6 | Shift+6 | shift+6 | | -| Ctrl+Alt+Digit6 | --- | Ctrl+Alt+6 | Ctrl+Alt+6 | ctrl+alt+6 | | -| Ctrl+Shift+Alt+Digit6 | --- | Ctrl+Shift+Alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit7 | 7 | 7 | 7 | 7 | | -| Shift+Digit7 | & | Shift+7 | Shift+7 | shift+7 | | -| Ctrl+Alt+Digit7 | --- | Ctrl+Alt+7 | Ctrl+Alt+7 | ctrl+alt+7 | | -| Ctrl+Shift+Alt+Digit7 | --- | Ctrl+Shift+Alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit8 | 8 | 8 | 8 | 8 | | -| Shift+Digit8 | * | Shift+8 | Shift+8 | shift+8 | | -| Ctrl+Alt+Digit8 | --- | Ctrl+Alt+8 | Ctrl+Alt+8 | ctrl+alt+8 | | -| Ctrl+Shift+Alt+Digit8 | --- | Ctrl+Shift+Alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit9 | 9 | 9 | 9 | 9 | | -| Shift+Digit9 | ( | Shift+9 | Shift+9 | shift+9 | | -| Ctrl+Alt+Digit9 | --- | Ctrl+Alt+9 | Ctrl+Alt+9 | ctrl+alt+9 | | -| Ctrl+Shift+Alt+Digit9 | --- | Ctrl+Shift+Alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit0 | 0 | 0 | 0 | 0 | | -| Shift+Digit0 | ) | Shift+0 | Shift+0 | shift+0 | | -| Ctrl+Alt+Digit0 | --- | Ctrl+Alt+0 | Ctrl+Alt+0 | ctrl+alt+0 | | -| Ctrl+Shift+Alt+Digit0 | --- | Ctrl+Shift+Alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| Minus | - | - | - | - | | -| Shift+Minus | _ | Shift+- | Shift+- | shift+- | | -| Ctrl+Alt+Minus | --- | Ctrl+Alt+- | Ctrl+Alt+- | ctrl+alt+- | | -| Ctrl+Shift+Alt+Minus | --- | Ctrl+Shift+Alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+- | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Equal | = | = | = | = | | -| Shift+Equal | + | Shift+= | Shift+= | shift+= | | -| Ctrl+Alt+Equal | --- | Ctrl+Alt+= | Ctrl+Alt+= | ctrl+alt+= | | -| Ctrl+Shift+Alt+Equal | --- | Ctrl+Shift+Alt+= | Ctrl+Shift+Alt+= | ctrl+shift+alt+= | | ------------------------------------------------------------------------------------------------------------------------------------------ -| BracketLeft | [ | [ | [ | [ | | -| Shift+BracketLeft | { | Shift+[ | Shift+[ | shift+[ | | -| Ctrl+Alt+BracketLeft | --- | Ctrl+Alt+[ | Ctrl+Alt+[ | ctrl+alt+[ | | -| Ctrl+Shift+Alt+BracketLeft | --- | Ctrl+Shift+Alt+[ | Ctrl+Shift+Alt+[ | ctrl+shift+alt+[ | | ------------------------------------------------------------------------------------------------------------------------------------------ -| BracketRight | ] | ] | ] | ] | | -| Shift+BracketRight | } | Shift+] | Shift+] | shift+] | | -| Ctrl+Alt+BracketRight | --- | Ctrl+Alt+] | Ctrl+Alt+] | ctrl+alt+] | | -| Ctrl+Shift+Alt+BracketRight | --- | Ctrl+Shift+Alt+] | Ctrl+Shift+Alt+] | ctrl+shift+alt+] | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Backslash | \ | \ | \ | \ | | -| Shift+Backslash | | | Shift+\ | Shift+\ | shift+\ | | -| Ctrl+Alt+Backslash | --- | Ctrl+Alt+\ | Ctrl+Alt+\ | ctrl+alt+\ | | -| Ctrl+Shift+Alt+Backslash | --- | Ctrl+Shift+Alt+\ | Ctrl+Shift+Alt+\ | ctrl+shift+alt+\ | | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlHash | --- | null | null | null | NO | -| Shift+IntlHash | --- | null | null | null | NO | -| Ctrl+Alt+IntlHash | --- | null | null | null | NO | -| Ctrl+Shift+Alt+IntlHash | --- | null | null | null | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| Semicolon | ; | ; | ; | ; | | -| Shift+Semicolon | : | Shift+; | Shift+; | shift+; | | -| Ctrl+Alt+Semicolon | --- | Ctrl+Alt+; | Ctrl+Alt+; | ctrl+alt+; | | -| Ctrl+Shift+Alt+Semicolon | --- | Ctrl+Shift+Alt+; | Ctrl+Shift+Alt+; | ctrl+shift+alt+; | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Quote | ' | ' | ' | ' | | -| Shift+Quote | " | Shift+' | Shift+' | shift+' | | -| Ctrl+Alt+Quote | --- | Ctrl+Alt+' | Ctrl+Alt+' | ctrl+alt+' | | -| Ctrl+Shift+Alt+Quote | --- | Ctrl+Shift+Alt+' | Ctrl+Shift+Alt+' | ctrl+shift+alt+' | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Backquote | ` | ` | ` | ` | | -| Shift+Backquote | ~ | Shift+` | Shift+` | shift+` | | -| Ctrl+Alt+Backquote | --- | Ctrl+Alt+` | Ctrl+Alt+` | ctrl+alt+` | | -| Ctrl+Shift+Alt+Backquote | --- | Ctrl+Shift+Alt+` | Ctrl+Shift+Alt+` | ctrl+shift+alt+` | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Comma | , | , | , | , | | -| Shift+Comma | < | Shift+, | Shift+, | shift+, | | -| Ctrl+Alt+Comma | --- | Ctrl+Alt+, | Ctrl+Alt+, | ctrl+alt+, | | -| Ctrl+Shift+Alt+Comma | --- | Ctrl+Shift+Alt+, | Ctrl+Shift+Alt+, | ctrl+shift+alt+, | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Period | . | . | . | . | | -| Shift+Period | > | Shift+. | Shift+. | shift+. | | -| Ctrl+Alt+Period | --- | Ctrl+Alt+. | Ctrl+Alt+. | ctrl+alt+. | | -| Ctrl+Shift+Alt+Period | --- | Ctrl+Shift+Alt+. | Ctrl+Shift+Alt+. | ctrl+shift+alt+. | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Slash | / | / | / | / | | -| Shift+Slash | ? | Shift+/ | Shift+/ | shift+/ | | -| Ctrl+Alt+Slash | --- | Ctrl+Alt+/ | Ctrl+Alt+/ | ctrl+alt+/ | | -| Ctrl+Shift+Alt+Slash | --- | Ctrl+Shift+Alt+/ | Ctrl+Shift+Alt+/ | ctrl+shift+alt+/ | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| ArrowUp | --- | UpArrow | UpArrow | up | | -| Shift+ArrowUp | --- | Shift+UpArrow | Shift+UpArrow | shift+up | | -| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | Ctrl+Alt+UpArrow | ctrl+alt+up | | -| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Numpad0 | --- | NumPad0 | NumPad0 | numpad0 | | -| Shift+Numpad0 | --- | Shift+NumPad0 | Shift+NumPad0 | shift+numpad0 | | -| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | | -| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlBackslash | \ | OEM_102 | \ | oem_102 | NO | -| Shift+IntlBackslash | | | Shift+OEM_102 | Shift+\ | shift+oem_102 | NO | -| Ctrl+Alt+IntlBackslash | --- | Ctrl+Alt+OEM_102 | Ctrl+Alt+\ | ctrl+alt+oem_102 | NO | -| Ctrl+Shift+Alt+IntlBackslash | --- | Ctrl+Shift+Alt+OEM_102 | Ctrl+Shift+Alt+\ | ctrl+shift+alt+oem_102 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlRo | --- | null | null | null | NO | -| Shift+IntlRo | --- | null | null | null | NO | -| Ctrl+Alt+IntlRo | --- | null | null | null | NO | -| Ctrl+Shift+Alt+IntlRo | --- | null | null | null | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlYen | --- | null | null | null | NO | -| Shift+IntlYen | --- | null | null | null | NO | -| Ctrl+Alt+IntlYen | --- | null | null | null | NO | -| Ctrl+Shift+Alt+IntlYen | --- | null | null | null | NO | ------------------------------------------------------------------------------------------------------------------------------------------ \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/win_por_ptb.js b/src/vs/workbench/services/keybinding/test/electron-browser/win_por_ptb.js deleted file mode 100644 index 683b2e24113..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/win_por_ptb.js +++ /dev/null @@ -1,1093 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -define({ - Sleep: { - vkey: 'VK_SLEEP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - WakeUp: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - KeyA: { - vkey: 'VK_A', - value: 'a', - withShift: 'A', - withAltGr: '', - withShiftAltGr: '' - }, - KeyB: { - vkey: 'VK_B', - value: 'b', - withShift: 'B', - withAltGr: '', - withShiftAltGr: '' - }, - KeyC: { - vkey: 'VK_C', - value: 'c', - withShift: 'C', - withAltGr: '₢', - withShiftAltGr: '' - }, - KeyD: { - vkey: 'VK_D', - value: 'd', - withShift: 'D', - withAltGr: '', - withShiftAltGr: '' - }, - KeyE: { - vkey: 'VK_E', - value: 'e', - withShift: 'E', - withAltGr: '°', - withShiftAltGr: '' - }, - KeyF: { - vkey: 'VK_F', - value: 'f', - withShift: 'F', - withAltGr: '', - withShiftAltGr: '' - }, - KeyG: { - vkey: 'VK_G', - value: 'g', - withShift: 'G', - withAltGr: '', - withShiftAltGr: '' - }, - KeyH: { - vkey: 'VK_H', - value: 'h', - withShift: 'H', - withAltGr: '', - withShiftAltGr: '' - }, - KeyI: { - vkey: 'VK_I', - value: 'i', - withShift: 'I', - withAltGr: '', - withShiftAltGr: '' - }, - KeyJ: { - vkey: 'VK_J', - value: 'j', - withShift: 'J', - withAltGr: '', - withShiftAltGr: '' - }, - KeyK: { - vkey: 'VK_K', - value: 'k', - withShift: 'K', - withAltGr: '', - withShiftAltGr: '' - }, - KeyL: { - vkey: 'VK_L', - value: 'l', - withShift: 'L', - withAltGr: '', - withShiftAltGr: '' - }, - KeyM: { - vkey: 'VK_M', - value: 'm', - withShift: 'M', - withAltGr: '', - withShiftAltGr: '' - }, - KeyN: { - vkey: 'VK_N', - value: 'n', - withShift: 'N', - withAltGr: '', - withShiftAltGr: '' - }, - KeyO: { - vkey: 'VK_O', - value: 'o', - withShift: 'O', - withAltGr: '', - withShiftAltGr: '' - }, - KeyP: { - vkey: 'VK_P', - value: 'p', - withShift: 'P', - withAltGr: '', - withShiftAltGr: '' - }, - KeyQ: { - vkey: 'VK_Q', - value: 'q', - withShift: 'Q', - withAltGr: '/', - withShiftAltGr: '' - }, - KeyR: { - vkey: 'VK_R', - value: 'r', - withShift: 'R', - withAltGr: '', - withShiftAltGr: '' - }, - KeyS: { - vkey: 'VK_S', - value: 's', - withShift: 'S', - withAltGr: '', - withShiftAltGr: '' - }, - KeyT: { - vkey: 'VK_T', - value: 't', - withShift: 'T', - withAltGr: '', - withShiftAltGr: '' - }, - KeyU: { - vkey: 'VK_U', - value: 'u', - withShift: 'U', - withAltGr: '', - withShiftAltGr: '' - }, - KeyV: { - vkey: 'VK_V', - value: 'v', - withShift: 'V', - withAltGr: '', - withShiftAltGr: '' - }, - KeyW: { - vkey: 'VK_W', - value: 'w', - withShift: 'W', - withAltGr: '?', - withShiftAltGr: '' - }, - KeyX: { - vkey: 'VK_X', - value: 'x', - withShift: 'X', - withAltGr: '', - withShiftAltGr: '' - }, - KeyY: { - vkey: 'VK_Y', - value: 'y', - withShift: 'Y', - withAltGr: '', - withShiftAltGr: '' - }, - KeyZ: { - vkey: 'VK_Z', - value: 'z', - withShift: 'Z', - withAltGr: '', - withShiftAltGr: '' - }, - Digit1: { - vkey: 'VK_1', - value: '1', - withShift: '!', - withAltGr: '¹', - withShiftAltGr: '' - }, - Digit2: { - vkey: 'VK_2', - value: '2', - withShift: '@', - withAltGr: '²', - withShiftAltGr: '' - }, - Digit3: { - vkey: 'VK_3', - value: '3', - withShift: '#', - withAltGr: '³', - withShiftAltGr: '' - }, - Digit4: { - vkey: 'VK_4', - value: '4', - withShift: '$', - withAltGr: '£', - withShiftAltGr: '' - }, - Digit5: { - vkey: 'VK_5', - value: '5', - withShift: '%', - withAltGr: '¢', - withShiftAltGr: '' - }, - Digit6: { - vkey: 'VK_6', - value: '6', - withShift: '¨', - withAltGr: '¬', - withShiftAltGr: '' - }, - Digit7: { - vkey: 'VK_7', - value: '7', - withShift: '&', - withAltGr: '', - withShiftAltGr: '' - }, - Digit8: { - vkey: 'VK_8', - value: '8', - withShift: '*', - withAltGr: '', - withShiftAltGr: '' - }, - Digit9: { - vkey: 'VK_9', - value: '9', - withShift: '(', - withAltGr: '', - withShiftAltGr: '' - }, - Digit0: { - vkey: 'VK_0', - value: '0', - withShift: ')', - withAltGr: '', - withShiftAltGr: '' - }, - Enter: { - vkey: 'VK_RETURN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Escape: { - vkey: 'VK_ESCAPE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Backspace: { - vkey: 'VK_BACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Tab: { - vkey: 'VK_TAB', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Space: { - vkey: 'VK_SPACE', - value: ' ', - withShift: ' ', - withAltGr: '', - withShiftAltGr: '' - }, - Minus: { - vkey: 'VK_OEM_MINUS', - value: '-', - withShift: '_', - withAltGr: '', - withShiftAltGr: '' - }, - Equal: { - vkey: 'VK_OEM_PLUS', - value: '=', - withShift: '+', - withAltGr: '§', - withShiftAltGr: '' - }, - BracketLeft: { - vkey: 'VK_OEM_4', - value: '´', - withShift: '`', - withAltGr: '', - withShiftAltGr: '' - }, - BracketRight: { - vkey: 'VK_OEM_6', - value: '[', - withShift: '{', - withAltGr: 'ª', - withShiftAltGr: '' - }, - Backslash: { - vkey: 'VK_OEM_5', - value: ']', - withShift: '}', - withAltGr: 'º', - withShiftAltGr: '' - }, - Semicolon: { - vkey: 'VK_OEM_1', - value: 'ç', - withShift: 'Ç', - withAltGr: '', - withShiftAltGr: '' - }, - Quote: { - vkey: 'VK_OEM_7', - value: '~', - withShift: '^', - withAltGr: '', - withShiftAltGr: '' - }, - Backquote: { - vkey: 'VK_OEM_3', - value: '\'', - withShift: '"', - withAltGr: '', - withShiftAltGr: '' - }, - Comma: { - vkey: 'VK_OEM_COMMA', - value: ',', - withShift: '<', - withAltGr: '', - withShiftAltGr: '' - }, - Period: { - vkey: 'VK_OEM_PERIOD', - value: '.', - withShift: '>', - withAltGr: '', - withShiftAltGr: '' - }, - Slash: { - vkey: 'VK_OEM_2', - value: ';', - withShift: ':', - withAltGr: '', - withShiftAltGr: '' - }, - CapsLock: { - vkey: 'VK_CAPITAL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F1: { - vkey: 'VK_F1', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F2: { - vkey: 'VK_F2', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F3: { - vkey: 'VK_F3', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F4: { - vkey: 'VK_F4', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F5: { - vkey: 'VK_F5', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F6: { - vkey: 'VK_F6', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F7: { - vkey: 'VK_F7', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F8: { - vkey: 'VK_F8', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F9: { - vkey: 'VK_F9', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F10: { - vkey: 'VK_F10', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F11: { - vkey: 'VK_F11', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F12: { - vkey: 'VK_F12', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PrintScreen: { - vkey: 'VK_SNAPSHOT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ScrollLock: { - vkey: 'VK_SCROLL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Pause: { - vkey: 'VK_NUMLOCK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Insert: { - vkey: 'VK_INSERT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Home: { - vkey: 'VK_HOME', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PageUp: { - vkey: 'VK_PRIOR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Delete: { - vkey: 'VK_DELETE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - End: { - vkey: 'VK_END', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PageDown: { - vkey: 'VK_NEXT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowRight: { - vkey: 'VK_RIGHT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowLeft: { - vkey: 'VK_LEFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowDown: { - vkey: 'VK_DOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowUp: { - vkey: 'VK_UP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumLock: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadDivide: { - vkey: 'VK_DIVIDE', - value: '/', - withShift: '/', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadMultiply: { - vkey: 'VK_MULTIPLY', - value: '*', - withShift: '*', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadSubtract: { - vkey: 'VK_SUBTRACT', - value: '-', - withShift: '-', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadAdd: { - vkey: 'VK_ADD', - value: '+', - withShift: '+', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadEnter: { - vkey: 'VK_RETURN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad1: { - vkey: 'VK_END', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad2: { - vkey: 'VK_DOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad3: { - vkey: 'VK_NEXT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad4: { - vkey: 'VK_LEFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad5: { - vkey: 'VK_CLEAR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad6: { - vkey: 'VK_RIGHT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad7: { - vkey: 'VK_HOME', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad8: { - vkey: 'VK_UP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad9: { - vkey: 'VK_PRIOR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad0: { - vkey: 'VK_INSERT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadDecimal: { - vkey: 'VK_DELETE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - IntlBackslash: { - vkey: 'VK_OEM_102', - value: '\\', - withShift: '|', - withAltGr: '', - withShiftAltGr: '' - }, - ContextMenu: { - vkey: 'VK_APPS', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Power: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadEqual: { - vkey: 'VK_CLEAR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F13: { - vkey: 'VK_F13', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F14: { - vkey: 'VK_F14', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F15: { - vkey: 'VK_F15', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F16: { - vkey: 'VK_F16', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F17: { - vkey: 'VK_F17', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F18: { - vkey: 'VK_F18', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F19: { - vkey: 'VK_F19', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F20: { - vkey: 'VK_F20', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F21: { - vkey: 'VK_F21', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F22: { - vkey: 'VK_F22', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F23: { - vkey: 'VK_F23', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F24: { - vkey: 'VK_F24', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Help: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Undo: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Cut: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Copy: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Paste: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeMute: { - vkey: 'VK_VOLUME_MUTE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeUp: { - vkey: 'VK_VOLUME_UP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeDown: { - vkey: 'VK_VOLUME_DOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadComma: { - vkey: 'VK_ABNT_C2', - value: '.', - withShift: '.', - withAltGr: '', - withShiftAltGr: '' - }, - IntlRo: { - vkey: 'VK_ABNT_C1', - value: '/', - withShift: '?', - withAltGr: '°', - withShiftAltGr: '' - }, - KanaMode: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - IntlYen: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Convert: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NonConvert: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang1: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang2: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang3: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang4: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ControlLeft: { - vkey: 'VK_CONTROL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ShiftLeft: { - vkey: 'VK_SHIFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AltLeft: { - vkey: 'VK_MENU', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MetaLeft: { - vkey: 'VK_LWIN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ControlRight: { - vkey: 'VK_CONTROL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ShiftRight: { - vkey: 'VK_SHIFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AltRight: { - vkey: 'VK_MENU', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MetaRight: { - vkey: 'VK_RWIN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaTrackNext: { - vkey: 'VK_MEDIA_NEXT_TRACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaTrackPrevious: { - vkey: 'VK_MEDIA_PREV_TRACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaStop: { - vkey: 'VK_MEDIA_STOP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Eject: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaPlayPause: { - vkey: 'VK_MEDIA_PLAY_PAUSE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaSelect: { - vkey: 'VK_LAUNCH_MEDIA_SELECT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchMail: { - vkey: 'VK_LAUNCH_MAIL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchApp2: { - vkey: 'VK_LAUNCH_APP2', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchApp1: { - vkey: 'VK_LAUNCH_APP1', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserSearch: { - vkey: 'VK_BROWSER_SEARCH', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserHome: { - vkey: 'VK_BROWSER_HOME', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserBack: { - vkey: 'VK_BROWSER_BACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserForward: { - vkey: 'VK_BROWSER_FORWARD', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserStop: { - vkey: 'VK_BROWSER_STOP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserRefresh: { - vkey: 'VK_BROWSER_REFRESH', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserFavorites: { - vkey: 'VK_BROWSER_FAVORITES', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - } -}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/win_por_ptb.txt b/src/vs/workbench/services/keybinding/test/electron-browser/win_por_ptb.txt deleted file mode 100644 index c29ed546991..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/win_por_ptb.txt +++ /dev/null @@ -1,284 +0,0 @@ ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyA | a | A | A | a | | -| Shift+KeyA | A | Shift+A | Shift+A | shift+a | | -| Ctrl+Alt+KeyA | --- | Ctrl+Alt+A | Ctrl+Alt+A | ctrl+alt+a | | -| Ctrl+Shift+Alt+KeyA | --- | Ctrl+Shift+Alt+A | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyB | b | B | B | b | | -| Shift+KeyB | B | Shift+B | Shift+B | shift+b | | -| Ctrl+Alt+KeyB | --- | Ctrl+Alt+B | Ctrl+Alt+B | ctrl+alt+b | | -| Ctrl+Shift+Alt+KeyB | --- | Ctrl+Shift+Alt+B | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyC | c | C | C | c | | -| Shift+KeyC | C | Shift+C | Shift+C | shift+c | | -| Ctrl+Alt+KeyC | ₢ | Ctrl+Alt+C | Ctrl+Alt+C | ctrl+alt+c | | -| Ctrl+Shift+Alt+KeyC | --- | Ctrl+Shift+Alt+C | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyD | d | D | D | d | | -| Shift+KeyD | D | Shift+D | Shift+D | shift+d | | -| Ctrl+Alt+KeyD | --- | Ctrl+Alt+D | Ctrl+Alt+D | ctrl+alt+d | | -| Ctrl+Shift+Alt+KeyD | --- | Ctrl+Shift+Alt+D | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyE | e | E | E | e | | -| Shift+KeyE | E | Shift+E | Shift+E | shift+e | | -| Ctrl+Alt+KeyE | ° | Ctrl+Alt+E | Ctrl+Alt+E | ctrl+alt+e | | -| Ctrl+Shift+Alt+KeyE | --- | Ctrl+Shift+Alt+E | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyF | f | F | F | f | | -| Shift+KeyF | F | Shift+F | Shift+F | shift+f | | -| Ctrl+Alt+KeyF | --- | Ctrl+Alt+F | Ctrl+Alt+F | ctrl+alt+f | | -| Ctrl+Shift+Alt+KeyF | --- | Ctrl+Shift+Alt+F | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyG | g | G | G | g | | -| Shift+KeyG | G | Shift+G | Shift+G | shift+g | | -| Ctrl+Alt+KeyG | --- | Ctrl+Alt+G | Ctrl+Alt+G | ctrl+alt+g | | -| Ctrl+Shift+Alt+KeyG | --- | Ctrl+Shift+Alt+G | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyH | h | H | H | h | | -| Shift+KeyH | H | Shift+H | Shift+H | shift+h | | -| Ctrl+Alt+KeyH | --- | Ctrl+Alt+H | Ctrl+Alt+H | ctrl+alt+h | | -| Ctrl+Shift+Alt+KeyH | --- | Ctrl+Shift+Alt+H | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyI | i | I | I | i | | -| Shift+KeyI | I | Shift+I | Shift+I | shift+i | | -| Ctrl+Alt+KeyI | --- | Ctrl+Alt+I | Ctrl+Alt+I | ctrl+alt+i | | -| Ctrl+Shift+Alt+KeyI | --- | Ctrl+Shift+Alt+I | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyJ | j | J | J | j | | -| Shift+KeyJ | J | Shift+J | Shift+J | shift+j | | -| Ctrl+Alt+KeyJ | --- | Ctrl+Alt+J | Ctrl+Alt+J | ctrl+alt+j | | -| Ctrl+Shift+Alt+KeyJ | --- | Ctrl+Shift+Alt+J | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyK | k | K | K | k | | -| Shift+KeyK | K | Shift+K | Shift+K | shift+k | | -| Ctrl+Alt+KeyK | --- | Ctrl+Alt+K | Ctrl+Alt+K | ctrl+alt+k | | -| Ctrl+Shift+Alt+KeyK | --- | Ctrl+Shift+Alt+K | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyL | l | L | L | l | | -| Shift+KeyL | L | Shift+L | Shift+L | shift+l | | -| Ctrl+Alt+KeyL | --- | Ctrl+Alt+L | Ctrl+Alt+L | ctrl+alt+l | | -| Ctrl+Shift+Alt+KeyL | --- | Ctrl+Shift+Alt+L | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyM | m | M | M | m | | -| Shift+KeyM | M | Shift+M | Shift+M | shift+m | | -| Ctrl+Alt+KeyM | --- | Ctrl+Alt+M | Ctrl+Alt+M | ctrl+alt+m | | -| Ctrl+Shift+Alt+KeyM | --- | Ctrl+Shift+Alt+M | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyN | n | N | N | n | | -| Shift+KeyN | N | Shift+N | Shift+N | shift+n | | -| Ctrl+Alt+KeyN | --- | Ctrl+Alt+N | Ctrl+Alt+N | ctrl+alt+n | | -| Ctrl+Shift+Alt+KeyN | --- | Ctrl+Shift+Alt+N | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyO | o | O | O | o | | -| Shift+KeyO | O | Shift+O | Shift+O | shift+o | | -| Ctrl+Alt+KeyO | --- | Ctrl+Alt+O | Ctrl+Alt+O | ctrl+alt+o | | -| Ctrl+Shift+Alt+KeyO | --- | Ctrl+Shift+Alt+O | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyP | p | P | P | p | | -| Shift+KeyP | P | Shift+P | Shift+P | shift+p | | -| Ctrl+Alt+KeyP | --- | Ctrl+Alt+P | Ctrl+Alt+P | ctrl+alt+p | | -| Ctrl+Shift+Alt+KeyP | --- | Ctrl+Shift+Alt+P | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyQ | q | Q | Q | q | | -| Shift+KeyQ | Q | Shift+Q | Shift+Q | shift+q | | -| Ctrl+Alt+KeyQ | / | Ctrl+Alt+Q | Ctrl+Alt+Q | ctrl+alt+q | | -| Ctrl+Shift+Alt+KeyQ | --- | Ctrl+Shift+Alt+Q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyR | r | R | R | r | | -| Shift+KeyR | R | Shift+R | Shift+R | shift+r | | -| Ctrl+Alt+KeyR | --- | Ctrl+Alt+R | Ctrl+Alt+R | ctrl+alt+r | | -| Ctrl+Shift+Alt+KeyR | --- | Ctrl+Shift+Alt+R | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyS | s | S | S | s | | -| Shift+KeyS | S | Shift+S | Shift+S | shift+s | | -| Ctrl+Alt+KeyS | --- | Ctrl+Alt+S | Ctrl+Alt+S | ctrl+alt+s | | -| Ctrl+Shift+Alt+KeyS | --- | Ctrl+Shift+Alt+S | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyT | t | T | T | t | | -| Shift+KeyT | T | Shift+T | Shift+T | shift+t | | -| Ctrl+Alt+KeyT | --- | Ctrl+Alt+T | Ctrl+Alt+T | ctrl+alt+t | | -| Ctrl+Shift+Alt+KeyT | --- | Ctrl+Shift+Alt+T | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyU | u | U | U | u | | -| Shift+KeyU | U | Shift+U | Shift+U | shift+u | | -| Ctrl+Alt+KeyU | --- | Ctrl+Alt+U | Ctrl+Alt+U | ctrl+alt+u | | -| Ctrl+Shift+Alt+KeyU | --- | Ctrl+Shift+Alt+U | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyV | v | V | V | v | | -| Shift+KeyV | V | Shift+V | Shift+V | shift+v | | -| Ctrl+Alt+KeyV | --- | Ctrl+Alt+V | Ctrl+Alt+V | ctrl+alt+v | | -| Ctrl+Shift+Alt+KeyV | --- | Ctrl+Shift+Alt+V | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyW | w | W | W | w | | -| Shift+KeyW | W | Shift+W | Shift+W | shift+w | | -| Ctrl+Alt+KeyW | ? | Ctrl+Alt+W | Ctrl+Alt+W | ctrl+alt+w | | -| Ctrl+Shift+Alt+KeyW | --- | Ctrl+Shift+Alt+W | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyX | x | X | X | x | | -| Shift+KeyX | X | Shift+X | Shift+X | shift+x | | -| Ctrl+Alt+KeyX | --- | Ctrl+Alt+X | Ctrl+Alt+X | ctrl+alt+x | | -| Ctrl+Shift+Alt+KeyX | --- | Ctrl+Shift+Alt+X | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyY | y | Y | Y | y | | -| Shift+KeyY | Y | Shift+Y | Shift+Y | shift+y | | -| Ctrl+Alt+KeyY | --- | Ctrl+Alt+Y | Ctrl+Alt+Y | ctrl+alt+y | | -| Ctrl+Shift+Alt+KeyY | --- | Ctrl+Shift+Alt+Y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyZ | z | Z | Z | z | | -| Shift+KeyZ | Z | Shift+Z | Shift+Z | shift+z | | -| Ctrl+Alt+KeyZ | --- | Ctrl+Alt+Z | Ctrl+Alt+Z | ctrl+alt+z | | -| Ctrl+Shift+Alt+KeyZ | --- | Ctrl+Shift+Alt+Z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit1 | 1 | 1 | 1 | 1 | | -| Shift+Digit1 | ! | Shift+1 | Shift+1 | shift+1 | | -| Ctrl+Alt+Digit1 | ¹ | Ctrl+Alt+1 | Ctrl+Alt+1 | ctrl+alt+1 | | -| Ctrl+Shift+Alt+Digit1 | --- | Ctrl+Shift+Alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit2 | 2 | 2 | 2 | 2 | | -| Shift+Digit2 | @ | Shift+2 | Shift+2 | shift+2 | | -| Ctrl+Alt+Digit2 | ² | Ctrl+Alt+2 | Ctrl+Alt+2 | ctrl+alt+2 | | -| Ctrl+Shift+Alt+Digit2 | --- | Ctrl+Shift+Alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit3 | 3 | 3 | 3 | 3 | | -| Shift+Digit3 | # | Shift+3 | Shift+3 | shift+3 | | -| Ctrl+Alt+Digit3 | ³ | Ctrl+Alt+3 | Ctrl+Alt+3 | ctrl+alt+3 | | -| Ctrl+Shift+Alt+Digit3 | --- | Ctrl+Shift+Alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit4 | 4 | 4 | 4 | 4 | | -| Shift+Digit4 | $ | Shift+4 | Shift+4 | shift+4 | | -| Ctrl+Alt+Digit4 | £ | Ctrl+Alt+4 | Ctrl+Alt+4 | ctrl+alt+4 | | -| Ctrl+Shift+Alt+Digit4 | --- | Ctrl+Shift+Alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit5 | 5 | 5 | 5 | 5 | | -| Shift+Digit5 | % | Shift+5 | Shift+5 | shift+5 | | -| Ctrl+Alt+Digit5 | ¢ | Ctrl+Alt+5 | Ctrl+Alt+5 | ctrl+alt+5 | | -| Ctrl+Shift+Alt+Digit5 | --- | Ctrl+Shift+Alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit6 | 6 | 6 | 6 | 6 | | -| Shift+Digit6 | ¨ | Shift+6 | Shift+6 | shift+6 | | -| Ctrl+Alt+Digit6 | ¬ | Ctrl+Alt+6 | Ctrl+Alt+6 | ctrl+alt+6 | | -| Ctrl+Shift+Alt+Digit6 | --- | Ctrl+Shift+Alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit7 | 7 | 7 | 7 | 7 | | -| Shift+Digit7 | & | Shift+7 | Shift+7 | shift+7 | | -| Ctrl+Alt+Digit7 | --- | Ctrl+Alt+7 | Ctrl+Alt+7 | ctrl+alt+7 | | -| Ctrl+Shift+Alt+Digit7 | --- | Ctrl+Shift+Alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit8 | 8 | 8 | 8 | 8 | | -| Shift+Digit8 | * | Shift+8 | Shift+8 | shift+8 | | -| Ctrl+Alt+Digit8 | --- | Ctrl+Alt+8 | Ctrl+Alt+8 | ctrl+alt+8 | | -| Ctrl+Shift+Alt+Digit8 | --- | Ctrl+Shift+Alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit9 | 9 | 9 | 9 | 9 | | -| Shift+Digit9 | ( | Shift+9 | Shift+9 | shift+9 | | -| Ctrl+Alt+Digit9 | --- | Ctrl+Alt+9 | Ctrl+Alt+9 | ctrl+alt+9 | | -| Ctrl+Shift+Alt+Digit9 | --- | Ctrl+Shift+Alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit0 | 0 | 0 | 0 | 0 | | -| Shift+Digit0 | ) | Shift+0 | Shift+0 | shift+0 | | -| Ctrl+Alt+Digit0 | --- | Ctrl+Alt+0 | Ctrl+Alt+0 | ctrl+alt+0 | | -| Ctrl+Shift+Alt+Digit0 | --- | Ctrl+Shift+Alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| Minus | - | - | - | oem_minus | NO | -| Shift+Minus | _ | Shift+- | Shift+- | shift+oem_minus | NO | -| Ctrl+Alt+Minus | --- | Ctrl+Alt+- | Ctrl+Alt+- | ctrl+alt+oem_minus | NO | -| Ctrl+Shift+Alt+Minus | --- | Ctrl+Shift+Alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+oem_minus | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Equal | = | = | = | oem_plus | NO | -| Shift+Equal | + | Shift+= | Shift+= | shift+oem_plus | NO | -| Ctrl+Alt+Equal | § | Ctrl+Alt+= | Ctrl+Alt+= | ctrl+alt+oem_plus | NO | -| Ctrl+Shift+Alt+Equal | --- | Ctrl+Shift+Alt+= | Ctrl+Shift+Alt+= | ctrl+shift+alt+oem_plus | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| BracketLeft | ´ | [ | ´ | oem_4 | NO | -| Shift+BracketLeft | ` | Shift+[ | Shift+´ | shift+oem_4 | NO | -| Ctrl+Alt+BracketLeft | --- | Ctrl+Alt+[ | Ctrl+Alt+´ | ctrl+alt+oem_4 | NO | -| Ctrl+Shift+Alt+BracketLeft | --- | Ctrl+Shift+Alt+[ | Ctrl+Shift+Alt+´ | ctrl+shift+alt+oem_4 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| BracketRight | [ | ] | [ | oem_6 | NO | -| Shift+BracketRight | { | Shift+] | Shift+[ | shift+oem_6 | NO | -| Ctrl+Alt+BracketRight | ª | Ctrl+Alt+] | Ctrl+Alt+[ | ctrl+alt+oem_6 | NO | -| Ctrl+Shift+Alt+BracketRight | --- | Ctrl+Shift+Alt+] | Ctrl+Shift+Alt+[ | ctrl+shift+alt+oem_6 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Backslash | ] | \ | ] | oem_5 | NO | -| Shift+Backslash | } | Shift+\ | Shift+] | shift+oem_5 | NO | -| Ctrl+Alt+Backslash | º | Ctrl+Alt+\ | Ctrl+Alt+] | ctrl+alt+oem_5 | NO | -| Ctrl+Shift+Alt+Backslash | --- | Ctrl+Shift+Alt+\ | Ctrl+Shift+Alt+] | ctrl+shift+alt+oem_5 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlHash | --- | null | null | null | NO | -| Shift+IntlHash | --- | null | null | null | NO | -| Ctrl+Alt+IntlHash | --- | null | null | null | NO | -| Ctrl+Shift+Alt+IntlHash | --- | null | null | null | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| Semicolon | ç | ; | ç | oem_1 | NO | -| Shift+Semicolon | Ç | Shift+; | Shift+ç | shift+oem_1 | NO | -| Ctrl+Alt+Semicolon | --- | Ctrl+Alt+; | Ctrl+Alt+ç | ctrl+alt+oem_1 | NO | -| Ctrl+Shift+Alt+Semicolon | --- | Ctrl+Shift+Alt+; | Ctrl+Shift+Alt+ç | ctrl+shift+alt+oem_1 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Quote | ~ | ' | ~ | oem_7 | NO | -| Shift+Quote | ^ | Shift+' | Shift+~ | shift+oem_7 | NO | -| Ctrl+Alt+Quote | --- | Ctrl+Alt+' | Ctrl+Alt+~ | ctrl+alt+oem_7 | NO | -| Ctrl+Shift+Alt+Quote | --- | Ctrl+Shift+Alt+' | Ctrl+Shift+Alt+~ | ctrl+shift+alt+oem_7 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Backquote | ' | ` | ' | oem_3 | NO | -| Shift+Backquote | " | Shift+` | Shift+' | shift+oem_3 | NO | -| Ctrl+Alt+Backquote | --- | Ctrl+Alt+` | Ctrl+Alt+' | ctrl+alt+oem_3 | NO | -| Ctrl+Shift+Alt+Backquote | --- | Ctrl+Shift+Alt+` | Ctrl+Shift+Alt+' | ctrl+shift+alt+oem_3 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Comma | , | , | , | oem_comma | NO | -| Shift+Comma | < | Shift+, | Shift+, | shift+oem_comma | NO | -| Ctrl+Alt+Comma | --- | Ctrl+Alt+, | Ctrl+Alt+, | ctrl+alt+oem_comma | NO | -| Ctrl+Shift+Alt+Comma | --- | Ctrl+Shift+Alt+, | Ctrl+Shift+Alt+, | ctrl+shift+alt+oem_comma | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Period | . | . | . | oem_period | NO | -| Shift+Period | > | Shift+. | Shift+. | shift+oem_period | NO | -| Ctrl+Alt+Period | --- | Ctrl+Alt+. | Ctrl+Alt+. | ctrl+alt+oem_period | NO | -| Ctrl+Shift+Alt+Period | --- | Ctrl+Shift+Alt+. | Ctrl+Shift+Alt+. | ctrl+shift+alt+oem_period | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Slash | ; | / | ; | oem_2 | NO | -| Shift+Slash | : | Shift+/ | Shift+; | shift+oem_2 | NO | -| Ctrl+Alt+Slash | --- | Ctrl+Alt+/ | Ctrl+Alt+; | ctrl+alt+oem_2 | NO | -| Ctrl+Shift+Alt+Slash | --- | Ctrl+Shift+Alt+/ | Ctrl+Shift+Alt+; | ctrl+shift+alt+oem_2 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| ArrowUp | --- | UpArrow | UpArrow | up | | -| Shift+ArrowUp | --- | Shift+UpArrow | Shift+UpArrow | shift+up | | -| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | Ctrl+Alt+UpArrow | ctrl+alt+up | | -| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Numpad0 | --- | NumPad0 | NumPad0 | numpad0 | | -| Shift+Numpad0 | --- | Shift+NumPad0 | Shift+NumPad0 | shift+numpad0 | | -| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | | -| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlBackslash | \ | OEM_102 | \ | oem_102 | NO | -| Shift+IntlBackslash | | | Shift+OEM_102 | Shift+\ | shift+oem_102 | NO | -| Ctrl+Alt+IntlBackslash | --- | Ctrl+Alt+OEM_102 | Ctrl+Alt+\ | ctrl+alt+oem_102 | NO | -| Ctrl+Shift+Alt+IntlBackslash | --- | Ctrl+Shift+Alt+OEM_102 | Ctrl+Shift+Alt+\ | ctrl+shift+alt+oem_102 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlRo | / | ABNT_C1 | / | abnt_c1 | NO | -| Shift+IntlRo | ? | Shift+ABNT_C1 | Shift+/ | shift+abnt_c1 | NO | -| Ctrl+Alt+IntlRo | ° | Ctrl+Alt+ABNT_C1 | Ctrl+Alt+/ | ctrl+alt+abnt_c1 | NO | -| Ctrl+Shift+Alt+IntlRo | --- | Ctrl+Shift+Alt+ABNT_C1 | Ctrl+Shift+Alt+/ | ctrl+shift+alt+abnt_c1 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlYen | --- | null | null | null | NO | -| Shift+IntlYen | --- | null | null | null | NO | -| Ctrl+Alt+IntlYen | --- | null | null | null | NO | -| Ctrl+Shift+Alt+IntlYen | --- | null | null | null | NO | ------------------------------------------------------------------------------------------------------------------------------------------ \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/win_ru.js b/src/vs/workbench/services/keybinding/test/electron-browser/win_ru.js deleted file mode 100644 index 4f024d361eb..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/win_ru.js +++ /dev/null @@ -1,1093 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -define({ - Sleep: { - vkey: 'VK_SLEEP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - WakeUp: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - KeyA: { - vkey: 'VK_A', - value: 'ф', - withShift: 'Ф', - withAltGr: '', - withShiftAltGr: '' - }, - KeyB: { - vkey: 'VK_B', - value: 'и', - withShift: 'И', - withAltGr: '', - withShiftAltGr: '' - }, - KeyC: { - vkey: 'VK_C', - value: 'с', - withShift: 'С', - withAltGr: '', - withShiftAltGr: '' - }, - KeyD: { - vkey: 'VK_D', - value: 'в', - withShift: 'В', - withAltGr: '', - withShiftAltGr: '' - }, - KeyE: { - vkey: 'VK_E', - value: 'у', - withShift: 'У', - withAltGr: '', - withShiftAltGr: '' - }, - KeyF: { - vkey: 'VK_F', - value: 'а', - withShift: 'А', - withAltGr: '', - withShiftAltGr: '' - }, - KeyG: { - vkey: 'VK_G', - value: 'п', - withShift: 'П', - withAltGr: '', - withShiftAltGr: '' - }, - KeyH: { - vkey: 'VK_H', - value: 'р', - withShift: 'Р', - withAltGr: '', - withShiftAltGr: '' - }, - KeyI: { - vkey: 'VK_I', - value: 'ш', - withShift: 'Ш', - withAltGr: '', - withShiftAltGr: '' - }, - KeyJ: { - vkey: 'VK_J', - value: 'о', - withShift: 'О', - withAltGr: '', - withShiftAltGr: '' - }, - KeyK: { - vkey: 'VK_K', - value: 'л', - withShift: 'Л', - withAltGr: '', - withShiftAltGr: '' - }, - KeyL: { - vkey: 'VK_L', - value: 'д', - withShift: 'Д', - withAltGr: '', - withShiftAltGr: '' - }, - KeyM: { - vkey: 'VK_M', - value: 'ь', - withShift: 'Ь', - withAltGr: '', - withShiftAltGr: '' - }, - KeyN: { - vkey: 'VK_N', - value: 'т', - withShift: 'Т', - withAltGr: '', - withShiftAltGr: '' - }, - KeyO: { - vkey: 'VK_O', - value: 'щ', - withShift: 'Щ', - withAltGr: '', - withShiftAltGr: '' - }, - KeyP: { - vkey: 'VK_P', - value: 'з', - withShift: 'З', - withAltGr: '', - withShiftAltGr: '' - }, - KeyQ: { - vkey: 'VK_Q', - value: 'й', - withShift: 'Й', - withAltGr: '', - withShiftAltGr: '' - }, - KeyR: { - vkey: 'VK_R', - value: 'к', - withShift: 'К', - withAltGr: '', - withShiftAltGr: '' - }, - KeyS: { - vkey: 'VK_S', - value: 'ы', - withShift: 'Ы', - withAltGr: '', - withShiftAltGr: '' - }, - KeyT: { - vkey: 'VK_T', - value: 'е', - withShift: 'Е', - withAltGr: '', - withShiftAltGr: '' - }, - KeyU: { - vkey: 'VK_U', - value: 'г', - withShift: 'Г', - withAltGr: '', - withShiftAltGr: '' - }, - KeyV: { - vkey: 'VK_V', - value: 'м', - withShift: 'М', - withAltGr: '', - withShiftAltGr: '' - }, - KeyW: { - vkey: 'VK_W', - value: 'ц', - withShift: 'Ц', - withAltGr: '', - withShiftAltGr: '' - }, - KeyX: { - vkey: 'VK_X', - value: 'ч', - withShift: 'Ч', - withAltGr: '', - withShiftAltGr: '' - }, - KeyY: { - vkey: 'VK_Y', - value: 'н', - withShift: 'Н', - withAltGr: '', - withShiftAltGr: '' - }, - KeyZ: { - vkey: 'VK_Z', - value: 'я', - withShift: 'Я', - withAltGr: '', - withShiftAltGr: '' - }, - Digit1: { - vkey: 'VK_1', - value: '1', - withShift: '!', - withAltGr: '', - withShiftAltGr: '' - }, - Digit2: { - vkey: 'VK_2', - value: '2', - withShift: '\"', - withAltGr: '', - withShiftAltGr: '' - }, - Digit3: { - vkey: 'VK_3', - value: '3', - withShift: '№', - withAltGr: '', - withShiftAltGr: '' - }, - Digit4: { - vkey: 'VK_4', - value: '4', - withShift: ';', - withAltGr: '', - withShiftAltGr: '' - }, - Digit5: { - vkey: 'VK_5', - value: '5', - withShift: '%', - withAltGr: '', - withShiftAltGr: '' - }, - Digit6: { - vkey: 'VK_6', - value: '6', - withShift: ':', - withAltGr: '', - withShiftAltGr: '' - }, - Digit7: { - vkey: 'VK_7', - value: '7', - withShift: '?', - withAltGr: '', - withShiftAltGr: '' - }, - Digit8: { - vkey: 'VK_8', - value: '8', - withShift: '*', - withAltGr: '₽', - withShiftAltGr: '' - }, - Digit9: { - vkey: 'VK_9', - value: '9', - withShift: '(', - withAltGr: '', - withShiftAltGr: '' - }, - Digit0: { - vkey: 'VK_0', - value: '0', - withShift: ')', - withAltGr: '', - withShiftAltGr: '' - }, - Enter: { - vkey: 'VK_RETURN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Escape: { - vkey: 'VK_ESCAPE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Backspace: { - vkey: 'VK_BACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Tab: { - vkey: 'VK_TAB', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Space: { - vkey: 'VK_SPACE', - value: ' ', - withShift: ' ', - withAltGr: '', - withShiftAltGr: '' - }, - Minus: { - vkey: 'VK_OEM_MINUS', - value: '-', - withShift: '_', - withAltGr: '', - withShiftAltGr: '' - }, - Equal: { - vkey: 'VK_OEM_PLUS', - value: '=', - withShift: '+', - withAltGr: '', - withShiftAltGr: '' - }, - BracketLeft: { - vkey: 'VK_OEM_4', - value: 'х', - withShift: 'Х', - withAltGr: '', - withShiftAltGr: '' - }, - BracketRight: { - vkey: 'VK_OEM_6', - value: 'ъ', - withShift: 'Ъ', - withAltGr: '', - withShiftAltGr: '' - }, - Backslash: { - vkey: 'VK_OEM_5', - value: '\\', - withShift: '/', - withAltGr: '', - withShiftAltGr: '' - }, - Semicolon: { - vkey: 'VK_OEM_1', - value: 'ж', - withShift: 'Ж', - withAltGr: '', - withShiftAltGr: '' - }, - Quote: { - vkey: 'VK_OEM_7', - value: 'э', - withShift: 'Э', - withAltGr: '', - withShiftAltGr: '' - }, - Backquote: { - vkey: 'VK_OEM_3', - value: 'ё', - withShift: 'Ё', - withAltGr: '', - withShiftAltGr: '' - }, - Comma: { - vkey: 'VK_OEM_COMMA', - value: 'б', - withShift: 'Б', - withAltGr: '', - withShiftAltGr: '' - }, - Period: { - vkey: 'VK_OEM_PERIOD', - value: 'ю', - withShift: 'Ю', - withAltGr: '', - withShiftAltGr: '' - }, - Slash: { - vkey: 'VK_OEM_2', - value: '.', - withShift: ',', - withAltGr: '', - withShiftAltGr: '' - }, - CapsLock: { - vkey: 'VK_CAPITAL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F1: { - vkey: 'VK_F1', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F2: { - vkey: 'VK_F2', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F3: { - vkey: 'VK_F3', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F4: { - vkey: 'VK_F4', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F5: { - vkey: 'VK_F5', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F6: { - vkey: 'VK_F6', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F7: { - vkey: 'VK_F7', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F8: { - vkey: 'VK_F8', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F9: { - vkey: 'VK_F9', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F10: { - vkey: 'VK_F10', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F11: { - vkey: 'VK_F11', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F12: { - vkey: 'VK_F12', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PrintScreen: { - vkey: 'VK_SNAPSHOT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ScrollLock: { - vkey: 'VK_SCROLL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Pause: { - vkey: 'VK_NUMLOCK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Insert: { - vkey: 'VK_INSERT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Home: { - vkey: 'VK_HOME', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PageUp: { - vkey: 'VK_PRIOR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Delete: { - vkey: 'VK_DELETE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - End: { - vkey: 'VK_END', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - PageDown: { - vkey: 'VK_NEXT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowRight: { - vkey: 'VK_RIGHT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowLeft: { - vkey: 'VK_LEFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowDown: { - vkey: 'VK_DOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ArrowUp: { - vkey: 'VK_UP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumLock: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadDivide: { - vkey: 'VK_DIVIDE', - value: '/', - withShift: '/', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadMultiply: { - vkey: 'VK_MULTIPLY', - value: '*', - withShift: '*', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadSubtract: { - vkey: 'VK_SUBTRACT', - value: '-', - withShift: '-', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadAdd: { - vkey: 'VK_ADD', - value: '+', - withShift: '+', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadEnter: { - vkey: 'VK_RETURN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad1: { - vkey: 'VK_END', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad2: { - vkey: 'VK_DOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad3: { - vkey: 'VK_NEXT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad4: { - vkey: 'VK_LEFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad5: { - vkey: 'VK_CLEAR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad6: { - vkey: 'VK_RIGHT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad7: { - vkey: 'VK_HOME', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad8: { - vkey: 'VK_UP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad9: { - vkey: 'VK_PRIOR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Numpad0: { - vkey: 'VK_INSERT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadDecimal: { - vkey: 'VK_DELETE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - IntlBackslash: { - vkey: 'VK_OEM_102', - value: '\\', - withShift: '/', - withAltGr: '', - withShiftAltGr: '' - }, - ContextMenu: { - vkey: 'VK_APPS', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Power: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadEqual: { - vkey: 'VK_CLEAR', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F13: { - vkey: 'VK_F13', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F14: { - vkey: 'VK_F14', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F15: { - vkey: 'VK_F15', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F16: { - vkey: 'VK_F16', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F17: { - vkey: 'VK_F17', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F18: { - vkey: 'VK_F18', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F19: { - vkey: 'VK_F19', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F20: { - vkey: 'VK_F20', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F21: { - vkey: 'VK_F21', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F22: { - vkey: 'VK_F22', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F23: { - vkey: 'VK_F23', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - F24: { - vkey: 'VK_F24', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Help: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Undo: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Cut: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Copy: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Paste: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeMute: { - vkey: 'VK_VOLUME_MUTE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeUp: { - vkey: 'VK_VOLUME_UP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AudioVolumeDown: { - vkey: 'VK_VOLUME_DOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NumpadComma: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - IntlRo: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - KanaMode: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - IntlYen: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Convert: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - NonConvert: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang1: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang2: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang3: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Lang4: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ControlLeft: { - vkey: 'VK_CONTROL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ShiftLeft: { - vkey: 'VK_SHIFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AltLeft: { - vkey: 'VK_MENU', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MetaLeft: { - vkey: 'VK_LWIN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ControlRight: { - vkey: 'VK_CONTROL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - ShiftRight: { - vkey: 'VK_SHIFT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - AltRight: { - vkey: 'VK_MENU', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MetaRight: { - vkey: 'VK_RWIN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaTrackNext: { - vkey: 'VK_MEDIA_NEXT_TRACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaTrackPrevious: { - vkey: 'VK_MEDIA_PREV_TRACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaStop: { - vkey: 'VK_MEDIA_STOP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - Eject: { - vkey: 'VK_UNKNOWN', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaPlayPause: { - vkey: 'VK_MEDIA_PLAY_PAUSE', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - MediaSelect: { - vkey: 'VK_LAUNCH_MEDIA_SELECT', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchMail: { - vkey: 'VK_LAUNCH_MAIL', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchApp2: { - vkey: 'VK_LAUNCH_APP2', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - LaunchApp1: { - vkey: 'VK_LAUNCH_APP1', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserSearch: { - vkey: 'VK_BROWSER_SEARCH', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserHome: { - vkey: 'VK_BROWSER_HOME', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserBack: { - vkey: 'VK_BROWSER_BACK', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserForward: { - vkey: 'VK_BROWSER_FORWARD', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserStop: { - vkey: 'VK_BROWSER_STOP', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserRefresh: { - vkey: 'VK_BROWSER_REFRESH', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - }, - BrowserFavorites: { - vkey: 'VK_BROWSER_FAVORITES', - value: '', - withShift: '', - withAltGr: '', - withShiftAltGr: '' - } -}); diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/win_ru.txt b/src/vs/workbench/services/keybinding/test/electron-browser/win_ru.txt deleted file mode 100644 index 61af5ab16e7..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/win_ru.txt +++ /dev/null @@ -1,284 +0,0 @@ ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyA | ф | A | A | a | | -| Shift+KeyA | Ф | Shift+A | Shift+A | shift+a | | -| Ctrl+Alt+KeyA | --- | Ctrl+Alt+A | Ctrl+Alt+A | ctrl+alt+a | | -| Ctrl+Shift+Alt+KeyA | --- | Ctrl+Shift+Alt+A | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyB | и | B | B | b | | -| Shift+KeyB | И | Shift+B | Shift+B | shift+b | | -| Ctrl+Alt+KeyB | --- | Ctrl+Alt+B | Ctrl+Alt+B | ctrl+alt+b | | -| Ctrl+Shift+Alt+KeyB | --- | Ctrl+Shift+Alt+B | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyC | с | C | C | c | | -| Shift+KeyC | С | Shift+C | Shift+C | shift+c | | -| Ctrl+Alt+KeyC | --- | Ctrl+Alt+C | Ctrl+Alt+C | ctrl+alt+c | | -| Ctrl+Shift+Alt+KeyC | --- | Ctrl+Shift+Alt+C | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyD | в | D | D | d | | -| Shift+KeyD | В | Shift+D | Shift+D | shift+d | | -| Ctrl+Alt+KeyD | --- | Ctrl+Alt+D | Ctrl+Alt+D | ctrl+alt+d | | -| Ctrl+Shift+Alt+KeyD | --- | Ctrl+Shift+Alt+D | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyE | у | E | E | e | | -| Shift+KeyE | У | Shift+E | Shift+E | shift+e | | -| Ctrl+Alt+KeyE | --- | Ctrl+Alt+E | Ctrl+Alt+E | ctrl+alt+e | | -| Ctrl+Shift+Alt+KeyE | --- | Ctrl+Shift+Alt+E | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyF | а | F | F | f | | -| Shift+KeyF | А | Shift+F | Shift+F | shift+f | | -| Ctrl+Alt+KeyF | --- | Ctrl+Alt+F | Ctrl+Alt+F | ctrl+alt+f | | -| Ctrl+Shift+Alt+KeyF | --- | Ctrl+Shift+Alt+F | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyG | п | G | G | g | | -| Shift+KeyG | П | Shift+G | Shift+G | shift+g | | -| Ctrl+Alt+KeyG | --- | Ctrl+Alt+G | Ctrl+Alt+G | ctrl+alt+g | | -| Ctrl+Shift+Alt+KeyG | --- | Ctrl+Shift+Alt+G | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyH | р | H | H | h | | -| Shift+KeyH | Р | Shift+H | Shift+H | shift+h | | -| Ctrl+Alt+KeyH | --- | Ctrl+Alt+H | Ctrl+Alt+H | ctrl+alt+h | | -| Ctrl+Shift+Alt+KeyH | --- | Ctrl+Shift+Alt+H | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyI | ш | I | I | i | | -| Shift+KeyI | Ш | Shift+I | Shift+I | shift+i | | -| Ctrl+Alt+KeyI | --- | Ctrl+Alt+I | Ctrl+Alt+I | ctrl+alt+i | | -| Ctrl+Shift+Alt+KeyI | --- | Ctrl+Shift+Alt+I | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyJ | о | J | J | j | | -| Shift+KeyJ | О | Shift+J | Shift+J | shift+j | | -| Ctrl+Alt+KeyJ | --- | Ctrl+Alt+J | Ctrl+Alt+J | ctrl+alt+j | | -| Ctrl+Shift+Alt+KeyJ | --- | Ctrl+Shift+Alt+J | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyK | л | K | K | k | | -| Shift+KeyK | Л | Shift+K | Shift+K | shift+k | | -| Ctrl+Alt+KeyK | --- | Ctrl+Alt+K | Ctrl+Alt+K | ctrl+alt+k | | -| Ctrl+Shift+Alt+KeyK | --- | Ctrl+Shift+Alt+K | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyL | д | L | L | l | | -| Shift+KeyL | Д | Shift+L | Shift+L | shift+l | | -| Ctrl+Alt+KeyL | --- | Ctrl+Alt+L | Ctrl+Alt+L | ctrl+alt+l | | -| Ctrl+Shift+Alt+KeyL | --- | Ctrl+Shift+Alt+L | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyM | ь | M | M | m | | -| Shift+KeyM | Ь | Shift+M | Shift+M | shift+m | | -| Ctrl+Alt+KeyM | --- | Ctrl+Alt+M | Ctrl+Alt+M | ctrl+alt+m | | -| Ctrl+Shift+Alt+KeyM | --- | Ctrl+Shift+Alt+M | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyN | т | N | N | n | | -| Shift+KeyN | Т | Shift+N | Shift+N | shift+n | | -| Ctrl+Alt+KeyN | --- | Ctrl+Alt+N | Ctrl+Alt+N | ctrl+alt+n | | -| Ctrl+Shift+Alt+KeyN | --- | Ctrl+Shift+Alt+N | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyO | щ | O | O | o | | -| Shift+KeyO | Щ | Shift+O | Shift+O | shift+o | | -| Ctrl+Alt+KeyO | --- | Ctrl+Alt+O | Ctrl+Alt+O | ctrl+alt+o | | -| Ctrl+Shift+Alt+KeyO | --- | Ctrl+Shift+Alt+O | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyP | з | P | P | p | | -| Shift+KeyP | З | Shift+P | Shift+P | shift+p | | -| Ctrl+Alt+KeyP | --- | Ctrl+Alt+P | Ctrl+Alt+P | ctrl+alt+p | | -| Ctrl+Shift+Alt+KeyP | --- | Ctrl+Shift+Alt+P | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyQ | й | Q | Q | q | | -| Shift+KeyQ | Й | Shift+Q | Shift+Q | shift+q | | -| Ctrl+Alt+KeyQ | --- | Ctrl+Alt+Q | Ctrl+Alt+Q | ctrl+alt+q | | -| Ctrl+Shift+Alt+KeyQ | --- | Ctrl+Shift+Alt+Q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyR | к | R | R | r | | -| Shift+KeyR | К | Shift+R | Shift+R | shift+r | | -| Ctrl+Alt+KeyR | --- | Ctrl+Alt+R | Ctrl+Alt+R | ctrl+alt+r | | -| Ctrl+Shift+Alt+KeyR | --- | Ctrl+Shift+Alt+R | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyS | ы | S | S | s | | -| Shift+KeyS | Ы | Shift+S | Shift+S | shift+s | | -| Ctrl+Alt+KeyS | --- | Ctrl+Alt+S | Ctrl+Alt+S | ctrl+alt+s | | -| Ctrl+Shift+Alt+KeyS | --- | Ctrl+Shift+Alt+S | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyT | е | T | T | t | | -| Shift+KeyT | Е | Shift+T | Shift+T | shift+t | | -| Ctrl+Alt+KeyT | --- | Ctrl+Alt+T | Ctrl+Alt+T | ctrl+alt+t | | -| Ctrl+Shift+Alt+KeyT | --- | Ctrl+Shift+Alt+T | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyU | г | U | U | u | | -| Shift+KeyU | Г | Shift+U | Shift+U | shift+u | | -| Ctrl+Alt+KeyU | --- | Ctrl+Alt+U | Ctrl+Alt+U | ctrl+alt+u | | -| Ctrl+Shift+Alt+KeyU | --- | Ctrl+Shift+Alt+U | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyV | м | V | V | v | | -| Shift+KeyV | М | Shift+V | Shift+V | shift+v | | -| Ctrl+Alt+KeyV | --- | Ctrl+Alt+V | Ctrl+Alt+V | ctrl+alt+v | | -| Ctrl+Shift+Alt+KeyV | --- | Ctrl+Shift+Alt+V | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyW | ц | W | W | w | | -| Shift+KeyW | Ц | Shift+W | Shift+W | shift+w | | -| Ctrl+Alt+KeyW | --- | Ctrl+Alt+W | Ctrl+Alt+W | ctrl+alt+w | | -| Ctrl+Shift+Alt+KeyW | --- | Ctrl+Shift+Alt+W | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyX | ч | X | X | x | | -| Shift+KeyX | Ч | Shift+X | Shift+X | shift+x | | -| Ctrl+Alt+KeyX | --- | Ctrl+Alt+X | Ctrl+Alt+X | ctrl+alt+x | | -| Ctrl+Shift+Alt+KeyX | --- | Ctrl+Shift+Alt+X | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyY | н | Y | Y | y | | -| Shift+KeyY | Н | Shift+Y | Shift+Y | shift+y | | -| Ctrl+Alt+KeyY | --- | Ctrl+Alt+Y | Ctrl+Alt+Y | ctrl+alt+y | | -| Ctrl+Shift+Alt+KeyY | --- | Ctrl+Shift+Alt+Y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | | ------------------------------------------------------------------------------------------------------------------------------------------ -| KeyZ | я | Z | Z | z | | -| Shift+KeyZ | Я | Shift+Z | Shift+Z | shift+z | | -| Ctrl+Alt+KeyZ | --- | Ctrl+Alt+Z | Ctrl+Alt+Z | ctrl+alt+z | | -| Ctrl+Shift+Alt+KeyZ | --- | Ctrl+Shift+Alt+Z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit1 | 1 | 1 | 1 | 1 | | -| Shift+Digit1 | ! | Shift+1 | Shift+1 | shift+1 | | -| Ctrl+Alt+Digit1 | --- | Ctrl+Alt+1 | Ctrl+Alt+1 | ctrl+alt+1 | | -| Ctrl+Shift+Alt+Digit1 | --- | Ctrl+Shift+Alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit2 | 2 | 2 | 2 | 2 | | -| Shift+Digit2 | " | Shift+2 | Shift+2 | shift+2 | | -| Ctrl+Alt+Digit2 | --- | Ctrl+Alt+2 | Ctrl+Alt+2 | ctrl+alt+2 | | -| Ctrl+Shift+Alt+Digit2 | --- | Ctrl+Shift+Alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit3 | 3 | 3 | 3 | 3 | | -| Shift+Digit3 | № | Shift+3 | Shift+3 | shift+3 | | -| Ctrl+Alt+Digit3 | --- | Ctrl+Alt+3 | Ctrl+Alt+3 | ctrl+alt+3 | | -| Ctrl+Shift+Alt+Digit3 | --- | Ctrl+Shift+Alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit4 | 4 | 4 | 4 | 4 | | -| Shift+Digit4 | ; | Shift+4 | Shift+4 | shift+4 | | -| Ctrl+Alt+Digit4 | --- | Ctrl+Alt+4 | Ctrl+Alt+4 | ctrl+alt+4 | | -| Ctrl+Shift+Alt+Digit4 | --- | Ctrl+Shift+Alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit5 | 5 | 5 | 5 | 5 | | -| Shift+Digit5 | % | Shift+5 | Shift+5 | shift+5 | | -| Ctrl+Alt+Digit5 | --- | Ctrl+Alt+5 | Ctrl+Alt+5 | ctrl+alt+5 | | -| Ctrl+Shift+Alt+Digit5 | --- | Ctrl+Shift+Alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit6 | 6 | 6 | 6 | 6 | | -| Shift+Digit6 | : | Shift+6 | Shift+6 | shift+6 | | -| Ctrl+Alt+Digit6 | --- | Ctrl+Alt+6 | Ctrl+Alt+6 | ctrl+alt+6 | | -| Ctrl+Shift+Alt+Digit6 | --- | Ctrl+Shift+Alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit7 | 7 | 7 | 7 | 7 | | -| Shift+Digit7 | ? | Shift+7 | Shift+7 | shift+7 | | -| Ctrl+Alt+Digit7 | --- | Ctrl+Alt+7 | Ctrl+Alt+7 | ctrl+alt+7 | | -| Ctrl+Shift+Alt+Digit7 | --- | Ctrl+Shift+Alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit8 | 8 | 8 | 8 | 8 | | -| Shift+Digit8 | * | Shift+8 | Shift+8 | shift+8 | | -| Ctrl+Alt+Digit8 | ₽ | Ctrl+Alt+8 | Ctrl+Alt+8 | ctrl+alt+8 | | -| Ctrl+Shift+Alt+Digit8 | --- | Ctrl+Shift+Alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit9 | 9 | 9 | 9 | 9 | | -| Shift+Digit9 | ( | Shift+9 | Shift+9 | shift+9 | | -| Ctrl+Alt+Digit9 | --- | Ctrl+Alt+9 | Ctrl+Alt+9 | ctrl+alt+9 | | -| Ctrl+Shift+Alt+Digit9 | --- | Ctrl+Shift+Alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Digit0 | 0 | 0 | 0 | 0 | | -| Shift+Digit0 | ) | Shift+0 | Shift+0 | shift+0 | | -| Ctrl+Alt+Digit0 | --- | Ctrl+Alt+0 | Ctrl+Alt+0 | ctrl+alt+0 | | -| Ctrl+Shift+Alt+Digit0 | --- | Ctrl+Shift+Alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| Minus | - | - | - | oem_minus | NO | -| Shift+Minus | _ | Shift+- | Shift+- | shift+oem_minus | NO | -| Ctrl+Alt+Minus | --- | Ctrl+Alt+- | Ctrl+Alt+- | ctrl+alt+oem_minus | NO | -| Ctrl+Shift+Alt+Minus | --- | Ctrl+Shift+Alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+oem_minus | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Equal | = | = | = | oem_plus | NO | -| Shift+Equal | + | Shift+= | Shift+= | shift+oem_plus | NO | -| Ctrl+Alt+Equal | --- | Ctrl+Alt+= | Ctrl+Alt+= | ctrl+alt+oem_plus | NO | -| Ctrl+Shift+Alt+Equal | --- | Ctrl+Shift+Alt+= | Ctrl+Shift+Alt+= | ctrl+shift+alt+oem_plus | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| BracketLeft | х | [ | [ | oem_4 | NO | -| Shift+BracketLeft | Х | Shift+[ | Shift+[ | shift+oem_4 | NO | -| Ctrl+Alt+BracketLeft | --- | Ctrl+Alt+[ | Ctrl+Alt+[ | ctrl+alt+oem_4 | NO | -| Ctrl+Shift+Alt+BracketLeft | --- | Ctrl+Shift+Alt+[ | Ctrl+Shift+Alt+[ | ctrl+shift+alt+oem_4 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| BracketRight | ъ | ] | ] | oem_6 | NO | -| Shift+BracketRight | Ъ | Shift+] | Shift+] | shift+oem_6 | NO | -| Ctrl+Alt+BracketRight | --- | Ctrl+Alt+] | Ctrl+Alt+] | ctrl+alt+oem_6 | NO | -| Ctrl+Shift+Alt+BracketRight | --- | Ctrl+Shift+Alt+] | Ctrl+Shift+Alt+] | ctrl+shift+alt+oem_6 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Backslash | \ | \ | \ | oem_5 | NO | -| Shift+Backslash | / | Shift+\ | Shift+\ | shift+oem_5 | NO | -| Ctrl+Alt+Backslash | --- | Ctrl+Alt+\ | Ctrl+Alt+\ | ctrl+alt+oem_5 | NO | -| Ctrl+Shift+Alt+Backslash | --- | Ctrl+Shift+Alt+\ | Ctrl+Shift+Alt+\ | ctrl+shift+alt+oem_5 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlHash | --- | null | null | null | NO | -| Shift+IntlHash | --- | null | null | null | NO | -| Ctrl+Alt+IntlHash | --- | null | null | null | NO | -| Ctrl+Shift+Alt+IntlHash | --- | null | null | null | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| Semicolon | ж | ; | ; | oem_1 | NO | -| Shift+Semicolon | Ж | Shift+; | Shift+; | shift+oem_1 | NO | -| Ctrl+Alt+Semicolon | --- | Ctrl+Alt+; | Ctrl+Alt+; | ctrl+alt+oem_1 | NO | -| Ctrl+Shift+Alt+Semicolon | --- | Ctrl+Shift+Alt+; | Ctrl+Shift+Alt+; | ctrl+shift+alt+oem_1 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Quote | э | ' | ' | oem_7 | NO | -| Shift+Quote | Э | Shift+' | Shift+' | shift+oem_7 | NO | -| Ctrl+Alt+Quote | --- | Ctrl+Alt+' | Ctrl+Alt+' | ctrl+alt+oem_7 | NO | -| Ctrl+Shift+Alt+Quote | --- | Ctrl+Shift+Alt+' | Ctrl+Shift+Alt+' | ctrl+shift+alt+oem_7 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Backquote | ё | ` | ` | oem_3 | NO | -| Shift+Backquote | Ё | Shift+` | Shift+` | shift+oem_3 | NO | -| Ctrl+Alt+Backquote | --- | Ctrl+Alt+` | Ctrl+Alt+` | ctrl+alt+oem_3 | NO | -| Ctrl+Shift+Alt+Backquote | --- | Ctrl+Shift+Alt+` | Ctrl+Shift+Alt+` | ctrl+shift+alt+oem_3 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Comma | б | , | , | oem_comma | NO | -| Shift+Comma | Б | Shift+, | Shift+, | shift+oem_comma | NO | -| Ctrl+Alt+Comma | --- | Ctrl+Alt+, | Ctrl+Alt+, | ctrl+alt+oem_comma | NO | -| Ctrl+Shift+Alt+Comma | --- | Ctrl+Shift+Alt+, | Ctrl+Shift+Alt+, | ctrl+shift+alt+oem_comma | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Period | ю | . | . | oem_period | NO | -| Shift+Period | Ю | Shift+. | Shift+. | shift+oem_period | NO | -| Ctrl+Alt+Period | --- | Ctrl+Alt+. | Ctrl+Alt+. | ctrl+alt+oem_period | NO | -| Ctrl+Shift+Alt+Period | --- | Ctrl+Shift+Alt+. | Ctrl+Shift+Alt+. | ctrl+shift+alt+oem_period | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| Slash | . | / | / | oem_2 | NO | -| Shift+Slash | , | Shift+/ | Shift+/ | shift+oem_2 | NO | -| Ctrl+Alt+Slash | --- | Ctrl+Alt+/ | Ctrl+Alt+/ | ctrl+alt+oem_2 | NO | -| Ctrl+Shift+Alt+Slash | --- | Ctrl+Shift+Alt+/ | Ctrl+Shift+Alt+/ | ctrl+shift+alt+oem_2 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | ------------------------------------------------------------------------------------------------------------------------------------------ -| ArrowUp | --- | UpArrow | UpArrow | up | | -| Shift+ArrowUp | --- | Shift+UpArrow | Shift+UpArrow | shift+up | | -| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | Ctrl+Alt+UpArrow | ctrl+alt+up | | -| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | | ------------------------------------------------------------------------------------------------------------------------------------------ -| Numpad0 | --- | NumPad0 | NumPad0 | numpad0 | | -| Shift+Numpad0 | --- | Shift+NumPad0 | Shift+NumPad0 | shift+numpad0 | | -| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | | -| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlBackslash | \ | OEM_102 | \ | oem_102 | NO | -| Shift+IntlBackslash | / | Shift+OEM_102 | Shift+\ | shift+oem_102 | NO | -| Ctrl+Alt+IntlBackslash | --- | Ctrl+Alt+OEM_102 | Ctrl+Alt+\ | ctrl+alt+oem_102 | NO | -| Ctrl+Shift+Alt+IntlBackslash | --- | Ctrl+Shift+Alt+OEM_102 | Ctrl+Shift+Alt+\ | ctrl+shift+alt+oem_102 | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlRo | --- | null | null | null | NO | -| Shift+IntlRo | --- | null | null | null | NO | -| Ctrl+Alt+IntlRo | --- | null | null | null | NO | -| Ctrl+Shift+Alt+IntlRo | --- | null | null | null | NO | ------------------------------------------------------------------------------------------------------------------------------------------ -| IntlYen | --- | null | null | null | NO | -| Shift+IntlYen | --- | null | null | null | NO | -| Ctrl+Alt+IntlYen | --- | null | null | null | NO | -| Ctrl+Shift+Alt+IntlYen | --- | null | null | null | NO | ------------------------------------------------------------------------------------------------------------------------------------------ \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/windowsKeyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/electron-browser/windowsKeyboardMapper.test.ts deleted file mode 100644 index f4e3a99adc0..00000000000 --- a/src/vs/workbench/services/keybinding/test/electron-browser/windowsKeyboardMapper.test.ts +++ /dev/null @@ -1,658 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { KeyChord, KeyCode, KeyMod, ScanCode } from 'vs/base/common/keyCodes'; -import { SimpleKeybinding, createKeybinding, ScanCodeBinding } from 'vs/base/common/keybindings'; -import { OperatingSystem } from 'vs/base/common/platform'; -import { WindowsKeyboardMapper } from 'vs/workbench/services/keybinding/common/windowsKeyboardMapper'; -import { IResolvedKeybinding, assertMapping, assertResolveKeybinding, assertResolveKeyboardEvent, assertResolveUserBinding, readRawMapping } from 'vs/workbench/services/keybinding/test/electron-browser/keyboardMapperTestUtils'; -import { IWindowsKeyboardMapping } from 'vs/platform/keyboardLayout/common/keyboardLayout'; - -const WRITE_FILE_IF_DIFFERENT = false; - -async function createKeyboardMapper(isUSStandard: boolean, file: string): Promise { - const rawMappings = await readRawMapping(file); - return new WindowsKeyboardMapper(isUSStandard, rawMappings); -} - -function _assertResolveKeybinding(mapper: WindowsKeyboardMapper, k: number, expected: IResolvedKeybinding[]): void { - const keyBinding = createKeybinding(k, OperatingSystem.Windows); - assertResolveKeybinding(mapper, keyBinding!, expected); -} - -suite('keyboardMapper - WINDOWS de_ch', () => { - - let mapper: WindowsKeyboardMapper; - - suiteSetup(async () => { - mapper = await createKeyboardMapper(false, 'win_de_ch'); - }); - - test('mapping', () => { - return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'win_de_ch.txt'); - }); - - test('resolveKeybinding Ctrl+A', () => { - _assertResolveKeybinding( - mapper, - KeyMod.CtrlCmd | KeyCode.KeyA, - [{ - label: 'Ctrl+A', - ariaLabel: 'Control+A', - electronAccelerator: 'Ctrl+A', - userSettingsLabel: 'ctrl+a', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+A'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+Z', () => { - _assertResolveKeybinding( - mapper, - KeyMod.CtrlCmd | KeyCode.KeyZ, - [{ - label: 'Ctrl+Z', - ariaLabel: 'Control+Z', - electronAccelerator: 'Ctrl+Z', - userSettingsLabel: 'ctrl+z', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+Z'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeyboardEvent Ctrl+Z', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: KeyCode.KeyZ, - code: null! - }, - { - label: 'Ctrl+Z', - ariaLabel: 'Control+Z', - electronAccelerator: 'Ctrl+Z', - userSettingsLabel: 'ctrl+z', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+Z'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveKeybinding Ctrl+]', () => { - _assertResolveKeybinding( - mapper, - KeyMod.CtrlCmd | KeyCode.BracketRight, - [{ - label: 'Ctrl+^', - ariaLabel: 'Control+^', - electronAccelerator: 'Ctrl+]', - userSettingsLabel: 'ctrl+oem_6', - isWYSIWYG: false, - isChord: false, - dispatchParts: ['ctrl+]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeyboardEvent Ctrl+]', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: KeyCode.BracketRight, - code: null! - }, - { - label: 'Ctrl+^', - ariaLabel: 'Control+^', - electronAccelerator: 'Ctrl+]', - userSettingsLabel: 'ctrl+oem_6', - isWYSIWYG: false, - isChord: false, - dispatchParts: ['ctrl+]'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveKeybinding Shift+]', () => { - _assertResolveKeybinding( - mapper, - KeyMod.Shift | KeyCode.BracketRight, - [{ - label: 'Shift+^', - ariaLabel: 'Shift+^', - electronAccelerator: 'Shift+]', - userSettingsLabel: 'shift+oem_6', - isWYSIWYG: false, - isChord: false, - dispatchParts: ['shift+]'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+/', () => { - _assertResolveKeybinding( - mapper, - KeyMod.CtrlCmd | KeyCode.Slash, - [{ - label: 'Ctrl+§', - ariaLabel: 'Control+§', - electronAccelerator: 'Ctrl+/', - userSettingsLabel: 'ctrl+oem_2', - isWYSIWYG: false, - isChord: false, - dispatchParts: ['ctrl+/'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+Shift+/', () => { - _assertResolveKeybinding( - mapper, - KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Slash, - [{ - label: 'Ctrl+Shift+§', - ariaLabel: 'Control+Shift+§', - electronAccelerator: 'Ctrl+Shift+/', - userSettingsLabel: 'ctrl+shift+oem_2', - isWYSIWYG: false, - isChord: false, - dispatchParts: ['ctrl+shift+/'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+K Ctrl+\\', () => { - _assertResolveKeybinding( - mapper, - KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Backslash), - [{ - label: 'Ctrl+K Ctrl+ä', - ariaLabel: 'Control+K Control+ä', - electronAccelerator: null, - userSettingsLabel: 'ctrl+k ctrl+oem_5', - isWYSIWYG: false, - isChord: true, - dispatchParts: ['ctrl+K', 'ctrl+\\'], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveKeybinding Ctrl+K Ctrl+=', () => { - _assertResolveKeybinding( - mapper, - KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Equal), - [] - ); - }); - - test('resolveKeybinding Ctrl+DownArrow', () => { - _assertResolveKeybinding( - mapper, - KeyMod.CtrlCmd | KeyCode.DownArrow, - [{ - label: 'Ctrl+DownArrow', - ariaLabel: 'Control+DownArrow', - electronAccelerator: 'Ctrl+Down', - userSettingsLabel: 'ctrl+down', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+DownArrow'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+NUMPAD_0', () => { - _assertResolveKeybinding( - mapper, - KeyMod.CtrlCmd | KeyCode.Numpad0, - [{ - label: 'Ctrl+NumPad0', - ariaLabel: 'Control+NumPad0', - electronAccelerator: null, - userSettingsLabel: 'ctrl+numpad0', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+NumPad0'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeybinding Ctrl+Home', () => { - _assertResolveKeybinding( - mapper, - KeyMod.CtrlCmd | KeyCode.Home, - [{ - label: 'Ctrl+Home', - ariaLabel: 'Control+Home', - electronAccelerator: 'Ctrl+Home', - userSettingsLabel: 'ctrl+home', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+Home'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeyboardEvent Ctrl+Home', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: KeyCode.Home, - code: null! - }, - { - label: 'Ctrl+Home', - ariaLabel: 'Control+Home', - electronAccelerator: 'Ctrl+Home', - userSettingsLabel: 'ctrl+home', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+Home'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveUserBinding empty', () => { - assertResolveUserBinding(mapper, [], []); - }); - - test('resolveUserBinding Ctrl+[Comma] Ctrl+/', () => { - assertResolveUserBinding( - mapper, [ - new ScanCodeBinding(true, false, false, false, ScanCode.Comma), - new SimpleKeybinding(true, false, false, false, KeyCode.Slash), - ], - [{ - label: 'Ctrl+, Ctrl+§', - ariaLabel: 'Control+, Control+§', - electronAccelerator: null, - userSettingsLabel: 'ctrl+oem_comma ctrl+oem_2', - isWYSIWYG: false, - isChord: true, - dispatchParts: ['ctrl+,', 'ctrl+/'], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveKeyboardEvent Single Modifier Ctrl+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: KeyCode.Ctrl, - code: null! - }, - { - label: 'Ctrl', - ariaLabel: 'Control', - electronAccelerator: null, - userSettingsLabel: 'ctrl', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['ctrl'], - } - ); - }); -}); - -suite('keyboardMapper - WINDOWS en_us', () => { - - let mapper: WindowsKeyboardMapper; - - suiteSetup(async () => { - mapper = await createKeyboardMapper(true, 'win_en_us'); - }); - - test('mapping', () => { - return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'win_en_us.txt'); - }); - - test('resolveKeybinding Ctrl+K Ctrl+\\', () => { - _assertResolveKeybinding( - mapper, - KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Backslash), - [{ - label: 'Ctrl+K Ctrl+\\', - ariaLabel: 'Control+K Control+\\', - electronAccelerator: null, - userSettingsLabel: 'ctrl+k ctrl+\\', - isWYSIWYG: true, - isChord: true, - dispatchParts: ['ctrl+K', 'ctrl+\\'], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveUserBinding Ctrl+[Comma] Ctrl+/', () => { - assertResolveUserBinding( - mapper, [ - new ScanCodeBinding(true, false, false, false, ScanCode.Comma), - new SimpleKeybinding(true, false, false, false, KeyCode.Slash), - ], - [{ - label: 'Ctrl+, Ctrl+/', - ariaLabel: 'Control+, Control+/', - electronAccelerator: null, - userSettingsLabel: 'ctrl+, ctrl+/', - isWYSIWYG: true, - isChord: true, - dispatchParts: ['ctrl+,', 'ctrl+/'], - singleModifierDispatchParts: [null, null], - }] - ); - }); - - test('resolveUserBinding Ctrl+[Comma]', () => { - assertResolveUserBinding( - mapper, [ - new ScanCodeBinding(true, false, false, false, ScanCode.Comma), - ], - [{ - label: 'Ctrl+,', - ariaLabel: 'Control+,', - electronAccelerator: 'Ctrl+,', - userSettingsLabel: 'ctrl+,', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+,'], - singleModifierDispatchParts: [null], - }] - ); - }); - - test('resolveKeyboardEvent Single Modifier Ctrl+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: KeyCode.Ctrl, - code: null! - }, - { - label: 'Ctrl', - ariaLabel: 'Control', - electronAccelerator: null, - userSettingsLabel: 'ctrl', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['ctrl'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier Shift+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: true, - altKey: false, - metaKey: false, - keyCode: KeyCode.Shift, - code: null! - }, - { - label: 'Shift', - ariaLabel: 'Shift', - electronAccelerator: null, - userSettingsLabel: 'shift', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['shift'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier Alt+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: true, - metaKey: false, - keyCode: KeyCode.Alt, - code: null! - }, - { - label: 'Alt', - ariaLabel: 'Alt', - electronAccelerator: null, - userSettingsLabel: 'alt', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['alt'], - } - ); - }); - - test('resolveKeyboardEvent Single Modifier Meta+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: false, - shiftKey: false, - altKey: false, - metaKey: true, - keyCode: KeyCode.Meta, - code: null! - }, - { - label: 'Windows', - ariaLabel: 'Windows', - electronAccelerator: null, - userSettingsLabel: 'win', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: ['meta'], - } - ); - }); - - test('resolveKeyboardEvent Only Modifiers Ctrl+Shift+', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: true, - altKey: false, - metaKey: false, - keyCode: KeyCode.Shift, - code: null! - }, - { - label: 'Ctrl+Shift', - ariaLabel: 'Control+Shift', - electronAccelerator: null, - userSettingsLabel: 'ctrl+shift', - isWYSIWYG: true, - isChord: false, - dispatchParts: [null], - singleModifierDispatchParts: [null], - } - ); - }); -}); - -suite('keyboardMapper - WINDOWS por_ptb', () => { - - let mapper: WindowsKeyboardMapper; - - suiteSetup(async () => { - mapper = await createKeyboardMapper(false, 'win_por_ptb'); - }); - - test('mapping', () => { - return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'win_por_ptb.txt'); - }); - - test('resolveKeyboardEvent Ctrl+[IntlRo]', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: KeyCode.ABNT_C1, - code: null! - }, - { - label: 'Ctrl+/', - ariaLabel: 'Control+/', - electronAccelerator: 'Ctrl+ABNT_C1', - userSettingsLabel: 'ctrl+abnt_c1', - isWYSIWYG: false, - isChord: false, - dispatchParts: ['ctrl+ABNT_C1'], - singleModifierDispatchParts: [null], - } - ); - }); - - test('resolveKeyboardEvent Ctrl+[NumpadComma]', () => { - assertResolveKeyboardEvent( - mapper, - { - _standardKeyboardEventBrand: true, - ctrlKey: true, - shiftKey: false, - altKey: false, - metaKey: false, - keyCode: KeyCode.ABNT_C2, - code: null! - }, - { - label: 'Ctrl+.', - ariaLabel: 'Control+.', - electronAccelerator: 'Ctrl+ABNT_C2', - userSettingsLabel: 'ctrl+abnt_c2', - isWYSIWYG: false, - isChord: false, - dispatchParts: ['ctrl+ABNT_C2'], - singleModifierDispatchParts: [null], - } - ); - }); -}); - -suite('keyboardMapper - WINDOWS ru', () => { - - let mapper: WindowsKeyboardMapper; - - suiteSetup(async () => { - mapper = await createKeyboardMapper(false, 'win_ru'); - }); - - test('mapping', () => { - return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'win_ru.txt'); - }); - - test('issue ##24361: resolveKeybinding Ctrl+K Ctrl+K', () => { - _assertResolveKeybinding( - mapper, - KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyK), - [{ - label: 'Ctrl+K Ctrl+K', - ariaLabel: 'Control+K Control+K', - electronAccelerator: null, - userSettingsLabel: 'ctrl+k ctrl+k', - isWYSIWYG: true, - isChord: true, - dispatchParts: ['ctrl+K', 'ctrl+K'], - singleModifierDispatchParts: [null, null], - }] - ); - }); -}); - -suite('keyboardMapper - misc', () => { - test('issue #23513: Toggle Sidebar Visibility and Go to Line display same key mapping in Arabic keyboard', () => { - const mapper = new WindowsKeyboardMapper(false, { - 'KeyB': { - 'vkey': 'VK_B', - 'value': 'لا', - 'withShift': 'لآ', - 'withAltGr': '', - 'withShiftAltGr': '' - }, - 'KeyG': { - 'vkey': 'VK_G', - 'value': 'ل', - 'withShift': 'لأ', - 'withAltGr': '', - 'withShiftAltGr': '' - } - }); - - _assertResolveKeybinding( - mapper, - KeyMod.CtrlCmd | KeyCode.KeyB, - [{ - label: 'Ctrl+B', - ariaLabel: 'Control+B', - electronAccelerator: 'Ctrl+B', - userSettingsLabel: 'ctrl+b', - isWYSIWYG: true, - isChord: false, - dispatchParts: ['ctrl+B'], - singleModifierDispatchParts: [null], - }] - ); - }); -}); diff --git a/src/vs/workbench/services/keybinding/test/node/keyboardMapperTestUtils.ts b/src/vs/workbench/services/keybinding/test/node/keyboardMapperTestUtils.ts new file mode 100644 index 00000000000..742d09e2c3a --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/keyboardMapperTestUtils.ts @@ -0,0 +1,77 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import * as path from 'vs/base/common/path'; +import { getPathFromAmdModule } from 'vs/base/test/node/testUtils'; +import { Keybinding, KeybindingModifier, ResolvedKeybinding, SimpleKeybinding, ScanCodeBinding } from 'vs/base/common/keybindings'; +import { Promises } from 'vs/base/node/pfs'; +import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; +import { IKeyboardMapper } from 'vs/platform/keyboardLayout/common/keyboardMapper'; + +export interface IResolvedKeybinding { + label: string | null; + ariaLabel: string | null; + electronAccelerator: string | null; + userSettingsLabel: string | null; + isWYSIWYG: boolean; + isChord: boolean; + dispatchParts: (string | null)[]; + singleModifierDispatchParts: (KeybindingModifier | null)[]; +} + +function toIResolvedKeybinding(kb: ResolvedKeybinding): IResolvedKeybinding { + return { + label: kb.getLabel(), + ariaLabel: kb.getAriaLabel(), + electronAccelerator: kb.getElectronAccelerator(), + userSettingsLabel: kb.getUserSettingsLabel(), + isWYSIWYG: kb.isWYSIWYG(), + isChord: kb.isChord(), + dispatchParts: kb.getDispatchParts(), + singleModifierDispatchParts: kb.getSingleModifierDispatchParts() + }; +} + +export function assertResolveKeybinding(mapper: IKeyboardMapper, keybinding: Keybinding | null, expected: IResolvedKeybinding[]): void { + const actual: IResolvedKeybinding[] = mapper.resolveKeybinding(keybinding!).map(toIResolvedKeybinding); + assert.deepStrictEqual(actual, expected); +} + +export function assertResolveKeyboardEvent(mapper: IKeyboardMapper, keyboardEvent: IKeyboardEvent, expected: IResolvedKeybinding): void { + const actual = toIResolvedKeybinding(mapper.resolveKeyboardEvent(keyboardEvent)); + assert.deepStrictEqual(actual, expected); +} + +export function assertResolveUserBinding(mapper: IKeyboardMapper, parts: (SimpleKeybinding | ScanCodeBinding)[], expected: IResolvedKeybinding[]): void { + const actual: IResolvedKeybinding[] = mapper.resolveUserBinding(parts).map(toIResolvedKeybinding); + assert.deepStrictEqual(actual, expected); +} + +export function readRawMapping(file: string): Promise { + return Promises.readFile(getPathFromAmdModule(require, `vs/workbench/services/keybinding/test/node/${file}.js`)).then((buff) => { + const contents = buff.toString(); + const func = new Function('define', contents); + let rawMappings: T | null = null; + func(function (value: T) { + rawMappings = value; + }); + return rawMappings!; + }); +} + +export function assertMapping(writeFileIfDifferent: boolean, mapper: IKeyboardMapper, file: string): Promise { + const filePath = path.normalize(getPathFromAmdModule(require, `vs/workbench/services/keybinding/test/node/${file}`)); + + return Promises.readFile(filePath).then((buff) => { + const expected = buff.toString().replace(/\r\n/g, '\n'); + const actual = mapper.dumpDebugInfo().replace(/\r\n/g, '\n'); + if (actual !== expected && writeFileIfDifferent) { + const destPath = filePath.replace(/[\/\\]out[\/\\]vs[\/\\]workbench/, '/src/vs/workbench'); + Promises.writeFile(destPath, actual); + } + assert.deepStrictEqual(actual, expected); + }); +} diff --git a/src/vs/workbench/services/keybinding/test/node/linux_de_ch.js b/src/vs/workbench/services/keybinding/test/node/linux_de_ch.js new file mode 100644 index 00000000000..3374e83f679 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/linux_de_ch.js @@ -0,0 +1,491 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +define({ + Sleep: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + WakeUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + KeyA: { + value: 'a', + withShift: 'A', + withAltGr: 'æ', + withShiftAltGr: 'Æ' + }, + KeyB: { + value: 'b', + withShift: 'B', + withAltGr: '”', + withShiftAltGr: '’' + }, + KeyC: { + value: 'c', + withShift: 'C', + withAltGr: '¢', + withShiftAltGr: '©' + }, + KeyD: { + value: 'd', + withShift: 'D', + withAltGr: 'ð', + withShiftAltGr: 'Ð' + }, + KeyE: { + value: 'e', + withShift: 'E', + withAltGr: '€', + withShiftAltGr: 'E' + }, + KeyF: { + value: 'f', + withShift: 'F', + withAltGr: 'đ', + withShiftAltGr: 'ª' + }, + KeyG: { + value: 'g', + withShift: 'G', + withAltGr: 'ŋ', + withShiftAltGr: 'Ŋ' + }, + KeyH: { + value: 'h', + withShift: 'H', + withAltGr: 'ħ', + withShiftAltGr: 'Ħ' + }, + KeyI: { + value: 'i', + withShift: 'I', + withAltGr: '→', + withShiftAltGr: 'ı' + }, + KeyJ: { + value: 'j', + withShift: 'J', + withAltGr: '̉', + withShiftAltGr: '̛' + }, + KeyK: { + value: 'k', + withShift: 'K', + withAltGr: 'ĸ', + withShiftAltGr: '&' + }, + KeyL: { + value: 'l', + withShift: 'L', + withAltGr: 'ł', + withShiftAltGr: 'Ł' + }, + KeyM: { + value: 'm', + withShift: 'M', + withAltGr: 'µ', + withShiftAltGr: 'º' + }, + KeyN: { + value: 'n', + withShift: 'N', + withAltGr: 'n', + withShiftAltGr: 'N' + }, + KeyO: { + value: 'o', + withShift: 'O', + withAltGr: 'œ', + withShiftAltGr: 'Œ' + }, + KeyP: { + value: 'p', + withShift: 'P', + withAltGr: 'þ', + withShiftAltGr: 'Þ' + }, + KeyQ: { + value: 'q', + withShift: 'Q', + withAltGr: '@', + withShiftAltGr: 'Ω' + }, + KeyR: { + value: 'r', + withShift: 'R', + withAltGr: '¶', + withShiftAltGr: '®' + }, + KeyS: { + value: 's', + withShift: 'S', + withAltGr: 'ß', + withShiftAltGr: '§' + }, + KeyT: { + value: 't', + withShift: 'T', + withAltGr: 'ŧ', + withShiftAltGr: 'Ŧ' + }, + KeyU: { + value: 'u', + withShift: 'U', + withAltGr: '↓', + withShiftAltGr: '↑' + }, + KeyV: { + value: 'v', + withShift: 'V', + withAltGr: '“', + withShiftAltGr: '‘' + }, + KeyW: { + value: 'w', + withShift: 'W', + withAltGr: 'ł', + withShiftAltGr: 'Ł' + }, + KeyX: { + value: 'x', + withShift: 'X', + withAltGr: '»', + withShiftAltGr: '>' + }, + KeyY: { + value: 'z', + withShift: 'Z', + withAltGr: '←', + withShiftAltGr: '¥' + }, + KeyZ: { + value: 'y', + withShift: 'Y', + withAltGr: '«', + withShiftAltGr: '<' + }, + Digit1: { + value: '1', + withShift: '+', + withAltGr: '|', + withShiftAltGr: '¡' + }, + Digit2: { + value: '2', + withShift: '"', + withAltGr: '@', + withShiftAltGr: '⅛' + }, + Digit3: { + value: '3', + withShift: '*', + withAltGr: '#', + withShiftAltGr: '£' + }, + Digit4: { + value: '4', + withShift: 'ç', + withAltGr: '¼', + withShiftAltGr: '$' + }, + Digit5: { + value: '5', + withShift: '%', + withAltGr: '½', + withShiftAltGr: '⅜' + }, + Digit6: { + value: '6', + withShift: '&', + withAltGr: '¬', + withShiftAltGr: '⅝' + }, + Digit7: { + value: '7', + withShift: '/', + withAltGr: '|', + withShiftAltGr: '⅞' + }, + Digit8: { + value: '8', + withShift: '(', + withAltGr: '¢', + withShiftAltGr: '™' + }, + Digit9: { + value: '9', + withShift: ')', + withAltGr: ']', + withShiftAltGr: '±' + }, + Digit0: { + value: '0', + withShift: '=', + withAltGr: '}', + withShiftAltGr: '°' + }, + Enter: { + value: '\r', + withShift: '\r', + withAltGr: '\r', + withShiftAltGr: '\r' + }, + Escape: { + value: '\u001b', + withShift: '\u001b', + withAltGr: '\u001b', + withShiftAltGr: '\u001b' + }, + Backspace: { + value: '\b', + withShift: '\b', + withAltGr: '\b', + withShiftAltGr: '\b' + }, + Tab: { + value: '\t', + withShift: '', + withAltGr: '\t', + withShiftAltGr: '' + }, + Space: { + value: ' ', + withShift: ' ', + withAltGr: ' ', + withShiftAltGr: ' ' + }, + Minus: { + value: '\'', + withShift: '?', + withAltGr: '́', + withShiftAltGr: '¿' + }, + Equal: { + value: '̂', + withShift: '̀', + withAltGr: '̃', + withShiftAltGr: '̨' + }, + BracketLeft: { + value: 'ü', + withShift: 'è', + withAltGr: '[', + withShiftAltGr: '̊' + }, + BracketRight: { + value: '̈', + withShift: '!', + withAltGr: ']', + withShiftAltGr: '̄' + }, + Backslash: { + value: '$', + withShift: '£', + withAltGr: '}', + withShiftAltGr: '̆' + }, + Semicolon: { + value: 'ö', + withShift: 'é', + withAltGr: '́', + withShiftAltGr: '̋' + }, + Quote: { + value: 'ä', + withShift: 'à', + withAltGr: '{', + withShiftAltGr: '̌' + }, + Backquote: { + value: '§', + withShift: '°', + withAltGr: '¬', + withShiftAltGr: '¬' + }, + Comma: { + value: ',', + withShift: ';', + withAltGr: '─', + withShiftAltGr: '×' + }, + Period: { + value: '.', + withShift: ':', + withAltGr: '·', + withShiftAltGr: '÷' + }, + Slash: { + value: '-', + withShift: '_', + withAltGr: '̣', + withShiftAltGr: '̇' + }, + CapsLock: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F1: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F2: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F3: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F4: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F5: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F6: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F7: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F8: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F9: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F10: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F11: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F12: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + PrintScreen: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ScrollLock: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Pause: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Insert: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Home: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + PageUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Delete: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + End: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + PageDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ArrowRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ArrowLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ArrowDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ArrowUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + NumLock: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + NumpadDivide: { + value: '/', + withShift: '/', + withAltGr: '/', + withShiftAltGr: '/' + }, + NumpadMultiply: { + value: '*', + withShift: '*', + withAltGr: '*', + withShiftAltGr: '*' + }, + NumpadSubtract: { + value: '-', + withShift: '-', + withAltGr: '-', + withShiftAltGr: '-' + }, + NumpadAdd: { + value: '+', + withShift: '+', + withAltGr: '+', + withShiftAltGr: '+' + }, + NumpadEnter: { + value: '\r', + withShift: '\r', + withAltGr: '\r', + withShiftAltGr: '\r' + }, + Numpad1: { value: '', withShift: '1', withAltGr: '', withShiftAltGr: '1' }, + Numpad2: { value: '', withShift: '2', withAltGr: '', withShiftAltGr: '2' }, + Numpad3: { value: '', withShift: '3', withAltGr: '', withShiftAltGr: '3' }, + Numpad4: { value: '', withShift: '4', withAltGr: '', withShiftAltGr: '4' }, + Numpad5: { value: '', withShift: '5', withAltGr: '', withShiftAltGr: '5' }, + Numpad6: { value: '', withShift: '6', withAltGr: '', withShiftAltGr: '6' }, + Numpad7: { value: '', withShift: '7', withAltGr: '', withShiftAltGr: '7' }, + Numpad8: { value: '', withShift: '8', withAltGr: '', withShiftAltGr: '8' }, + Numpad9: { value: '', withShift: '9', withAltGr: '', withShiftAltGr: '9' }, + Numpad0: { value: '', withShift: '0', withAltGr: '', withShiftAltGr: '0' }, + NumpadDecimal: { value: '', withShift: '.', withAltGr: '', withShiftAltGr: '.' }, + IntlBackslash: { + value: '<', + withShift: '>', + withAltGr: '\\', + withShiftAltGr: '¦' + }, + ContextMenu: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Power: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + NumpadEqual: { + value: '=', + withShift: '=', + withAltGr: '=', + withShiftAltGr: '=' + }, + F13: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F14: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F15: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F16: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F17: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F18: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F19: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F20: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F21: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F22: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F23: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F24: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Open: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Help: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Select: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Again: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Undo: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Cut: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Copy: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Paste: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Find: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + AudioVolumeMute: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + AudioVolumeUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + AudioVolumeDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + NumpadComma: { + value: '.', + withShift: '.', + withAltGr: '.', + withShiftAltGr: '.' + }, + IntlRo: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + KanaMode: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + IntlYen: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Convert: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + NonConvert: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Lang1: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Lang2: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Lang3: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Lang4: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Lang5: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + NumpadParenLeft: { + value: '(', + withShift: '(', + withAltGr: '(', + withShiftAltGr: '(' + }, + NumpadParenRight: { + value: ')', + withShift: ')', + withAltGr: ')', + withShiftAltGr: ')' + }, + ControlLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ShiftLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + AltLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MetaLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ControlRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ShiftRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + AltRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MetaRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrightnessUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrightnessDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaPlay: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaRecord: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaFastForward: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaRewind: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaTrackNext: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaTrackPrevious: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaStop: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Eject: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaPlayPause: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaSelect: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + LaunchMail: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + LaunchApp2: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + LaunchApp1: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + SelectTask: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + LaunchScreenSaver: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrowserSearch: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrowserHome: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrowserBack: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrowserForward: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrowserStop: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrowserRefresh: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrowserFavorites: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MailReply: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MailForward: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MailSend: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' } +}); diff --git a/src/vs/workbench/services/keybinding/test/node/linux_de_ch.txt b/src/vs/workbench/services/keybinding/test/node/linux_de_ch.txt new file mode 100644 index 00000000000..aaf9263ec26 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/linux_de_ch.txt @@ -0,0 +1,529 @@ +isUSStandard: false +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyA | a | A | | A | a | A | [KeyA] | | +| Ctrl+KeyA | a | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | +| Shift+KeyA | A | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | +| Ctrl+Shift+KeyA | A | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | +| Alt+KeyA | a | Alt+A | | Alt+A | alt+a | Alt+A | alt+[KeyA] | | +| Ctrl+Alt+KeyA | æ | Ctrl+Alt+A | | Ctrl+Alt+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | +| Shift+Alt+KeyA | A | Shift+Alt+A | | Shift+Alt+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | +| Ctrl+Shift+Alt+KeyA | Æ | Ctrl+Shift+Alt+A | | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyB | b | B | | B | b | B | [KeyB] | | +| Ctrl+KeyB | b | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | +| Shift+KeyB | B | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | +| Ctrl+Shift+KeyB | B | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | +| Alt+KeyB | b | Alt+B | | Alt+B | alt+b | Alt+B | alt+[KeyB] | | +| Ctrl+Alt+KeyB | ” | Ctrl+Alt+B | | Ctrl+Alt+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | +| Shift+Alt+KeyB | B | Shift+Alt+B | | Shift+Alt+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | +| Ctrl+Shift+Alt+KeyB | ’ | Ctrl+Shift+Alt+B | | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyC | c | C | | C | c | C | [KeyC] | | +| Ctrl+KeyC | c | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | +| Shift+KeyC | C | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | +| Ctrl+Shift+KeyC | C | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | +| Alt+KeyC | c | Alt+C | | Alt+C | alt+c | Alt+C | alt+[KeyC] | | +| Ctrl+Alt+KeyC | ¢ | Ctrl+Alt+C | | Ctrl+Alt+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | +| Shift+Alt+KeyC | C | Shift+Alt+C | | Shift+Alt+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | +| Ctrl+Shift+Alt+KeyC | © | Ctrl+Shift+Alt+C | | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyD | d | D | | D | d | D | [KeyD] | | +| Ctrl+KeyD | d | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | +| Shift+KeyD | D | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | +| Ctrl+Shift+KeyD | D | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | +| Alt+KeyD | d | Alt+D | | Alt+D | alt+d | Alt+D | alt+[KeyD] | | +| Ctrl+Alt+KeyD | ð | Ctrl+Alt+D | | Ctrl+Alt+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | +| Shift+Alt+KeyD | D | Shift+Alt+D | | Shift+Alt+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | +| Ctrl+Shift+Alt+KeyD | Ð | Ctrl+Shift+Alt+D | | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyE | e | E | | E | e | E | [KeyE] | | +| Ctrl+KeyE | e | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | +| Shift+KeyE | E | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | +| Ctrl+Shift+KeyE | E | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | +| Alt+KeyE | e | Alt+E | | Alt+E | alt+e | Alt+E | alt+[KeyE] | | +| Ctrl+Alt+KeyE | € | Ctrl+Alt+E | | Ctrl+Alt+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | +| Shift+Alt+KeyE | E | Shift+Alt+E | | Shift+Alt+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | +| Ctrl+Shift+Alt+KeyE | E | Ctrl+Shift+Alt+E | | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyF | f | F | | F | f | F | [KeyF] | | +| Ctrl+KeyF | f | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | +| Shift+KeyF | F | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | +| Ctrl+Shift+KeyF | F | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | +| Alt+KeyF | f | Alt+F | | Alt+F | alt+f | Alt+F | alt+[KeyF] | | +| Ctrl+Alt+KeyF | đ | Ctrl+Alt+F | | Ctrl+Alt+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | +| Shift+Alt+KeyF | F | Shift+Alt+F | | Shift+Alt+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | +| Ctrl+Shift+Alt+KeyF | ª | Ctrl+Shift+Alt+F | | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyG | g | G | | G | g | G | [KeyG] | | +| Ctrl+KeyG | g | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | +| Shift+KeyG | G | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | +| Ctrl+Shift+KeyG | G | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | +| Alt+KeyG | g | Alt+G | | Alt+G | alt+g | Alt+G | alt+[KeyG] | | +| Ctrl+Alt+KeyG | ŋ | Ctrl+Alt+G | | Ctrl+Alt+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | +| Shift+Alt+KeyG | G | Shift+Alt+G | | Shift+Alt+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | +| Ctrl+Shift+Alt+KeyG | Ŋ | Ctrl+Shift+Alt+G | | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyH | h | H | | H | h | H | [KeyH] | | +| Ctrl+KeyH | h | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | +| Shift+KeyH | H | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | +| Ctrl+Shift+KeyH | H | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | +| Alt+KeyH | h | Alt+H | | Alt+H | alt+h | Alt+H | alt+[KeyH] | | +| Ctrl+Alt+KeyH | ħ | Ctrl+Alt+H | | Ctrl+Alt+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | +| Shift+Alt+KeyH | H | Shift+Alt+H | | Shift+Alt+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | +| Ctrl+Shift+Alt+KeyH | Ħ | Ctrl+Shift+Alt+H | | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyI | i | I | | I | i | I | [KeyI] | | +| Ctrl+KeyI | i | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | +| Shift+KeyI | I | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | +| Ctrl+Shift+KeyI | I | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | +| Alt+KeyI | i | Alt+I | | Alt+I | alt+i | Alt+I | alt+[KeyI] | | +| Ctrl+Alt+KeyI | → | Ctrl+Alt+I | | Ctrl+Alt+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | +| Shift+Alt+KeyI | I | Shift+Alt+I | | Shift+Alt+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | +| Ctrl+Shift+Alt+KeyI | ı | Ctrl+Shift+Alt+I | | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyJ | j | J | | J | j | J | [KeyJ] | | +| Ctrl+KeyJ | j | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | +| Shift+KeyJ | J | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | +| Ctrl+Shift+KeyJ | J | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | +| Alt+KeyJ | j | Alt+J | | Alt+J | alt+j | Alt+J | alt+[KeyJ] | | +| Ctrl+Alt+KeyJ | U+309 | Ctrl+Alt+J | | Ctrl+Alt+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | +| Shift+Alt+KeyJ | J | Shift+Alt+J | | Shift+Alt+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | +| Ctrl+Shift+Alt+KeyJ | U+31b | Ctrl+Shift+Alt+J | | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyK | k | K | | K | k | K | [KeyK] | | +| Ctrl+KeyK | k | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | +| Shift+KeyK | K | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | +| Ctrl+Shift+KeyK | K | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | +| Alt+KeyK | k | Alt+K | | Alt+K | alt+k | Alt+K | alt+[KeyK] | | +| Ctrl+Alt+KeyK | ĸ | Ctrl+Alt+K | | Ctrl+Alt+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | +| Shift+Alt+KeyK | K | Shift+Alt+K | | Shift+Alt+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | +| Ctrl+Shift+Alt+KeyK | & | Ctrl+Shift+Alt+K | | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyL | l | L | | L | l | L | [KeyL] | | +| Ctrl+KeyL | l | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | +| Shift+KeyL | L | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | +| Ctrl+Shift+KeyL | L | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | +| Alt+KeyL | l | Alt+L | | Alt+L | alt+l | Alt+L | alt+[KeyL] | | +| Ctrl+Alt+KeyL | ł | Ctrl+Alt+L | | Ctrl+Alt+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | +| Shift+Alt+KeyL | L | Shift+Alt+L | | Shift+Alt+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | +| Ctrl+Shift+Alt+KeyL | Ł | Ctrl+Shift+Alt+L | | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyM | m | M | | M | m | M | [KeyM] | | +| Ctrl+KeyM | m | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | +| Shift+KeyM | M | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | +| Ctrl+Shift+KeyM | M | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | +| Alt+KeyM | m | Alt+M | | Alt+M | alt+m | Alt+M | alt+[KeyM] | | +| Ctrl+Alt+KeyM | µ | Ctrl+Alt+M | | Ctrl+Alt+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | +| Shift+Alt+KeyM | M | Shift+Alt+M | | Shift+Alt+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | +| Ctrl+Shift+Alt+KeyM | º | Ctrl+Shift+Alt+M | | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyN | n | N | | N | n | N | [KeyN] | | +| Ctrl+KeyN | n | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | +| Shift+KeyN | N | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | +| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | +| Alt+KeyN | n | Alt+N | | Alt+N | alt+n | Alt+N | alt+[KeyN] | | +| Ctrl+Alt+KeyN | n | Ctrl+Alt+N | | Ctrl+Alt+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | +| Shift+Alt+KeyN | N | Shift+Alt+N | | Shift+Alt+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | +| Ctrl+Shift+Alt+KeyN | N | Ctrl+Shift+Alt+N | | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyO | o | O | | O | o | O | [KeyO] | | +| Ctrl+KeyO | o | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | +| Shift+KeyO | O | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | +| Ctrl+Shift+KeyO | O | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | +| Alt+KeyO | o | Alt+O | | Alt+O | alt+o | Alt+O | alt+[KeyO] | | +| Ctrl+Alt+KeyO | œ | Ctrl+Alt+O | | Ctrl+Alt+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | +| Shift+Alt+KeyO | O | Shift+Alt+O | | Shift+Alt+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | +| Ctrl+Shift+Alt+KeyO | Œ | Ctrl+Shift+Alt+O | | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyP | p | P | | P | p | P | [KeyP] | | +| Ctrl+KeyP | p | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | +| Shift+KeyP | P | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | +| Ctrl+Shift+KeyP | P | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | +| Alt+KeyP | p | Alt+P | | Alt+P | alt+p | Alt+P | alt+[KeyP] | | +| Ctrl+Alt+KeyP | þ | Ctrl+Alt+P | | Ctrl+Alt+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | +| Shift+Alt+KeyP | P | Shift+Alt+P | | Shift+Alt+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | +| Ctrl+Shift+Alt+KeyP | Þ | Ctrl+Shift+Alt+P | | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyQ | q | Q | | Q | q | Q | [KeyQ] | | +| Ctrl+KeyQ | q | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | +| Shift+KeyQ | Q | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | +| Ctrl+Shift+KeyQ | Q | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | +| Alt+KeyQ | q | Alt+Q | | Alt+Q | alt+q | Alt+Q | alt+[KeyQ] | | +| Ctrl+Alt+KeyQ | @ | Ctrl+Alt+Q | | Ctrl+Alt+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | +| Shift+Alt+KeyQ | Q | Shift+Alt+Q | | Shift+Alt+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | +| Ctrl+Shift+Alt+KeyQ | Ω | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyR | r | R | | R | r | R | [KeyR] | | +| Ctrl+KeyR | r | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | +| Shift+KeyR | R | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | +| Ctrl+Shift+KeyR | R | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | +| Alt+KeyR | r | Alt+R | | Alt+R | alt+r | Alt+R | alt+[KeyR] | | +| Ctrl+Alt+KeyR | ¶ | Ctrl+Alt+R | | Ctrl+Alt+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | +| Shift+Alt+KeyR | R | Shift+Alt+R | | Shift+Alt+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | +| Ctrl+Shift+Alt+KeyR | ® | Ctrl+Shift+Alt+R | | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyS | s | S | | S | s | S | [KeyS] | | +| Ctrl+KeyS | s | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | +| Shift+KeyS | S | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | +| Ctrl+Shift+KeyS | S | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | +| Alt+KeyS | s | Alt+S | | Alt+S | alt+s | Alt+S | alt+[KeyS] | | +| Ctrl+Alt+KeyS | ß | Ctrl+Alt+S | | Ctrl+Alt+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | +| Shift+Alt+KeyS | S | Shift+Alt+S | | Shift+Alt+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | +| Ctrl+Shift+Alt+KeyS | § | Ctrl+Shift+Alt+S | | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyT | t | T | | T | t | T | [KeyT] | | +| Ctrl+KeyT | t | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | +| Shift+KeyT | T | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | +| Ctrl+Shift+KeyT | T | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | +| Alt+KeyT | t | Alt+T | | Alt+T | alt+t | Alt+T | alt+[KeyT] | | +| Ctrl+Alt+KeyT | ŧ | Ctrl+Alt+T | | Ctrl+Alt+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | +| Shift+Alt+KeyT | T | Shift+Alt+T | | Shift+Alt+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | +| Ctrl+Shift+Alt+KeyT | Ŧ | Ctrl+Shift+Alt+T | | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyU | u | U | | U | u | U | [KeyU] | | +| Ctrl+KeyU | u | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | +| Shift+KeyU | U | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | +| Ctrl+Shift+KeyU | U | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | +| Alt+KeyU | u | Alt+U | | Alt+U | alt+u | Alt+U | alt+[KeyU] | | +| Ctrl+Alt+KeyU | ↓ | Ctrl+Alt+U | | Ctrl+Alt+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | +| Shift+Alt+KeyU | U | Shift+Alt+U | | Shift+Alt+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | +| Ctrl+Shift+Alt+KeyU | ↑ | Ctrl+Shift+Alt+U | | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyV | v | V | | V | v | V | [KeyV] | | +| Ctrl+KeyV | v | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | +| Shift+KeyV | V | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | +| Ctrl+Shift+KeyV | V | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | +| Alt+KeyV | v | Alt+V | | Alt+V | alt+v | Alt+V | alt+[KeyV] | | +| Ctrl+Alt+KeyV | “ | Ctrl+Alt+V | | Ctrl+Alt+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | +| Shift+Alt+KeyV | V | Shift+Alt+V | | Shift+Alt+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | +| Ctrl+Shift+Alt+KeyV | ‘ | Ctrl+Shift+Alt+V | | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyW | w | W | | W | w | W | [KeyW] | | +| Ctrl+KeyW | w | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | +| Shift+KeyW | W | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | +| Ctrl+Shift+KeyW | W | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | +| Alt+KeyW | w | Alt+W | | Alt+W | alt+w | Alt+W | alt+[KeyW] | | +| Ctrl+Alt+KeyW | ł | Ctrl+Alt+W | | Ctrl+Alt+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | +| Shift+Alt+KeyW | W | Shift+Alt+W | | Shift+Alt+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | +| Ctrl+Shift+Alt+KeyW | Ł | Ctrl+Shift+Alt+W | | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyX | x | X | | X | x | X | [KeyX] | | +| Ctrl+KeyX | x | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | +| Shift+KeyX | X | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | +| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | +| Alt+KeyX | x | Alt+X | | Alt+X | alt+x | Alt+X | alt+[KeyX] | | +| Ctrl+Alt+KeyX | » | Ctrl+Alt+X | | Ctrl+Alt+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | +| Shift+Alt+KeyX | X | Shift+Alt+X | | Shift+Alt+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | +| Ctrl+Shift+Alt+KeyX | > | Ctrl+Shift+Alt+X | | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | +| | | Shift+. | 1 | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyY | z | Z | | Z | z | Z | [KeyY] | | +| Ctrl+KeyY | z | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyY] | | +| Shift+KeyY | Z | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyY] | | +| Ctrl+Shift+KeyY | Z | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyY] | | +| Alt+KeyY | z | Alt+Z | | Alt+Z | alt+z | Alt+Z | alt+[KeyY] | | +| Ctrl+Alt+KeyY | ← | Ctrl+Alt+Z | | Ctrl+Alt+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyY] | | +| Shift+Alt+KeyY | Z | Shift+Alt+Z | | Shift+Alt+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyY] | | +| Ctrl+Shift+Alt+KeyY | ¥ | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyY] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyZ | y | Y | | Y | y | Y | [KeyZ] | | +| Ctrl+KeyZ | y | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyZ] | | +| Shift+KeyZ | Y | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyZ] | | +| Ctrl+Shift+KeyZ | Y | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyZ] | | +| Alt+KeyZ | y | Alt+Y | | Alt+Y | alt+y | Alt+Y | alt+[KeyZ] | | +| Ctrl+Alt+KeyZ | « | Ctrl+Alt+Y | | Ctrl+Alt+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyZ] | | +| Shift+Alt+KeyZ | Y | Shift+Alt+Y | | Shift+Alt+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyZ] | | +| Ctrl+Shift+Alt+KeyZ | < | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyZ] | | +| | | Shift+, | 1 | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit1 | 1 | 1 | | 1 | 1 | 1 | [Digit1] | | +| Ctrl+Digit1 | 1 | Ctrl+1 | | Ctrl+1 | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | | +| Shift+Digit1 | + | Shift+1 | | Shift+1 | shift+1 | Shift+1 | shift+[Digit1] | | +| | | Shift+= | | | | | | | +| Ctrl+Shift+Digit1 | + | Ctrl+Shift+1 | | Ctrl+Shift+1 | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | | +| | | Ctrl+Shift+= | | | | | | | +| Alt+Digit1 | 1 | Alt+1 | | Alt+1 | alt+1 | Alt+1 | alt+[Digit1] | | +| Ctrl+Alt+Digit1 | | | Ctrl+Alt+1 | | Ctrl+Alt+1 | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | | +| | | Shift+\ | 1 | | | | | | +| Shift+Alt+Digit1 | + | Shift+Alt+1 | | Shift+Alt+1 | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | | +| | | Shift+Alt+= | | | | | | | +| Ctrl+Shift+Alt+Digit1 | ¡ | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | | +| | | Ctrl+Shift+Alt+= | | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit2 | 2 | 2 | | 2 | 2 | 2 | [Digit2] | | +| Ctrl+Digit2 | 2 | Ctrl+2 | | Ctrl+2 | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | | +| Shift+Digit2 | " | Shift+2 | | Shift+2 | shift+2 | Shift+2 | shift+[Digit2] | | +| | | Shift+' | | | | | | | +| Ctrl+Shift+Digit2 | " | Ctrl+Shift+2 | | Ctrl+Shift+2 | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | | +| | | Ctrl+Shift+' | | | | | | | +| Alt+Digit2 | 2 | Alt+2 | | Alt+2 | alt+2 | Alt+2 | alt+[Digit2] | | +| Ctrl+Alt+Digit2 | @ | Ctrl+Alt+2 | | Ctrl+Alt+2 | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | | +| Shift+Alt+Digit2 | " | Shift+Alt+2 | | Shift+Alt+2 | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | | +| | | Shift+Alt+' | | | | | | | +| Ctrl+Shift+Alt+Digit2 | ⅛ | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | | +| | | Ctrl+Shift+Alt+' | | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit3 | 3 | 3 | | 3 | 3 | 3 | [Digit3] | | +| Ctrl+Digit3 | 3 | Ctrl+3 | | Ctrl+3 | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | | +| Shift+Digit3 | * | Shift+3 | | Shift+3 | shift+3 | Shift+3 | shift+[Digit3] | | +| Ctrl+Shift+Digit3 | * | Ctrl+Shift+3 | | Ctrl+Shift+3 | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | | +| Alt+Digit3 | 3 | Alt+3 | | Alt+3 | alt+3 | Alt+3 | alt+[Digit3] | | +| Ctrl+Alt+Digit3 | # | Ctrl+Alt+3 | | Ctrl+Alt+3 | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | | +| Shift+Alt+Digit3 | * | Shift+Alt+3 | | Shift+Alt+3 | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | | +| Ctrl+Shift+Alt+Digit3 | £ | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit4 | 4 | 4 | | 4 | 4 | 4 | [Digit4] | | +| Ctrl+Digit4 | 4 | Ctrl+4 | | Ctrl+4 | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | | +| Shift+Digit4 | ç | Shift+4 | | Shift+4 | shift+4 | Shift+4 | shift+[Digit4] | | +| Ctrl+Shift+Digit4 | ç | Ctrl+Shift+4 | | Ctrl+Shift+4 | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | | +| Alt+Digit4 | 4 | Alt+4 | | Alt+4 | alt+4 | Alt+4 | alt+[Digit4] | | +| Ctrl+Alt+Digit4 | ¼ | Ctrl+Alt+4 | | Ctrl+Alt+4 | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | | +| Shift+Alt+Digit4 | ç | Shift+Alt+4 | | Shift+Alt+4 | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | | +| Ctrl+Shift+Alt+Digit4 | $ | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit5 | 5 | 5 | | 5 | 5 | 5 | [Digit5] | | +| Ctrl+Digit5 | 5 | Ctrl+5 | | Ctrl+5 | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | | +| Shift+Digit5 | % | Shift+5 | | Shift+5 | shift+5 | Shift+5 | shift+[Digit5] | | +| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+5 | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | | +| Alt+Digit5 | 5 | Alt+5 | | Alt+5 | alt+5 | Alt+5 | alt+[Digit5] | | +| Ctrl+Alt+Digit5 | ½ | Ctrl+Alt+5 | | Ctrl+Alt+5 | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | | +| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Alt+5 | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | | +| Ctrl+Shift+Alt+Digit5 | ⅜ | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit6 | 6 | 6 | | 6 | 6 | 6 | [Digit6] | | +| Ctrl+Digit6 | 6 | Ctrl+6 | | Ctrl+6 | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | | +| Shift+Digit6 | & | Shift+6 | | Shift+6 | shift+6 | Shift+6 | shift+[Digit6] | | +| Ctrl+Shift+Digit6 | & | Ctrl+Shift+6 | | Ctrl+Shift+6 | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | | +| Alt+Digit6 | 6 | Alt+6 | | Alt+6 | alt+6 | Alt+6 | alt+[Digit6] | | +| Ctrl+Alt+Digit6 | ¬ | Ctrl+Alt+6 | | Ctrl+Alt+6 | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | | +| Shift+Alt+Digit6 | & | Shift+Alt+6 | | Shift+Alt+6 | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | | +| Ctrl+Shift+Alt+Digit6 | ⅝ | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit7 | 7 | 7 | | 7 | 7 | 7 | [Digit7] | | +| Ctrl+Digit7 | 7 | Ctrl+7 | | Ctrl+7 | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | | +| Shift+Digit7 | / | Shift+7 | | Shift+7 | shift+7 | Shift+7 | shift+[Digit7] | | +| | | / | | | | | | | +| Ctrl+Shift+Digit7 | / | Ctrl+Shift+7 | | Ctrl+Shift+7 | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | | +| | | Ctrl+/ | | | | | | | +| Alt+Digit7 | 7 | Alt+7 | | Alt+7 | alt+7 | Alt+7 | alt+[Digit7] | | +| Ctrl+Alt+Digit7 | | | Ctrl+Alt+7 | | Ctrl+Alt+7 | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | | +| | | Shift+\ | 2 | | | | | | +| Shift+Alt+Digit7 | / | Shift+Alt+7 | | Shift+Alt+7 | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | | +| | | Alt+/ | | | | | | | +| Ctrl+Shift+Alt+Digit7 | ⅞ | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | | +| | | Ctrl+Alt+/ | | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit8 | 8 | 8 | | 8 | 8 | 8 | [Digit8] | | +| Ctrl+Digit8 | 8 | Ctrl+8 | | Ctrl+8 | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | | +| Shift+Digit8 | ( | Shift+8 | | Shift+8 | shift+8 | Shift+8 | shift+[Digit8] | | +| Ctrl+Shift+Digit8 | ( | Ctrl+Shift+8 | | Ctrl+Shift+8 | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | | +| Alt+Digit8 | 8 | Alt+8 | | Alt+8 | alt+8 | Alt+8 | alt+[Digit8] | | +| Ctrl+Alt+Digit8 | ¢ | Ctrl+Alt+8 | | Ctrl+Alt+8 | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | | +| Shift+Alt+Digit8 | ( | Shift+Alt+8 | | Shift+Alt+8 | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | | +| Ctrl+Shift+Alt+Digit8 | ™ | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit9 | 9 | 9 | | 9 | 9 | 9 | [Digit9] | | +| Ctrl+Digit9 | 9 | Ctrl+9 | | Ctrl+9 | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | | +| Shift+Digit9 | ) | Shift+9 | | Shift+9 | shift+9 | Shift+9 | shift+[Digit9] | | +| Ctrl+Shift+Digit9 | ) | Ctrl+Shift+9 | | Ctrl+Shift+9 | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | | +| Alt+Digit9 | 9 | Alt+9 | | Alt+9 | alt+9 | Alt+9 | alt+[Digit9] | | +| Ctrl+Alt+Digit9 | ] | Ctrl+Alt+9 | | Ctrl+Alt+9 | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | | +| | | ] | 1 | | | | | | +| Shift+Alt+Digit9 | ) | Shift+Alt+9 | | Shift+Alt+9 | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | | +| Ctrl+Shift+Alt+Digit9 | ± | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit0 | 0 | 0 | | 0 | 0 | 0 | [Digit0] | | +| Ctrl+Digit0 | 0 | Ctrl+0 | | Ctrl+0 | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | | +| Shift+Digit0 | = | Shift+0 | | Shift+0 | shift+0 | Shift+0 | shift+[Digit0] | | +| | | = | | | | | | | +| Ctrl+Shift+Digit0 | = | Ctrl+Shift+0 | | Ctrl+Shift+0 | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | | +| | | Ctrl+= | | | | | | | +| Alt+Digit0 | 0 | Alt+0 | | Alt+0 | alt+0 | Alt+0 | alt+[Digit0] | | +| Ctrl+Alt+Digit0 | } | Ctrl+Alt+0 | | Ctrl+Alt+0 | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | | +| | | Shift+] | 1 | | | | | | +| Shift+Alt+Digit0 | = | Shift+Alt+0 | | Shift+Alt+0 | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | | +| | | Alt+= | | | | | | | +| Ctrl+Shift+Alt+Digit0 | ° | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | | +| | | Ctrl+Alt+= | | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Minus | ' | ' | | ' | [Minus] | null | [Minus] | NO | +| Ctrl+Minus | ' | Ctrl+' | | Ctrl+' | ctrl+[Minus] | null | ctrl+[Minus] | NO | +| Shift+Minus | ? | Shift+/ | | Shift+' | shift+[Minus] | null | shift+[Minus] | NO | +| Ctrl+Shift+Minus | ? | Ctrl+Shift+/ | | Ctrl+Shift+' | ctrl+shift+[Minus] | null | ctrl+shift+[Minus] | NO | +| Alt+Minus | ' | Alt+' | | Alt+' | alt+[Minus] | null | alt+[Minus] | NO | +| Ctrl+Alt+Minus | ´ | Ctrl+Alt+' | | Ctrl+Alt+' | ctrl+alt+[Minus] | null | ctrl+alt+[Minus] | NO | +| Shift+Alt+Minus | ? | Shift+Alt+/ | | Shift+Alt+' | shift+alt+[Minus] | null | shift+alt+[Minus] | NO | +| Ctrl+Shift+Alt+Minus | ¿ | Ctrl+Shift+Alt+/ | | Ctrl+Shift+Alt+' | ctrl+shift+alt+[Minus] | null | ctrl+shift+alt+[Minus] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Equal | ^ | | | ^ | [Equal] | null | [Equal] | NO | +| Ctrl+Equal | ^ | | | Ctrl+^ | ctrl+[Equal] | null | ctrl+[Equal] | NO | +| Shift+Equal | ` | ` | | Shift+^ | shift+[Equal] | null | shift+[Equal] | NO | +| Ctrl+Shift+Equal | ` | Ctrl+` | | Ctrl+Shift+^ | ctrl+shift+[Equal] | null | ctrl+shift+[Equal] | NO | +| Alt+Equal | ^ | | | Alt+^ | alt+[Equal] | null | alt+[Equal] | NO | +| Ctrl+Alt+Equal | ˜ | | | Ctrl+Alt+^ | ctrl+alt+[Equal] | null | ctrl+alt+[Equal] | NO | +| Shift+Alt+Equal | ` | Alt+` | | Shift+Alt+^ | shift+alt+[Equal] | null | shift+alt+[Equal] | NO | +| Ctrl+Shift+Alt+Equal | U+328 | Ctrl+Alt+` | | Ctrl+Shift+Alt+^ | ctrl+shift+alt+[Equal] | null | ctrl+shift+alt+[Equal] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketLeft | ü | | | ü | [BracketLeft] | null | [BracketLeft] | NO | +| Ctrl+BracketLeft | ü | | | Ctrl+ü | ctrl+[BracketLeft] | null | ctrl+[BracketLeft] | NO | +| Shift+BracketLeft | è | | | Shift+ü | shift+[BracketLeft] | null | shift+[BracketLeft] | NO | +| Ctrl+Shift+BracketLeft | è | | | Ctrl+Shift+ü | ctrl+shift+[BracketLeft] | null | ctrl+shift+[BracketLeft] | NO | +| Alt+BracketLeft | ü | | | Alt+ü | alt+[BracketLeft] | null | alt+[BracketLeft] | NO | +| Ctrl+Alt+BracketLeft | [ | [ | | Ctrl+Alt+ü | ctrl+alt+[BracketLeft] | null | ctrl+alt+[BracketLeft] | NO | +| Shift+Alt+BracketLeft | è | | | Shift+Alt+ü | shift+alt+[BracketLeft] | null | shift+alt+[BracketLeft] | NO | +| Ctrl+Shift+Alt+BracketLeft | ˚ | | | Ctrl+Shift+Alt+ü | ctrl+shift+alt+[BracketLeft] | null | ctrl+shift+alt+[BracketLeft] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketRight | ¨ | | | ¨ | [BracketRight] | null | [BracketRight] | NO | +| Ctrl+BracketRight | ¨ | | | Ctrl+¨ | ctrl+[BracketRight] | null | ctrl+[BracketRight] | NO | +| Shift+BracketRight | ! | | | Shift+¨ | shift+[BracketRight] | null | shift+[BracketRight] | NO | +| Ctrl+Shift+BracketRight | ! | | | Ctrl+Shift+¨ | ctrl+shift+[BracketRight] | null | ctrl+shift+[BracketRight] | NO | +| Alt+BracketRight | ¨ | | | Alt+¨ | alt+[BracketRight] | null | alt+[BracketRight] | NO | +| Ctrl+Alt+BracketRight | ] | ] | 2 | Ctrl+Alt+¨ | ctrl+alt+[BracketRight] | null | ctrl+alt+[BracketRight] | NO | +| Shift+Alt+BracketRight | ! | | | Shift+Alt+¨ | shift+alt+[BracketRight] | null | shift+alt+[BracketRight] | NO | +| Ctrl+Shift+Alt+BracketRight | ¯ | | | Ctrl+Shift+Alt+¨ | ctrl+shift+alt+[BracketRight] | null | ctrl+shift+alt+[BracketRight] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backslash | $ | | | $ | [Backslash] | null | [Backslash] | NO | +| Ctrl+Backslash | $ | | | Ctrl+$ | ctrl+[Backslash] | null | ctrl+[Backslash] | NO | +| Shift+Backslash | £ | | | Shift+$ | shift+[Backslash] | null | shift+[Backslash] | NO | +| Ctrl+Shift+Backslash | £ | | | Ctrl+Shift+$ | ctrl+shift+[Backslash] | null | ctrl+shift+[Backslash] | NO | +| Alt+Backslash | $ | | | Alt+$ | alt+[Backslash] | null | alt+[Backslash] | NO | +| Ctrl+Alt+Backslash | } | Shift+] | 2 | Ctrl+Alt+$ | ctrl+alt+[Backslash] | null | ctrl+alt+[Backslash] | NO | +| Shift+Alt+Backslash | £ | | | Shift+Alt+$ | shift+alt+[Backslash] | null | shift+alt+[Backslash] | NO | +| Ctrl+Shift+Alt+Backslash | ˘ | | | Ctrl+Shift+Alt+$ | ctrl+shift+alt+[Backslash] | null | ctrl+shift+alt+[Backslash] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlHash | --- | | | null | null | null | null | | +| Ctrl+IntlHash | --- | | | null | null | null | null | | +| Shift+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | +| Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | +| Shift+Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Semicolon | ö | | | ö | [Semicolon] | null | [Semicolon] | NO | +| Ctrl+Semicolon | ö | | | Ctrl+ö | ctrl+[Semicolon] | null | ctrl+[Semicolon] | NO | +| Shift+Semicolon | é | | | Shift+ö | shift+[Semicolon] | null | shift+[Semicolon] | NO | +| Ctrl+Shift+Semicolon | é | | | Ctrl+Shift+ö | ctrl+shift+[Semicolon] | null | ctrl+shift+[Semicolon] | NO | +| Alt+Semicolon | ö | | | Alt+ö | alt+[Semicolon] | null | alt+[Semicolon] | NO | +| Ctrl+Alt+Semicolon | ´ | | | Ctrl+Alt+ö | ctrl+alt+[Semicolon] | null | ctrl+alt+[Semicolon] | NO | +| Shift+Alt+Semicolon | é | | | Shift+Alt+ö | shift+alt+[Semicolon] | null | shift+alt+[Semicolon] | NO | +| Ctrl+Shift+Alt+Semicolon | ˝ | | | Ctrl+Shift+Alt+ö | ctrl+shift+alt+[Semicolon] | null | ctrl+shift+alt+[Semicolon] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Quote | ä | | | ä | [Quote] | null | [Quote] | NO | +| Ctrl+Quote | ä | | | Ctrl+ä | ctrl+[Quote] | null | ctrl+[Quote] | NO | +| Shift+Quote | à | | | Shift+ä | shift+[Quote] | null | shift+[Quote] | NO | +| Ctrl+Shift+Quote | à | | | Ctrl+Shift+ä | ctrl+shift+[Quote] | null | ctrl+shift+[Quote] | NO | +| Alt+Quote | ä | | | Alt+ä | alt+[Quote] | null | alt+[Quote] | NO | +| Ctrl+Alt+Quote | { | Shift+[ | | Ctrl+Alt+ä | ctrl+alt+[Quote] | null | ctrl+alt+[Quote] | NO | +| Shift+Alt+Quote | à | | | Shift+Alt+ä | shift+alt+[Quote] | null | shift+alt+[Quote] | NO | +| Ctrl+Shift+Alt+Quote | U+30c | | | Ctrl+Shift+Alt+ä | ctrl+shift+alt+[Quote] | null | ctrl+shift+alt+[Quote] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backquote | § | | | § | [Backquote] | null | [Backquote] | NO | +| Ctrl+Backquote | § | | | Ctrl+§ | ctrl+[Backquote] | null | ctrl+[Backquote] | NO | +| Shift+Backquote | ° | | | Shift+§ | shift+[Backquote] | null | shift+[Backquote] | NO | +| Ctrl+Shift+Backquote | ° | | | Ctrl+Shift+§ | ctrl+shift+[Backquote] | null | ctrl+shift+[Backquote] | NO | +| Alt+Backquote | § | | | Alt+§ | alt+[Backquote] | null | alt+[Backquote] | NO | +| Ctrl+Alt+Backquote | ¬ | | | Ctrl+Alt+§ | ctrl+alt+[Backquote] | null | ctrl+alt+[Backquote] | NO | +| Shift+Alt+Backquote | ° | | | Shift+Alt+§ | shift+alt+[Backquote] | null | shift+alt+[Backquote] | NO | +| Ctrl+Shift+Alt+Backquote | ¬ | | | Ctrl+Shift+Alt+§ | ctrl+shift+alt+[Backquote] | null | ctrl+shift+alt+[Backquote] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Comma | , | , | | , | [Comma] | null | [Comma] | NO | +| Ctrl+Comma | , | Ctrl+, | | Ctrl+, | ctrl+[Comma] | null | ctrl+[Comma] | NO | +| Shift+Comma | ; | ; | | Shift+, | shift+[Comma] | null | shift+[Comma] | NO | +| Ctrl+Shift+Comma | ; | Ctrl+; | | Ctrl+Shift+, | ctrl+shift+[Comma] | null | ctrl+shift+[Comma] | NO | +| Alt+Comma | , | Alt+, | | Alt+, | alt+[Comma] | null | alt+[Comma] | NO | +| Ctrl+Alt+Comma | ─ | Ctrl+Alt+, | | Ctrl+Alt+, | ctrl+alt+[Comma] | null | ctrl+alt+[Comma] | NO | +| Shift+Alt+Comma | ; | Alt+; | | Shift+Alt+, | shift+alt+[Comma] | null | shift+alt+[Comma] | NO | +| Ctrl+Shift+Alt+Comma | × | Ctrl+Alt+; | | Ctrl+Shift+Alt+, | ctrl+shift+alt+[Comma] | null | ctrl+shift+alt+[Comma] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Period | . | . | | . | [Period] | null | [Period] | NO | +| Ctrl+Period | . | Ctrl+. | | Ctrl+. | ctrl+[Period] | null | ctrl+[Period] | NO | +| Shift+Period | : | Shift+; | | Shift+. | shift+[Period] | null | shift+[Period] | NO | +| Ctrl+Shift+Period | : | Ctrl+Shift+; | | Ctrl+Shift+. | ctrl+shift+[Period] | null | ctrl+shift+[Period] | NO | +| Alt+Period | . | Alt+. | | Alt+. | alt+[Period] | null | alt+[Period] | NO | +| Ctrl+Alt+Period | · | Ctrl+Alt+. | | Ctrl+Alt+. | ctrl+alt+[Period] | null | ctrl+alt+[Period] | NO | +| Shift+Alt+Period | : | Shift+Alt+; | | Shift+Alt+. | shift+alt+[Period] | null | shift+alt+[Period] | NO | +| Ctrl+Shift+Alt+Period | ÷ | Ctrl+Shift+Alt+; | | Ctrl+Shift+Alt+. | ctrl+shift+alt+[Period] | null | ctrl+shift+alt+[Period] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Slash | - | - | | - | - | null | [Slash] | | +| Ctrl+Slash | - | Ctrl+- | | Ctrl+- | ctrl+- | null | ctrl+[Slash] | | +| Shift+Slash | _ | Shift+- | | Shift+- | shift+- | null | shift+[Slash] | | +| Ctrl+Shift+Slash | _ | Ctrl+Shift+- | | Ctrl+Shift+- | ctrl+shift+- | null | ctrl+shift+[Slash] | | +| Alt+Slash | - | Alt+- | | Alt+- | alt+- | null | alt+[Slash] | | +| Ctrl+Alt+Slash | U+323 | Ctrl+Alt+- | | Ctrl+Alt+- | ctrl+alt+- | null | ctrl+alt+[Slash] | | +| Shift+Alt+Slash | _ | Shift+Alt+- | | Shift+Alt+- | shift+alt+- | null | shift+alt+[Slash] | | +| Ctrl+Shift+Alt+Slash | ˙ | Ctrl+Shift+Alt+- | | Ctrl+Shift+Alt+- | ctrl+shift+alt+- | null | ctrl+shift+alt+[Slash] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | +| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | +| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | +| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | +| Alt+ArrowUp | --- | Alt+UpArrow | | Alt+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | +| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Alt+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | +| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Alt+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | +| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | +| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | +| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | +| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | +| Alt+Numpad0 | --- | Alt+NumPad0 | | Alt+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | +| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | +| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Alt+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | +| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlBackslash | < | Shift+, | 2 | < | [IntlBackslash] | null | [IntlBackslash] | NO | +| Ctrl+IntlBackslash | < | Ctrl+Shift+, | | Ctrl+< | ctrl+[IntlBackslash] | null | ctrl+[IntlBackslash] | NO | +| Shift+IntlBackslash | > | Shift+. | 2 | Shift+< | shift+[IntlBackslash] | null | shift+[IntlBackslash] | NO | +| Ctrl+Shift+IntlBackslash | > | Ctrl+Shift+. | | Ctrl+Shift+< | ctrl+shift+[IntlBackslash] | null | ctrl+shift+[IntlBackslash] | NO | +| Alt+IntlBackslash | < | Shift+Alt+, | | Alt+< | alt+[IntlBackslash] | null | alt+[IntlBackslash] | NO | +| Ctrl+Alt+IntlBackslash | \ | \ | | Ctrl+Alt+< | ctrl+alt+[IntlBackslash] | null | ctrl+alt+[IntlBackslash] | NO | +| Shift+Alt+IntlBackslash | > | Shift+Alt+. | | Shift+Alt+< | shift+alt+[IntlBackslash] | null | shift+alt+[IntlBackslash] | NO | +| Ctrl+Shift+Alt+IntlBackslash | ¦ | Ctrl+Shift+Alt+. | | Ctrl+Shift+Alt+< | ctrl+shift+alt+[IntlBackslash] | null | ctrl+shift+alt+[IntlBackslash] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | +| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | +| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | +| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | +| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | +| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | +| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | +| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | +| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | +| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | +| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | +| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | +| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | +| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | +| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/node/linux_en_uk.js b/src/vs/workbench/services/keybinding/test/node/linux_en_uk.js new file mode 100644 index 00000000000..379e7355c8e --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/linux_en_uk.js @@ -0,0 +1,1046 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +define({ + Sleep: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + WakeUp: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + KeyA: { + value: 'a', + withShift: 'A', + withAltGr: 'æ', + withShiftAltGr: 'Æ' + }, + KeyB: { + value: 'b', + withShift: 'B', + withAltGr: '”', + withShiftAltGr: '’' + }, + KeyC: { + value: 'c', + withShift: 'C', + withAltGr: '¢', + withShiftAltGr: '©' + }, + KeyD: { + value: 'd', + withShift: 'D', + withAltGr: 'ð', + withShiftAltGr: 'Ð' + }, + KeyE: { + value: 'e', + withShift: 'E', + withAltGr: 'e', + withShiftAltGr: 'E' + }, + KeyF: { + value: 'f', + withShift: 'F', + withAltGr: 'đ', + withShiftAltGr: 'ª' + }, + KeyG: { + value: 'g', + withShift: 'G', + withAltGr: 'ŋ', + withShiftAltGr: 'Ŋ' + }, + KeyH: { + value: 'h', + withShift: 'H', + withAltGr: 'ħ', + withShiftAltGr: 'Ħ' + }, + KeyI: { + value: 'i', + withShift: 'I', + withAltGr: '→', + withShiftAltGr: 'ı' + }, + KeyJ: { + value: 'j', + withShift: 'J', + withAltGr: '̉', + withShiftAltGr: '̛' + }, + KeyK: { + value: 'k', + withShift: 'K', + withAltGr: 'ĸ', + withShiftAltGr: '&' + }, + KeyL: { + value: 'l', + withShift: 'L', + withAltGr: 'ł', + withShiftAltGr: 'Ł' + }, + KeyM: { + value: 'm', + withShift: 'M', + withAltGr: 'µ', + withShiftAltGr: 'º' + }, + KeyN: { + value: 'n', + withShift: 'N', + withAltGr: 'n', + withShiftAltGr: 'N' + }, + KeyO: { + value: 'o', + withShift: 'O', + withAltGr: 'ø', + withShiftAltGr: 'Ø' + }, + KeyP: { + value: 'p', + withShift: 'P', + withAltGr: 'þ', + withShiftAltGr: 'Þ' + }, + KeyQ: { + value: 'q', + withShift: 'Q', + withAltGr: '@', + withShiftAltGr: 'Ω' + }, + KeyR: { + value: 'r', + withShift: 'R', + withAltGr: '¶', + withShiftAltGr: '®' + }, + KeyS: { + value: 's', + withShift: 'S', + withAltGr: 'ß', + withShiftAltGr: '§' + }, + KeyT: { + value: 't', + withShift: 'T', + withAltGr: 'ŧ', + withShiftAltGr: 'Ŧ' + }, + KeyU: { + value: 'u', + withShift: 'U', + withAltGr: '↓', + withShiftAltGr: '↑' + }, + KeyV: { + value: 'v', + withShift: 'V', + withAltGr: '“', + withShiftAltGr: '‘' + }, + KeyW: { + value: 'w', + withShift: 'W', + withAltGr: 'ł', + withShiftAltGr: 'Ł' + }, + KeyX: { + value: 'x', + withShift: 'X', + withAltGr: '»', + withShiftAltGr: '>' + }, + KeyY: { + value: 'y', + withShift: 'Y', + withAltGr: '←', + withShiftAltGr: '¥' + }, + KeyZ: { + value: 'z', + withShift: 'Z', + withAltGr: '«', + withShiftAltGr: '<' + }, + Digit1: { + value: '1', + withShift: '!', + withAltGr: '¹', + withShiftAltGr: '¡' + }, + Digit2: { + value: '2', + withShift: '"', + withAltGr: '²', + withShiftAltGr: '⅛' + }, + Digit3: { + value: '3', + withShift: '£', + withAltGr: '³', + withShiftAltGr: '£' + }, + Digit4: { + value: '4', + withShift: '$', + withAltGr: '€', + withShiftAltGr: '¼' + }, + Digit5: { + value: '5', + withShift: '%', + withAltGr: '½', + withShiftAltGr: '⅜' + }, + Digit6: { + value: '6', + withShift: '^', + withAltGr: '¾', + withShiftAltGr: '⅝' + }, + Digit7: { + value: '7', + withShift: '&', + withAltGr: '{', + withShiftAltGr: '⅞' + }, + Digit8: { + value: '8', + withShift: '*', + withAltGr: '[', + withShiftAltGr: '™' + }, + Digit9: { + value: '9', + withShift: '(', + withAltGr: ']', + withShiftAltGr: '±' + }, + Digit0: { + value: '0', + withShift: ')', + withAltGr: '}', + withShiftAltGr: '°' + }, + Enter: { + value: '\r', + withShift: '\r', + withAltGr: '\r', + withShiftAltGr: '\r' + }, + Escape: { + value: '\u001b', + withShift: '\u001b', + withAltGr: '\u001b', + withShiftAltGr: '\u001b' + }, + Backspace: { + value: '\b', + withShift: '\b', + withAltGr: '\b', + withShiftAltGr: '\b' + }, + Tab: { + value: '\t', + withShift: '', + withAltGr: '\t', + withShiftAltGr: '' + }, + Space: { + value: ' ', + withShift: ' ', + withAltGr: ' ', + withShiftAltGr: ' ' + }, + Minus: { + value: '-', + withShift: '_', + withAltGr: '\\', + withShiftAltGr: '¿' + }, + Equal: { + value: '=', + withShift: '+', + withAltGr: '̧', + withShiftAltGr: '̨' + }, + BracketLeft: { + value: '[', + withShift: '{', + withAltGr: '̈', + withShiftAltGr: '̊' + }, + BracketRight: { + value: ']', + withShift: '}', + withAltGr: '̃', + withShiftAltGr: '̄' + }, + Backslash: { + value: '#', + withShift: '~', + withAltGr: '̀', + withShiftAltGr: '̆' + }, + Semicolon: { + value: ';', + withShift: ':', + withAltGr: '́', + withShiftAltGr: '̋' + }, + Quote: { + value: '\'', + withShift: '@', + withAltGr: '̂', + withShiftAltGr: '̌' + }, + Backquote: { + value: '`', + withShift: '¬', + withAltGr: '|', + withShiftAltGr: '|' + }, + Comma: { + value: ',', + withShift: '<', + withAltGr: '─', + withShiftAltGr: '×' + }, + Period: { + value: '.', + withShift: '>', + withAltGr: '·', + withShiftAltGr: '÷' + }, + Slash: { + value: '/', + withShift: '?', + withAltGr: '̣', + withShiftAltGr: '̇' + }, + CapsLock: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F1: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F2: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F3: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F4: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F5: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F6: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F7: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F8: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F9: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F10: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F11: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F12: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PrintScreen: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ScrollLock: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Pause: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Insert: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Home: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PageUp: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Delete: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + End: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PageDown: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowRight: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowLeft: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowDown: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowUp: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumLock: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadDivide: { + value: '/', + withShift: '/', + withAltGr: '/', + withShiftAltGr: '/' + }, + NumpadMultiply: { + value: '*', + withShift: '*', + withAltGr: '*', + withShiftAltGr: '*' + }, + NumpadSubtract: { + value: '-', + withShift: '-', + withAltGr: '-', + withShiftAltGr: '-' + }, + NumpadAdd: { + value: '+', + withShift: '+', + withAltGr: '+', + withShiftAltGr: '+' + }, + NumpadEnter: { + value: '\r', + withShift: '\r', + withAltGr: '\r', + withShiftAltGr: '\r' + }, + Numpad1: { + value: '', + withShift: '1', + withAltGr: '', + withShiftAltGr: '1' + }, + Numpad2: { + value: '', + withShift: '2', + withAltGr: '', + withShiftAltGr: '2' + }, + Numpad3: { + value: '', + withShift: '3', + withAltGr: '', + withShiftAltGr: '3' + }, + Numpad4: { + value: '', + withShift: '4', + withAltGr: '', + withShiftAltGr: '4' + }, + Numpad5: { + value: '', + withShift: '5', + withAltGr: '', + withShiftAltGr: '5' + }, + Numpad6: { + value: '', + withShift: '6', + withAltGr: '', + withShiftAltGr: '6' + }, + Numpad7: { + value: '', + withShift: '7', + withAltGr: '', + withShiftAltGr: '7' + }, + Numpad8: { + value: '', + withShift: '8', + withAltGr: '', + withShiftAltGr: '8' + }, + Numpad9: { + value: '', + withShift: '9', + withAltGr: '', + withShiftAltGr: '9' + }, + Numpad0: { + value: '', + withShift: '0', + withAltGr: '', + withShiftAltGr: '0' + }, + NumpadDecimal: { + value: '', + withShift: '.', + withAltGr: '', + withShiftAltGr: '.' + }, + IntlBackslash: { + value: '\\', + withShift: '|', + withAltGr: '|', + withShiftAltGr: '¦' + }, + ContextMenu: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Power: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadEqual: { + value: '=', + withShift: '=', + withAltGr: '=', + withShiftAltGr: '=' + }, + F13: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F14: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F15: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F16: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F17: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F18: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F19: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F20: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F21: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F22: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F23: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F24: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Open: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Help: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Select: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Again: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Undo: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Cut: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Copy: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Paste: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Find: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeMute: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeUp: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeDown: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadComma: { + value: '.', + withShift: '.', + withAltGr: '.', + withShiftAltGr: '.' + }, + IntlRo: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + KanaMode: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + IntlYen: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Convert: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NonConvert: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang1: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang2: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang3: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang4: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang5: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadParenLeft: { + value: '(', + withShift: '(', + withAltGr: '(', + withShiftAltGr: '(' + }, + NumpadParenRight: { + value: ')', + withShift: ')', + withAltGr: ')', + withShiftAltGr: ')' + }, + ControlLeft: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ShiftLeft: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AltLeft: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MetaLeft: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ControlRight: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ShiftRight: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AltRight: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MetaRight: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrightnessUp: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrightnessDown: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaPlay: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaRecord: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaFastForward: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaRewind: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaTrackNext: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaTrackPrevious: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaStop: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Eject: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaPlayPause: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaSelect: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchMail: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchApp2: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchApp1: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + SelectTask: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchScreenSaver: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserSearch: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserHome: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserBack: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserForward: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserStop: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserRefresh: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserFavorites: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MailReply: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MailForward: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MailSend: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + } +}); diff --git a/src/vs/workbench/services/keybinding/test/node/linux_en_uk.txt b/src/vs/workbench/services/keybinding/test/node/linux_en_uk.txt new file mode 100644 index 00000000000..9d1ab7184c4 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/linux_en_uk.txt @@ -0,0 +1,517 @@ +isUSStandard: false +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyA | a | A | | A | a | A | [KeyA] | | +| Ctrl+KeyA | a | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | +| Shift+KeyA | A | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | +| Ctrl+Shift+KeyA | A | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | +| Alt+KeyA | a | Alt+A | | Alt+A | alt+a | Alt+A | alt+[KeyA] | | +| Ctrl+Alt+KeyA | æ | Ctrl+Alt+A | | Ctrl+Alt+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | +| Shift+Alt+KeyA | A | Shift+Alt+A | | Shift+Alt+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | +| Ctrl+Shift+Alt+KeyA | Æ | Ctrl+Shift+Alt+A | | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyB | b | B | | B | b | B | [KeyB] | | +| Ctrl+KeyB | b | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | +| Shift+KeyB | B | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | +| Ctrl+Shift+KeyB | B | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | +| Alt+KeyB | b | Alt+B | | Alt+B | alt+b | Alt+B | alt+[KeyB] | | +| Ctrl+Alt+KeyB | ” | Ctrl+Alt+B | | Ctrl+Alt+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | +| Shift+Alt+KeyB | B | Shift+Alt+B | | Shift+Alt+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | +| Ctrl+Shift+Alt+KeyB | ’ | Ctrl+Shift+Alt+B | | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyC | c | C | | C | c | C | [KeyC] | | +| Ctrl+KeyC | c | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | +| Shift+KeyC | C | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | +| Ctrl+Shift+KeyC | C | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | +| Alt+KeyC | c | Alt+C | | Alt+C | alt+c | Alt+C | alt+[KeyC] | | +| Ctrl+Alt+KeyC | ¢ | Ctrl+Alt+C | | Ctrl+Alt+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | +| Shift+Alt+KeyC | C | Shift+Alt+C | | Shift+Alt+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | +| Ctrl+Shift+Alt+KeyC | © | Ctrl+Shift+Alt+C | | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyD | d | D | | D | d | D | [KeyD] | | +| Ctrl+KeyD | d | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | +| Shift+KeyD | D | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | +| Ctrl+Shift+KeyD | D | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | +| Alt+KeyD | d | Alt+D | | Alt+D | alt+d | Alt+D | alt+[KeyD] | | +| Ctrl+Alt+KeyD | ð | Ctrl+Alt+D | | Ctrl+Alt+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | +| Shift+Alt+KeyD | D | Shift+Alt+D | | Shift+Alt+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | +| Ctrl+Shift+Alt+KeyD | Ð | Ctrl+Shift+Alt+D | | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyE | e | E | | E | e | E | [KeyE] | | +| Ctrl+KeyE | e | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | +| Shift+KeyE | E | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | +| Ctrl+Shift+KeyE | E | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | +| Alt+KeyE | e | Alt+E | | Alt+E | alt+e | Alt+E | alt+[KeyE] | | +| Ctrl+Alt+KeyE | e | Ctrl+Alt+E | | Ctrl+Alt+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | +| Shift+Alt+KeyE | E | Shift+Alt+E | | Shift+Alt+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | +| Ctrl+Shift+Alt+KeyE | E | Ctrl+Shift+Alt+E | | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyF | f | F | | F | f | F | [KeyF] | | +| Ctrl+KeyF | f | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | +| Shift+KeyF | F | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | +| Ctrl+Shift+KeyF | F | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | +| Alt+KeyF | f | Alt+F | | Alt+F | alt+f | Alt+F | alt+[KeyF] | | +| Ctrl+Alt+KeyF | đ | Ctrl+Alt+F | | Ctrl+Alt+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | +| Shift+Alt+KeyF | F | Shift+Alt+F | | Shift+Alt+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | +| Ctrl+Shift+Alt+KeyF | ª | Ctrl+Shift+Alt+F | | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyG | g | G | | G | g | G | [KeyG] | | +| Ctrl+KeyG | g | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | +| Shift+KeyG | G | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | +| Ctrl+Shift+KeyG | G | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | +| Alt+KeyG | g | Alt+G | | Alt+G | alt+g | Alt+G | alt+[KeyG] | | +| Ctrl+Alt+KeyG | ŋ | Ctrl+Alt+G | | Ctrl+Alt+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | +| Shift+Alt+KeyG | G | Shift+Alt+G | | Shift+Alt+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | +| Ctrl+Shift+Alt+KeyG | Ŋ | Ctrl+Shift+Alt+G | | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyH | h | H | | H | h | H | [KeyH] | | +| Ctrl+KeyH | h | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | +| Shift+KeyH | H | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | +| Ctrl+Shift+KeyH | H | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | +| Alt+KeyH | h | Alt+H | | Alt+H | alt+h | Alt+H | alt+[KeyH] | | +| Ctrl+Alt+KeyH | ħ | Ctrl+Alt+H | | Ctrl+Alt+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | +| Shift+Alt+KeyH | H | Shift+Alt+H | | Shift+Alt+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | +| Ctrl+Shift+Alt+KeyH | Ħ | Ctrl+Shift+Alt+H | | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyI | i | I | | I | i | I | [KeyI] | | +| Ctrl+KeyI | i | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | +| Shift+KeyI | I | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | +| Ctrl+Shift+KeyI | I | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | +| Alt+KeyI | i | Alt+I | | Alt+I | alt+i | Alt+I | alt+[KeyI] | | +| Ctrl+Alt+KeyI | → | Ctrl+Alt+I | | Ctrl+Alt+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | +| Shift+Alt+KeyI | I | Shift+Alt+I | | Shift+Alt+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | +| Ctrl+Shift+Alt+KeyI | ı | Ctrl+Shift+Alt+I | | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyJ | j | J | | J | j | J | [KeyJ] | | +| Ctrl+KeyJ | j | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | +| Shift+KeyJ | J | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | +| Ctrl+Shift+KeyJ | J | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | +| Alt+KeyJ | j | Alt+J | | Alt+J | alt+j | Alt+J | alt+[KeyJ] | | +| Ctrl+Alt+KeyJ | U+309 | Ctrl+Alt+J | | Ctrl+Alt+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | +| Shift+Alt+KeyJ | J | Shift+Alt+J | | Shift+Alt+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | +| Ctrl+Shift+Alt+KeyJ | U+31b | Ctrl+Shift+Alt+J | | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyK | k | K | | K | k | K | [KeyK] | | +| Ctrl+KeyK | k | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | +| Shift+KeyK | K | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | +| Ctrl+Shift+KeyK | K | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | +| Alt+KeyK | k | Alt+K | | Alt+K | alt+k | Alt+K | alt+[KeyK] | | +| Ctrl+Alt+KeyK | ĸ | Ctrl+Alt+K | | Ctrl+Alt+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | +| Shift+Alt+KeyK | K | Shift+Alt+K | | Shift+Alt+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | +| Ctrl+Shift+Alt+KeyK | & | Ctrl+Shift+Alt+K | | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyL | l | L | | L | l | L | [KeyL] | | +| Ctrl+KeyL | l | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | +| Shift+KeyL | L | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | +| Ctrl+Shift+KeyL | L | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | +| Alt+KeyL | l | Alt+L | | Alt+L | alt+l | Alt+L | alt+[KeyL] | | +| Ctrl+Alt+KeyL | ł | Ctrl+Alt+L | | Ctrl+Alt+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | +| Shift+Alt+KeyL | L | Shift+Alt+L | | Shift+Alt+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | +| Ctrl+Shift+Alt+KeyL | Ł | Ctrl+Shift+Alt+L | | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyM | m | M | | M | m | M | [KeyM] | | +| Ctrl+KeyM | m | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | +| Shift+KeyM | M | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | +| Ctrl+Shift+KeyM | M | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | +| Alt+KeyM | m | Alt+M | | Alt+M | alt+m | Alt+M | alt+[KeyM] | | +| Ctrl+Alt+KeyM | µ | Ctrl+Alt+M | | Ctrl+Alt+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | +| Shift+Alt+KeyM | M | Shift+Alt+M | | Shift+Alt+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | +| Ctrl+Shift+Alt+KeyM | º | Ctrl+Shift+Alt+M | | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyN | n | N | | N | n | N | [KeyN] | | +| Ctrl+KeyN | n | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | +| Shift+KeyN | N | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | +| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | +| Alt+KeyN | n | Alt+N | | Alt+N | alt+n | Alt+N | alt+[KeyN] | | +| Ctrl+Alt+KeyN | n | Ctrl+Alt+N | | Ctrl+Alt+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | +| Shift+Alt+KeyN | N | Shift+Alt+N | | Shift+Alt+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | +| Ctrl+Shift+Alt+KeyN | N | Ctrl+Shift+Alt+N | | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyO | o | O | | O | o | O | [KeyO] | | +| Ctrl+KeyO | o | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | +| Shift+KeyO | O | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | +| Ctrl+Shift+KeyO | O | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | +| Alt+KeyO | o | Alt+O | | Alt+O | alt+o | Alt+O | alt+[KeyO] | | +| Ctrl+Alt+KeyO | ø | Ctrl+Alt+O | | Ctrl+Alt+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | +| Shift+Alt+KeyO | O | Shift+Alt+O | | Shift+Alt+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | +| Ctrl+Shift+Alt+KeyO | Ø | Ctrl+Shift+Alt+O | | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyP | p | P | | P | p | P | [KeyP] | | +| Ctrl+KeyP | p | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | +| Shift+KeyP | P | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | +| Ctrl+Shift+KeyP | P | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | +| Alt+KeyP | p | Alt+P | | Alt+P | alt+p | Alt+P | alt+[KeyP] | | +| Ctrl+Alt+KeyP | þ | Ctrl+Alt+P | | Ctrl+Alt+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | +| Shift+Alt+KeyP | P | Shift+Alt+P | | Shift+Alt+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | +| Ctrl+Shift+Alt+KeyP | Þ | Ctrl+Shift+Alt+P | | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyQ | q | Q | | Q | q | Q | [KeyQ] | | +| Ctrl+KeyQ | q | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | +| Shift+KeyQ | Q | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | +| Ctrl+Shift+KeyQ | Q | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | +| Alt+KeyQ | q | Alt+Q | | Alt+Q | alt+q | Alt+Q | alt+[KeyQ] | | +| Ctrl+Alt+KeyQ | @ | Ctrl+Alt+Q | | Ctrl+Alt+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | +| Shift+Alt+KeyQ | Q | Shift+Alt+Q | | Shift+Alt+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | +| Ctrl+Shift+Alt+KeyQ | Ω | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyR | r | R | | R | r | R | [KeyR] | | +| Ctrl+KeyR | r | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | +| Shift+KeyR | R | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | +| Ctrl+Shift+KeyR | R | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | +| Alt+KeyR | r | Alt+R | | Alt+R | alt+r | Alt+R | alt+[KeyR] | | +| Ctrl+Alt+KeyR | ¶ | Ctrl+Alt+R | | Ctrl+Alt+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | +| Shift+Alt+KeyR | R | Shift+Alt+R | | Shift+Alt+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | +| Ctrl+Shift+Alt+KeyR | ® | Ctrl+Shift+Alt+R | | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyS | s | S | | S | s | S | [KeyS] | | +| Ctrl+KeyS | s | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | +| Shift+KeyS | S | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | +| Ctrl+Shift+KeyS | S | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | +| Alt+KeyS | s | Alt+S | | Alt+S | alt+s | Alt+S | alt+[KeyS] | | +| Ctrl+Alt+KeyS | ß | Ctrl+Alt+S | | Ctrl+Alt+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | +| Shift+Alt+KeyS | S | Shift+Alt+S | | Shift+Alt+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | +| Ctrl+Shift+Alt+KeyS | § | Ctrl+Shift+Alt+S | | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyT | t | T | | T | t | T | [KeyT] | | +| Ctrl+KeyT | t | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | +| Shift+KeyT | T | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | +| Ctrl+Shift+KeyT | T | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | +| Alt+KeyT | t | Alt+T | | Alt+T | alt+t | Alt+T | alt+[KeyT] | | +| Ctrl+Alt+KeyT | ŧ | Ctrl+Alt+T | | Ctrl+Alt+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | +| Shift+Alt+KeyT | T | Shift+Alt+T | | Shift+Alt+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | +| Ctrl+Shift+Alt+KeyT | Ŧ | Ctrl+Shift+Alt+T | | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyU | u | U | | U | u | U | [KeyU] | | +| Ctrl+KeyU | u | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | +| Shift+KeyU | U | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | +| Ctrl+Shift+KeyU | U | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | +| Alt+KeyU | u | Alt+U | | Alt+U | alt+u | Alt+U | alt+[KeyU] | | +| Ctrl+Alt+KeyU | ↓ | Ctrl+Alt+U | | Ctrl+Alt+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | +| Shift+Alt+KeyU | U | Shift+Alt+U | | Shift+Alt+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | +| Ctrl+Shift+Alt+KeyU | ↑ | Ctrl+Shift+Alt+U | | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyV | v | V | | V | v | V | [KeyV] | | +| Ctrl+KeyV | v | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | +| Shift+KeyV | V | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | +| Ctrl+Shift+KeyV | V | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | +| Alt+KeyV | v | Alt+V | | Alt+V | alt+v | Alt+V | alt+[KeyV] | | +| Ctrl+Alt+KeyV | “ | Ctrl+Alt+V | | Ctrl+Alt+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | +| Shift+Alt+KeyV | V | Shift+Alt+V | | Shift+Alt+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | +| Ctrl+Shift+Alt+KeyV | ‘ | Ctrl+Shift+Alt+V | | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyW | w | W | | W | w | W | [KeyW] | | +| Ctrl+KeyW | w | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | +| Shift+KeyW | W | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | +| Ctrl+Shift+KeyW | W | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | +| Alt+KeyW | w | Alt+W | | Alt+W | alt+w | Alt+W | alt+[KeyW] | | +| Ctrl+Alt+KeyW | ł | Ctrl+Alt+W | | Ctrl+Alt+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | +| Shift+Alt+KeyW | W | Shift+Alt+W | | Shift+Alt+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | +| Ctrl+Shift+Alt+KeyW | Ł | Ctrl+Shift+Alt+W | | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyX | x | X | | X | x | X | [KeyX] | | +| Ctrl+KeyX | x | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | +| Shift+KeyX | X | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | +| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | +| Alt+KeyX | x | Alt+X | | Alt+X | alt+x | Alt+X | alt+[KeyX] | | +| Ctrl+Alt+KeyX | » | Ctrl+Alt+X | | Ctrl+Alt+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | +| Shift+Alt+KeyX | X | Shift+Alt+X | | Shift+Alt+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | +| Ctrl+Shift+Alt+KeyX | > | Ctrl+Shift+Alt+X | | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | +| | | Shift+. | 2 | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyY | y | Y | | Y | y | Y | [KeyY] | | +| Ctrl+KeyY | y | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyY] | | +| Shift+KeyY | Y | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyY] | | +| Ctrl+Shift+KeyY | Y | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyY] | | +| Alt+KeyY | y | Alt+Y | | Alt+Y | alt+y | Alt+Y | alt+[KeyY] | | +| Ctrl+Alt+KeyY | ← | Ctrl+Alt+Y | | Ctrl+Alt+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyY] | | +| Shift+Alt+KeyY | Y | Shift+Alt+Y | | Shift+Alt+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyY] | | +| Ctrl+Shift+Alt+KeyY | ¥ | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyY] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyZ | z | Z | | Z | z | Z | [KeyZ] | | +| Ctrl+KeyZ | z | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyZ] | | +| Shift+KeyZ | Z | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyZ] | | +| Ctrl+Shift+KeyZ | Z | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyZ] | | +| Alt+KeyZ | z | Alt+Z | | Alt+Z | alt+z | Alt+Z | alt+[KeyZ] | | +| Ctrl+Alt+KeyZ | « | Ctrl+Alt+Z | | Ctrl+Alt+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyZ] | | +| Shift+Alt+KeyZ | Z | Shift+Alt+Z | | Shift+Alt+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyZ] | | +| Ctrl+Shift+Alt+KeyZ | < | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyZ] | | +| | | Shift+, | 2 | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit1 | 1 | 1 | | 1 | 1 | 1 | [Digit1] | | +| Ctrl+Digit1 | 1 | Ctrl+1 | | Ctrl+1 | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | | +| Shift+Digit1 | ! | Shift+1 | | Shift+1 | shift+1 | Shift+1 | shift+[Digit1] | | +| Ctrl+Shift+Digit1 | ! | Ctrl+Shift+1 | | Ctrl+Shift+1 | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | | +| Alt+Digit1 | 1 | Alt+1 | | Alt+1 | alt+1 | Alt+1 | alt+[Digit1] | | +| Ctrl+Alt+Digit1 | ¹ | Ctrl+Alt+1 | | Ctrl+Alt+1 | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | | +| Shift+Alt+Digit1 | ! | Shift+Alt+1 | | Shift+Alt+1 | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | | +| Ctrl+Shift+Alt+Digit1 | ¡ | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit2 | 2 | 2 | | 2 | 2 | 2 | [Digit2] | | +| Ctrl+Digit2 | 2 | Ctrl+2 | | Ctrl+2 | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | | +| Shift+Digit2 | " | Shift+2 | | Shift+2 | shift+2 | Shift+2 | shift+[Digit2] | | +| | | Shift+' | 2 | | | | | | +| Ctrl+Shift+Digit2 | " | Ctrl+Shift+2 | | Ctrl+Shift+2 | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | | +| | | Ctrl+Shift+' | 2 | | | | | | +| Alt+Digit2 | 2 | Alt+2 | | Alt+2 | alt+2 | Alt+2 | alt+[Digit2] | | +| Ctrl+Alt+Digit2 | ² | Ctrl+Alt+2 | | Ctrl+Alt+2 | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | | +| Shift+Alt+Digit2 | " | Shift+Alt+2 | | Shift+Alt+2 | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | | +| | | Shift+Alt+' | 2 | | | | | | +| Ctrl+Shift+Alt+Digit2 | ⅛ | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | | +| | | Ctrl+Shift+Alt+' | 2 | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit3 | 3 | 3 | | 3 | 3 | 3 | [Digit3] | | +| Ctrl+Digit3 | 3 | Ctrl+3 | | Ctrl+3 | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | | +| Shift+Digit3 | £ | Shift+3 | | Shift+3 | shift+3 | Shift+3 | shift+[Digit3] | | +| Ctrl+Shift+Digit3 | £ | Ctrl+Shift+3 | | Ctrl+Shift+3 | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | | +| Alt+Digit3 | 3 | Alt+3 | | Alt+3 | alt+3 | Alt+3 | alt+[Digit3] | | +| Ctrl+Alt+Digit3 | ³ | Ctrl+Alt+3 | | Ctrl+Alt+3 | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | | +| Shift+Alt+Digit3 | £ | Shift+Alt+3 | | Shift+Alt+3 | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | | +| Ctrl+Shift+Alt+Digit3 | £ | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit4 | 4 | 4 | | 4 | 4 | 4 | [Digit4] | | +| Ctrl+Digit4 | 4 | Ctrl+4 | | Ctrl+4 | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | | +| Shift+Digit4 | $ | Shift+4 | | Shift+4 | shift+4 | Shift+4 | shift+[Digit4] | | +| Ctrl+Shift+Digit4 | $ | Ctrl+Shift+4 | | Ctrl+Shift+4 | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | | +| Alt+Digit4 | 4 | Alt+4 | | Alt+4 | alt+4 | Alt+4 | alt+[Digit4] | | +| Ctrl+Alt+Digit4 | € | Ctrl+Alt+4 | | Ctrl+Alt+4 | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | | +| Shift+Alt+Digit4 | $ | Shift+Alt+4 | | Shift+Alt+4 | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | | +| Ctrl+Shift+Alt+Digit4 | ¼ | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit5 | 5 | 5 | | 5 | 5 | 5 | [Digit5] | | +| Ctrl+Digit5 | 5 | Ctrl+5 | | Ctrl+5 | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | | +| Shift+Digit5 | % | Shift+5 | | Shift+5 | shift+5 | Shift+5 | shift+[Digit5] | | +| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+5 | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | | +| Alt+Digit5 | 5 | Alt+5 | | Alt+5 | alt+5 | Alt+5 | alt+[Digit5] | | +| Ctrl+Alt+Digit5 | ½ | Ctrl+Alt+5 | | Ctrl+Alt+5 | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | | +| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Alt+5 | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | | +| Ctrl+Shift+Alt+Digit5 | ⅜ | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit6 | 6 | 6 | | 6 | 6 | 6 | [Digit6] | | +| Ctrl+Digit6 | 6 | Ctrl+6 | | Ctrl+6 | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | | +| Shift+Digit6 | ^ | Shift+6 | | Shift+6 | shift+6 | Shift+6 | shift+[Digit6] | | +| Ctrl+Shift+Digit6 | ^ | Ctrl+Shift+6 | | Ctrl+Shift+6 | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | | +| Alt+Digit6 | 6 | Alt+6 | | Alt+6 | alt+6 | Alt+6 | alt+[Digit6] | | +| Ctrl+Alt+Digit6 | ¾ | Ctrl+Alt+6 | | Ctrl+Alt+6 | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | | +| Shift+Alt+Digit6 | ^ | Shift+Alt+6 | | Shift+Alt+6 | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | | +| Ctrl+Shift+Alt+Digit6 | ⅝ | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit7 | 7 | 7 | | 7 | 7 | 7 | [Digit7] | | +| Ctrl+Digit7 | 7 | Ctrl+7 | | Ctrl+7 | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | | +| Shift+Digit7 | & | Shift+7 | | Shift+7 | shift+7 | Shift+7 | shift+[Digit7] | | +| Ctrl+Shift+Digit7 | & | Ctrl+Shift+7 | | Ctrl+Shift+7 | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | | +| Alt+Digit7 | 7 | Alt+7 | | Alt+7 | alt+7 | Alt+7 | alt+[Digit7] | | +| Ctrl+Alt+Digit7 | { | Ctrl+Alt+7 | | Ctrl+Alt+7 | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | | +| | | Shift+[ | 2 | | | | | | +| Shift+Alt+Digit7 | & | Shift+Alt+7 | | Shift+Alt+7 | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | | +| Ctrl+Shift+Alt+Digit7 | ⅞ | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit8 | 8 | 8 | | 8 | 8 | 8 | [Digit8] | | +| Ctrl+Digit8 | 8 | Ctrl+8 | | Ctrl+8 | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | | +| Shift+Digit8 | * | Shift+8 | | Shift+8 | shift+8 | Shift+8 | shift+[Digit8] | | +| Ctrl+Shift+Digit8 | * | Ctrl+Shift+8 | | Ctrl+Shift+8 | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | | +| Alt+Digit8 | 8 | Alt+8 | | Alt+8 | alt+8 | Alt+8 | alt+[Digit8] | | +| Ctrl+Alt+Digit8 | [ | Ctrl+Alt+8 | | Ctrl+Alt+8 | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | | +| | | [ | 2 | | | | | | +| Shift+Alt+Digit8 | * | Shift+Alt+8 | | Shift+Alt+8 | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | | +| Ctrl+Shift+Alt+Digit8 | ™ | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit9 | 9 | 9 | | 9 | 9 | 9 | [Digit9] | | +| Ctrl+Digit9 | 9 | Ctrl+9 | | Ctrl+9 | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | | +| Shift+Digit9 | ( | Shift+9 | | Shift+9 | shift+9 | Shift+9 | shift+[Digit9] | | +| Ctrl+Shift+Digit9 | ( | Ctrl+Shift+9 | | Ctrl+Shift+9 | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | | +| Alt+Digit9 | 9 | Alt+9 | | Alt+9 | alt+9 | Alt+9 | alt+[Digit9] | | +| Ctrl+Alt+Digit9 | ] | Ctrl+Alt+9 | | Ctrl+Alt+9 | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | | +| | | ] | 2 | | | | | | +| Shift+Alt+Digit9 | ( | Shift+Alt+9 | | Shift+Alt+9 | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | | +| Ctrl+Shift+Alt+Digit9 | ± | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit0 | 0 | 0 | | 0 | 0 | 0 | [Digit0] | | +| Ctrl+Digit0 | 0 | Ctrl+0 | | Ctrl+0 | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | | +| Shift+Digit0 | ) | Shift+0 | | Shift+0 | shift+0 | Shift+0 | shift+[Digit0] | | +| Ctrl+Shift+Digit0 | ) | Ctrl+Shift+0 | | Ctrl+Shift+0 | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | | +| Alt+Digit0 | 0 | Alt+0 | | Alt+0 | alt+0 | Alt+0 | alt+[Digit0] | | +| Ctrl+Alt+Digit0 | } | Ctrl+Alt+0 | | Ctrl+Alt+0 | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | | +| | | Shift+] | 2 | | | | | | +| Shift+Alt+Digit0 | ) | Shift+Alt+0 | | Shift+Alt+0 | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | | +| Ctrl+Shift+Alt+Digit0 | ° | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Minus | - | - | | - | - | null | [Minus] | | +| Ctrl+Minus | - | Ctrl+- | | Ctrl+- | ctrl+- | null | ctrl+[Minus] | | +| Shift+Minus | _ | Shift+- | | Shift+- | shift+- | null | shift+[Minus] | | +| Ctrl+Shift+Minus | _ | Ctrl+Shift+- | | Ctrl+Shift+- | ctrl+shift+- | null | ctrl+shift+[Minus] | | +| Alt+Minus | - | Alt+- | | Alt+- | alt+- | null | alt+[Minus] | | +| Ctrl+Alt+Minus | \ | \ | 1 | Ctrl+Alt+- | ctrl+alt+[Minus] | null | ctrl+alt+[Minus] | NO | +| Shift+Alt+Minus | _ | Shift+Alt+- | | Shift+Alt+- | shift+alt+- | null | shift+alt+[Minus] | | +| Ctrl+Shift+Alt+Minus | ¿ | Ctrl+Shift+Alt+- | | Ctrl+Shift+Alt+- | ctrl+shift+alt+- | null | ctrl+shift+alt+[Minus] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Equal | = | = | | = | = | null | [Equal] | | +| Ctrl+Equal | = | Ctrl+= | | Ctrl+= | ctrl+= | null | ctrl+[Equal] | | +| Shift+Equal | + | Shift+= | | Shift+= | shift+= | null | shift+[Equal] | | +| Ctrl+Shift+Equal | + | Ctrl+Shift+= | | Ctrl+Shift+= | ctrl+shift+= | null | ctrl+shift+[Equal] | | +| Alt+Equal | = | Alt+= | | Alt+= | alt+= | null | alt+[Equal] | | +| Ctrl+Alt+Equal | U+327 | Ctrl+Alt+= | | Ctrl+Alt+= | ctrl+alt+= | null | ctrl+alt+[Equal] | | +| Shift+Alt+Equal | + | Shift+Alt+= | | Shift+Alt+= | shift+alt+= | null | shift+alt+[Equal] | | +| Ctrl+Shift+Alt+Equal | U+328 | Ctrl+Shift+Alt+= | | Ctrl+Shift+Alt+= | ctrl+shift+alt+= | null | ctrl+shift+alt+[Equal] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketLeft | [ | [ | 1 | [ | [ | null | [BracketLeft] | | +| Ctrl+BracketLeft | [ | Ctrl+[ | | Ctrl+[ | ctrl+[ | null | ctrl+[BracketLeft] | | +| Shift+BracketLeft | { | Shift+[ | 1 | Shift+[ | shift+[ | null | shift+[BracketLeft] | | +| Ctrl+Shift+BracketLeft | { | Ctrl+Shift+[ | | Ctrl+Shift+[ | ctrl+shift+[ | null | ctrl+shift+[BracketLeft] | | +| Alt+BracketLeft | [ | Alt+[ | | Alt+[ | alt+[ | null | alt+[BracketLeft] | | +| Ctrl+Alt+BracketLeft | ¨ | Ctrl+Alt+[ | | Ctrl+Alt+[ | ctrl+alt+[ | null | ctrl+alt+[BracketLeft] | | +| Shift+Alt+BracketLeft | { | Shift+Alt+[ | | Shift+Alt+[ | shift+alt+[ | null | shift+alt+[BracketLeft] | | +| Ctrl+Shift+Alt+BracketLeft | ˚ | Ctrl+Shift+Alt+[ | | Ctrl+Shift+Alt+[ | ctrl+shift+alt+[ | null | ctrl+shift+alt+[BracketLeft] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketRight | ] | ] | 1 | ] | ] | null | [BracketRight] | | +| Ctrl+BracketRight | ] | Ctrl+] | | Ctrl+] | ctrl+] | null | ctrl+[BracketRight] | | +| Shift+BracketRight | } | Shift+] | 1 | Shift+] | shift+] | null | shift+[BracketRight] | | +| Ctrl+Shift+BracketRight | } | Ctrl+Shift+] | | Ctrl+Shift+] | ctrl+shift+] | null | ctrl+shift+[BracketRight] | | +| Alt+BracketRight | ] | Alt+] | | Alt+] | alt+] | null | alt+[BracketRight] | | +| Ctrl+Alt+BracketRight | ˜ | Ctrl+Alt+] | | Ctrl+Alt+] | ctrl+alt+] | null | ctrl+alt+[BracketRight] | | +| Shift+Alt+BracketRight | } | Shift+Alt+] | | Shift+Alt+] | shift+alt+] | null | shift+alt+[BracketRight] | | +| Ctrl+Shift+Alt+BracketRight | ¯ | Ctrl+Shift+Alt+] | | Ctrl+Shift+Alt+] | ctrl+shift+alt+] | null | ctrl+shift+alt+[BracketRight] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backslash | # | | | # | [Backslash] | null | [Backslash] | NO | +| Ctrl+Backslash | # | | | Ctrl+# | ctrl+[Backslash] | null | ctrl+[Backslash] | NO | +| Shift+Backslash | ~ | Shift+` | 2 | Shift+# | shift+[Backslash] | null | shift+[Backslash] | NO | +| Ctrl+Shift+Backslash | ~ | Ctrl+Shift+` | 2 | Ctrl+Shift+# | ctrl+shift+[Backslash] | null | ctrl+shift+[Backslash] | NO | +| Alt+Backslash | # | | | Alt+# | alt+[Backslash] | null | alt+[Backslash] | NO | +| Ctrl+Alt+Backslash | ` | ` | 2 | Ctrl+Alt+# | ctrl+alt+[Backslash] | null | ctrl+alt+[Backslash] | NO | +| Shift+Alt+Backslash | ~ | Shift+Alt+` | 2 | Shift+Alt+# | shift+alt+[Backslash] | null | shift+alt+[Backslash] | NO | +| Ctrl+Shift+Alt+Backslash | ˘ | Ctrl+Shift+Alt+` | 2 | Ctrl+Shift+Alt+# | ctrl+shift+alt+[Backslash] | null | ctrl+shift+alt+[Backslash] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlHash | --- | | | null | null | null | null | | +| Ctrl+IntlHash | --- | | | null | null | null | null | | +| Shift+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | +| Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | +| Shift+Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Semicolon | ; | ; | | ; | ; | null | [Semicolon] | | +| Ctrl+Semicolon | ; | Ctrl+; | | Ctrl+; | ctrl+; | null | ctrl+[Semicolon] | | +| Shift+Semicolon | : | Shift+; | | Shift+; | shift+; | null | shift+[Semicolon] | | +| Ctrl+Shift+Semicolon | : | Ctrl+Shift+; | | Ctrl+Shift+; | ctrl+shift+; | null | ctrl+shift+[Semicolon] | | +| Alt+Semicolon | ; | Alt+; | | Alt+; | alt+; | null | alt+[Semicolon] | | +| Ctrl+Alt+Semicolon | ´ | Ctrl+Alt+; | | Ctrl+Alt+; | ctrl+alt+; | null | ctrl+alt+[Semicolon] | | +| Shift+Alt+Semicolon | : | Shift+Alt+; | | Shift+Alt+; | shift+alt+; | null | shift+alt+[Semicolon] | | +| Ctrl+Shift+Alt+Semicolon | ˝ | Ctrl+Shift+Alt+; | | Ctrl+Shift+Alt+; | ctrl+shift+alt+; | null | ctrl+shift+alt+[Semicolon] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Quote | ' | ' | | ' | ' | ' | [Quote] | | +| Ctrl+Quote | ' | Ctrl+' | | Ctrl+' | ctrl+' | Ctrl+' | ctrl+[Quote] | | +| Shift+Quote | @ | Shift+' | 1 | Shift+' | shift+' | Shift+' | shift+[Quote] | | +| Ctrl+Shift+Quote | @ | Ctrl+Shift+' | 1 | Ctrl+Shift+' | ctrl+shift+' | Ctrl+Shift+' | ctrl+shift+[Quote] | | +| Alt+Quote | ' | Alt+' | | Alt+' | alt+' | Alt+' | alt+[Quote] | | +| Ctrl+Alt+Quote | ^ | Ctrl+Alt+' | | Ctrl+Alt+' | ctrl+alt+' | Ctrl+Alt+' | ctrl+alt+[Quote] | | +| Shift+Alt+Quote | @ | Shift+Alt+' | 1 | Shift+Alt+' | shift+alt+' | Shift+Alt+' | shift+alt+[Quote] | | +| Ctrl+Shift+Alt+Quote | U+30c | Ctrl+Shift+Alt+' | 1 | Ctrl+Shift+Alt+' | ctrl+shift+alt+' | Ctrl+Shift+Alt+' | ctrl+shift+alt+[Quote] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backquote | ` | ` | 1 | ` | ` | null | [Backquote] | | +| Ctrl+Backquote | ` | Ctrl+` | | Ctrl+` | ctrl+` | null | ctrl+[Backquote] | | +| Shift+Backquote | ¬ | Shift+` | 1 | Shift+` | shift+` | null | shift+[Backquote] | | +| Ctrl+Shift+Backquote | ¬ | Ctrl+Shift+` | 1 | Ctrl+Shift+` | ctrl+shift+` | null | ctrl+shift+[Backquote] | | +| Alt+Backquote | ` | Alt+` | | Alt+` | alt+` | null | alt+[Backquote] | | +| Ctrl+Alt+Backquote | | | Shift+\ | 1 | Ctrl+Alt+` | ctrl+alt+[Backquote] | null | ctrl+alt+[Backquote] | NO | +| Shift+Alt+Backquote | ¬ | Shift+Alt+` | 1 | Shift+Alt+` | shift+alt+` | null | shift+alt+[Backquote] | | +| Ctrl+Shift+Alt+Backquote | | | Ctrl+Shift+Alt+` | 1 | Ctrl+Shift+Alt+` | ctrl+shift+alt+` | null | ctrl+shift+alt+[Backquote] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Comma | , | , | | , | , | null | [Comma] | | +| Ctrl+Comma | , | Ctrl+, | | Ctrl+, | ctrl+, | null | ctrl+[Comma] | | +| Shift+Comma | < | Shift+, | 1 | Shift+, | shift+, | null | shift+[Comma] | | +| Ctrl+Shift+Comma | < | Ctrl+Shift+, | | Ctrl+Shift+, | ctrl+shift+, | null | ctrl+shift+[Comma] | | +| Alt+Comma | , | Alt+, | | Alt+, | alt+, | null | alt+[Comma] | | +| Ctrl+Alt+Comma | ─ | Ctrl+Alt+, | | Ctrl+Alt+, | ctrl+alt+, | null | ctrl+alt+[Comma] | | +| Shift+Alt+Comma | < | Shift+Alt+, | | Shift+Alt+, | shift+alt+, | null | shift+alt+[Comma] | | +| Ctrl+Shift+Alt+Comma | × | Ctrl+Shift+Alt+, | | Ctrl+Shift+Alt+, | ctrl+shift+alt+, | null | ctrl+shift+alt+[Comma] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Period | . | . | | . | . | null | [Period] | | +| Ctrl+Period | . | Ctrl+. | | Ctrl+. | ctrl+. | null | ctrl+[Period] | | +| Shift+Period | > | Shift+. | 1 | Shift+. | shift+. | null | shift+[Period] | | +| Ctrl+Shift+Period | > | Ctrl+Shift+. | | Ctrl+Shift+. | ctrl+shift+. | null | ctrl+shift+[Period] | | +| Alt+Period | . | Alt+. | | Alt+. | alt+. | null | alt+[Period] | | +| Ctrl+Alt+Period | · | Ctrl+Alt+. | | Ctrl+Alt+. | ctrl+alt+. | null | ctrl+alt+[Period] | | +| Shift+Alt+Period | > | Shift+Alt+. | | Shift+Alt+. | shift+alt+. | null | shift+alt+[Period] | | +| Ctrl+Shift+Alt+Period | ÷ | Ctrl+Shift+Alt+. | | Ctrl+Shift+Alt+. | ctrl+shift+alt+. | null | ctrl+shift+alt+[Period] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Slash | / | / | | / | / | null | [Slash] | | +| Ctrl+Slash | / | Ctrl+/ | | Ctrl+/ | ctrl+/ | null | ctrl+[Slash] | | +| Shift+Slash | ? | Shift+/ | | Shift+/ | shift+/ | null | shift+[Slash] | | +| Ctrl+Shift+Slash | ? | Ctrl+Shift+/ | | Ctrl+Shift+/ | ctrl+shift+/ | null | ctrl+shift+[Slash] | | +| Alt+Slash | / | Alt+/ | | Alt+/ | alt+/ | null | alt+[Slash] | | +| Ctrl+Alt+Slash | U+323 | Ctrl+Alt+/ | | Ctrl+Alt+/ | ctrl+alt+/ | null | ctrl+alt+[Slash] | | +| Shift+Alt+Slash | ? | Shift+Alt+/ | | Shift+Alt+/ | shift+alt+/ | null | shift+alt+[Slash] | | +| Ctrl+Shift+Alt+Slash | ˙ | Ctrl+Shift+Alt+/ | | Ctrl+Shift+Alt+/ | ctrl+shift+alt+/ | null | ctrl+shift+alt+[Slash] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | +| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | +| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | +| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | +| Alt+ArrowUp | --- | Alt+UpArrow | | Alt+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | +| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Alt+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | +| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Alt+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | +| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | +| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | +| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | +| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | +| Alt+Numpad0 | --- | Alt+NumPad0 | | Alt+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | +| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | +| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Alt+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | +| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlBackslash | \ | \ | 2 | \ | \ | null | [IntlBackslash] | | +| Ctrl+IntlBackslash | \ | Ctrl+\ | | Ctrl+\ | ctrl+\ | null | ctrl+[IntlBackslash] | | +| Shift+IntlBackslash | | | Shift+\ | 2 | Shift+\ | shift+\ | null | shift+[IntlBackslash] | | +| Ctrl+Shift+IntlBackslash | | | Ctrl+Shift+\ | | Ctrl+Shift+\ | ctrl+shift+\ | null | ctrl+shift+[IntlBackslash] | | +| Alt+IntlBackslash | \ | Alt+\ | | Alt+\ | alt+\ | null | alt+[IntlBackslash] | | +| Ctrl+Alt+IntlBackslash | | | Ctrl+Alt+\ | | Ctrl+Alt+\ | ctrl+alt+\ | null | ctrl+alt+[IntlBackslash] | | +| Shift+Alt+IntlBackslash | | | Shift+Alt+\ | | Shift+Alt+\ | shift+alt+\ | null | shift+alt+[IntlBackslash] | | +| Ctrl+Shift+Alt+IntlBackslash | ¦ | Ctrl+Shift+Alt+\ | | Ctrl+Shift+Alt+\ | ctrl+shift+alt+\ | null | ctrl+shift+alt+[IntlBackslash] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | +| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | +| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | +| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | +| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | +| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | +| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | +| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | +| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | +| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | +| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | +| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | +| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | +| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | +| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/node/linux_en_us.js b/src/vs/workbench/services/keybinding/test/node/linux_en_us.js new file mode 100644 index 00000000000..9f6ddd3caf9 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/linux_en_us.js @@ -0,0 +1,497 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +define({ + Sleep: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + WakeUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + KeyA: { + value: 'a', + withShift: 'A', + withAltGr: 'a', + withShiftAltGr: 'A' + }, + KeyB: { + value: 'b', + withShift: 'B', + withAltGr: 'b', + withShiftAltGr: 'B' + }, + KeyC: { + value: 'c', + withShift: 'C', + withAltGr: 'c', + withShiftAltGr: 'C' + }, + KeyD: { + value: 'd', + withShift: 'D', + withAltGr: 'd', + withShiftAltGr: 'D' + }, + KeyE: { + value: 'e', + withShift: 'E', + withAltGr: 'e', + withShiftAltGr: 'E' + }, + KeyF: { + value: 'f', + withShift: 'F', + withAltGr: 'f', + withShiftAltGr: 'F' + }, + KeyG: { + value: 'g', + withShift: 'G', + withAltGr: 'g', + withShiftAltGr: 'G' + }, + KeyH: { + value: 'h', + withShift: 'H', + withAltGr: 'h', + withShiftAltGr: 'H' + }, + KeyI: { + value: 'i', + withShift: 'I', + withAltGr: 'i', + withShiftAltGr: 'I' + }, + KeyJ: { + value: 'j', + withShift: 'J', + withAltGr: 'j', + withShiftAltGr: 'J' + }, + KeyK: { + value: 'k', + withShift: 'K', + withAltGr: 'k', + withShiftAltGr: 'K' + }, + KeyL: { + value: 'l', + withShift: 'L', + withAltGr: 'l', + withShiftAltGr: 'L' + }, + KeyM: { + value: 'm', + withShift: 'M', + withAltGr: 'm', + withShiftAltGr: 'M' + }, + KeyN: { + value: 'n', + withShift: 'N', + withAltGr: 'n', + withShiftAltGr: 'N' + }, + KeyO: { + value: 'o', + withShift: 'O', + withAltGr: 'o', + withShiftAltGr: 'O' + }, + KeyP: { + value: 'p', + withShift: 'P', + withAltGr: 'p', + withShiftAltGr: 'P' + }, + KeyQ: { + value: 'q', + withShift: 'Q', + withAltGr: 'q', + withShiftAltGr: 'Q' + }, + KeyR: { + value: 'r', + withShift: 'R', + withAltGr: 'r', + withShiftAltGr: 'R' + }, + KeyS: { + value: 's', + withShift: 'S', + withAltGr: 's', + withShiftAltGr: 'S' + }, + KeyT: { + value: 't', + withShift: 'T', + withAltGr: 't', + withShiftAltGr: 'T' + }, + KeyU: { + value: 'u', + withShift: 'U', + withAltGr: 'u', + withShiftAltGr: 'U' + }, + KeyV: { + value: 'v', + withShift: 'V', + withAltGr: 'v', + withShiftAltGr: 'V' + }, + KeyW: { + value: 'w', + withShift: 'W', + withAltGr: 'w', + withShiftAltGr: 'W' + }, + KeyX: { + value: 'x', + withShift: 'X', + withAltGr: 'x', + withShiftAltGr: 'X' + }, + KeyY: { + value: 'y', + withShift: 'Y', + withAltGr: 'y', + withShiftAltGr: 'Y' + }, + KeyZ: { + value: 'z', + withShift: 'Z', + withAltGr: 'z', + withShiftAltGr: 'Z' + }, + Digit1: { + value: '1', + withShift: '!', + withAltGr: '1', + withShiftAltGr: '!' + }, + Digit2: { + value: '2', + withShift: '@', + withAltGr: '2', + withShiftAltGr: '@' + }, + Digit3: { + value: '3', + withShift: '#', + withAltGr: '3', + withShiftAltGr: '#' + }, + Digit4: { + value: '4', + withShift: '$', + withAltGr: '4', + withShiftAltGr: '$' + }, + Digit5: { + value: '5', + withShift: '%', + withAltGr: '5', + withShiftAltGr: '%' + }, + Digit6: { + value: '6', + withShift: '^', + withAltGr: '6', + withShiftAltGr: '^' + }, + Digit7: { + value: '7', + withShift: '&', + withAltGr: '7', + withShiftAltGr: '&' + }, + Digit8: { + value: '8', + withShift: '*', + withAltGr: '8', + withShiftAltGr: '*' + }, + Digit9: { + value: '9', + withShift: '(', + withAltGr: '9', + withShiftAltGr: '(' + }, + Digit0: { + value: '0', + withShift: ')', + withAltGr: '0', + withShiftAltGr: ')' + }, + Enter: { + value: '\r', + withShift: '\r', + withAltGr: '\r', + withShiftAltGr: '\r' + }, + Escape: { + value: '\u001b', + withShift: '\u001b', + withAltGr: '\u001b', + withShiftAltGr: '\u001b' + }, + Backspace: { + value: '\b', + withShift: '\b', + withAltGr: '\b', + withShiftAltGr: '\b' + }, + Tab: { + value: '\t', + withShift: '', + withAltGr: '\t', + withShiftAltGr: '' + }, + Space: { + value: ' ', + withShift: ' ', + withAltGr: ' ', + withShiftAltGr: ' ' + }, + Minus: { + value: '-', + withShift: '_', + withAltGr: '-', + withShiftAltGr: '_' + }, + Equal: { + value: '=', + withShift: '+', + withAltGr: '=', + withShiftAltGr: '+' + }, + BracketLeft: { + value: '[', + withShift: '{', + withAltGr: '[', + withShiftAltGr: '{' + }, + BracketRight: { + value: ']', + withShift: '}', + withAltGr: ']', + withShiftAltGr: '}' + }, + Backslash: { + value: '\\', + withShift: '|', + withAltGr: '\\', + withShiftAltGr: '|' + }, + Semicolon: { + value: ';', + withShift: ':', + withAltGr: ';', + withShiftAltGr: ':' + }, + Quote: { + value: '\'', + withShift: '"', + withAltGr: '\'', + withShiftAltGr: '"' + }, + Backquote: { + value: '`', + withShift: '~', + withAltGr: '`', + withShiftAltGr: '~' + }, + Comma: { + value: ',', + withShift: '<', + withAltGr: ',', + withShiftAltGr: '<' + }, + Period: { + value: '.', + withShift: '>', + withAltGr: '.', + withShiftAltGr: '>' + }, + Slash: { + value: '/', + withShift: '?', + withAltGr: '/', + withShiftAltGr: '?' + }, + CapsLock: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F1: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F2: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F3: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F4: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F5: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F6: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F7: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F8: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F9: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F10: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F11: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F12: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + PrintScreen: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ScrollLock: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Pause: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Insert: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Home: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + PageUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Delete: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + End: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + PageDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ArrowRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ArrowLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ArrowDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ArrowUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + NumLock: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + NumpadDivide: { + value: '/', + withShift: '/', + withAltGr: '/', + withShiftAltGr: '/' + }, + NumpadMultiply: { + value: '*', + withShift: '*', + withAltGr: '*', + withShiftAltGr: '*' + }, + NumpadSubtract: { + value: '-', + withShift: '-', + withAltGr: '-', + withShiftAltGr: '-' + }, + NumpadAdd: { + value: '+', + withShift: '+', + withAltGr: '+', + withShiftAltGr: '+' + }, + NumpadEnter: { + value: '\r', + withShift: '\r', + withAltGr: '\r', + withShiftAltGr: '\r' + }, + Numpad1: { value: '', withShift: '1', withAltGr: '', withShiftAltGr: '1' }, + Numpad2: { value: '', withShift: '2', withAltGr: '', withShiftAltGr: '2' }, + Numpad3: { value: '', withShift: '3', withAltGr: '', withShiftAltGr: '3' }, + Numpad4: { value: '', withShift: '4', withAltGr: '', withShiftAltGr: '4' }, + Numpad5: { value: '', withShift: '5', withAltGr: '', withShiftAltGr: '5' }, + Numpad6: { value: '', withShift: '6', withAltGr: '', withShiftAltGr: '6' }, + Numpad7: { value: '', withShift: '7', withAltGr: '', withShiftAltGr: '7' }, + Numpad8: { value: '', withShift: '8', withAltGr: '', withShiftAltGr: '8' }, + Numpad9: { value: '', withShift: '9', withAltGr: '', withShiftAltGr: '9' }, + Numpad0: { value: '', withShift: '0', withAltGr: '', withShiftAltGr: '0' }, + NumpadDecimal: { value: '', withShift: '.', withAltGr: '', withShiftAltGr: '.' }, + IntlBackslash: { + value: '<', + withShift: '>', + withAltGr: '|', + withShiftAltGr: '¦' + }, + ContextMenu: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Power: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + NumpadEqual: { + value: '=', + withShift: '=', + withAltGr: '=', + withShiftAltGr: '=' + }, + F13: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F14: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F15: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F16: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F17: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F18: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F19: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F20: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F21: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F22: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F23: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + F24: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Open: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Help: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Select: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Again: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Undo: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Cut: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Copy: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Paste: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Find: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + AudioVolumeMute: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + AudioVolumeUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + AudioVolumeDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + NumpadComma: { + value: '.', + withShift: '.', + withAltGr: '.', + withShiftAltGr: '.' + }, + IntlRo: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + KanaMode: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + IntlYen: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Convert: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + NonConvert: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Lang1: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Lang2: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Lang3: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Lang4: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Lang5: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + NumpadParenLeft: { + value: '(', + withShift: '(', + withAltGr: '(', + withShiftAltGr: '(' + }, + NumpadParenRight: { + value: ')', + withShift: ')', + withAltGr: ')', + withShiftAltGr: ')' + }, + ControlLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ShiftLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + AltLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MetaLeft: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ControlRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + ShiftRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + AltRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MetaRight: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrightnessUp: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrightnessDown: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaPlay: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaRecord: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaFastForward: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaRewind: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaTrackNext: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaTrackPrevious: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaStop: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + Eject: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaPlayPause: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MediaSelect: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + LaunchMail: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + LaunchApp2: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + LaunchApp1: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + SelectTask: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + LaunchScreenSaver: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrowserSearch: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrowserHome: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrowserBack: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrowserForward: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrowserStop: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrowserRefresh: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + BrowserFavorites: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MailReply: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MailForward: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' }, + MailSend: { value: '', withShift: '', withAltGr: '', withShiftAltGr: '' } + +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/node/linux_en_us.txt b/src/vs/workbench/services/keybinding/test/node/linux_en_us.txt new file mode 100644 index 00000000000..704e852f8d6 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/linux_en_us.txt @@ -0,0 +1,507 @@ +isUSStandard: true +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyA | a | A | | A | a | A | [KeyA] | | +| Ctrl+KeyA | a | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | +| Shift+KeyA | A | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | +| Ctrl+Shift+KeyA | A | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | +| Alt+KeyA | a | Alt+A | | Alt+A | alt+a | Alt+A | alt+[KeyA] | | +| Ctrl+Alt+KeyA | a | Ctrl+Alt+A | | Ctrl+Alt+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | +| Shift+Alt+KeyA | A | Shift+Alt+A | | Shift+Alt+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | +| Ctrl+Shift+Alt+KeyA | A | Ctrl+Shift+Alt+A | | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyB | b | B | | B | b | B | [KeyB] | | +| Ctrl+KeyB | b | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | +| Shift+KeyB | B | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | +| Ctrl+Shift+KeyB | B | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | +| Alt+KeyB | b | Alt+B | | Alt+B | alt+b | Alt+B | alt+[KeyB] | | +| Ctrl+Alt+KeyB | b | Ctrl+Alt+B | | Ctrl+Alt+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | +| Shift+Alt+KeyB | B | Shift+Alt+B | | Shift+Alt+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | +| Ctrl+Shift+Alt+KeyB | B | Ctrl+Shift+Alt+B | | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyC | c | C | | C | c | C | [KeyC] | | +| Ctrl+KeyC | c | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | +| Shift+KeyC | C | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | +| Ctrl+Shift+KeyC | C | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | +| Alt+KeyC | c | Alt+C | | Alt+C | alt+c | Alt+C | alt+[KeyC] | | +| Ctrl+Alt+KeyC | c | Ctrl+Alt+C | | Ctrl+Alt+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | +| Shift+Alt+KeyC | C | Shift+Alt+C | | Shift+Alt+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | +| Ctrl+Shift+Alt+KeyC | C | Ctrl+Shift+Alt+C | | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyD | d | D | | D | d | D | [KeyD] | | +| Ctrl+KeyD | d | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | +| Shift+KeyD | D | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | +| Ctrl+Shift+KeyD | D | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | +| Alt+KeyD | d | Alt+D | | Alt+D | alt+d | Alt+D | alt+[KeyD] | | +| Ctrl+Alt+KeyD | d | Ctrl+Alt+D | | Ctrl+Alt+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | +| Shift+Alt+KeyD | D | Shift+Alt+D | | Shift+Alt+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | +| Ctrl+Shift+Alt+KeyD | D | Ctrl+Shift+Alt+D | | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyE | e | E | | E | e | E | [KeyE] | | +| Ctrl+KeyE | e | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | +| Shift+KeyE | E | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | +| Ctrl+Shift+KeyE | E | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | +| Alt+KeyE | e | Alt+E | | Alt+E | alt+e | Alt+E | alt+[KeyE] | | +| Ctrl+Alt+KeyE | e | Ctrl+Alt+E | | Ctrl+Alt+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | +| Shift+Alt+KeyE | E | Shift+Alt+E | | Shift+Alt+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | +| Ctrl+Shift+Alt+KeyE | E | Ctrl+Shift+Alt+E | | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyF | f | F | | F | f | F | [KeyF] | | +| Ctrl+KeyF | f | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | +| Shift+KeyF | F | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | +| Ctrl+Shift+KeyF | F | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | +| Alt+KeyF | f | Alt+F | | Alt+F | alt+f | Alt+F | alt+[KeyF] | | +| Ctrl+Alt+KeyF | f | Ctrl+Alt+F | | Ctrl+Alt+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | +| Shift+Alt+KeyF | F | Shift+Alt+F | | Shift+Alt+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | +| Ctrl+Shift+Alt+KeyF | F | Ctrl+Shift+Alt+F | | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyG | g | G | | G | g | G | [KeyG] | | +| Ctrl+KeyG | g | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | +| Shift+KeyG | G | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | +| Ctrl+Shift+KeyG | G | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | +| Alt+KeyG | g | Alt+G | | Alt+G | alt+g | Alt+G | alt+[KeyG] | | +| Ctrl+Alt+KeyG | g | Ctrl+Alt+G | | Ctrl+Alt+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | +| Shift+Alt+KeyG | G | Shift+Alt+G | | Shift+Alt+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | +| Ctrl+Shift+Alt+KeyG | G | Ctrl+Shift+Alt+G | | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyH | h | H | | H | h | H | [KeyH] | | +| Ctrl+KeyH | h | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | +| Shift+KeyH | H | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | +| Ctrl+Shift+KeyH | H | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | +| Alt+KeyH | h | Alt+H | | Alt+H | alt+h | Alt+H | alt+[KeyH] | | +| Ctrl+Alt+KeyH | h | Ctrl+Alt+H | | Ctrl+Alt+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | +| Shift+Alt+KeyH | H | Shift+Alt+H | | Shift+Alt+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | +| Ctrl+Shift+Alt+KeyH | H | Ctrl+Shift+Alt+H | | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyI | i | I | | I | i | I | [KeyI] | | +| Ctrl+KeyI | i | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | +| Shift+KeyI | I | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | +| Ctrl+Shift+KeyI | I | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | +| Alt+KeyI | i | Alt+I | | Alt+I | alt+i | Alt+I | alt+[KeyI] | | +| Ctrl+Alt+KeyI | i | Ctrl+Alt+I | | Ctrl+Alt+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | +| Shift+Alt+KeyI | I | Shift+Alt+I | | Shift+Alt+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | +| Ctrl+Shift+Alt+KeyI | I | Ctrl+Shift+Alt+I | | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyJ | j | J | | J | j | J | [KeyJ] | | +| Ctrl+KeyJ | j | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | +| Shift+KeyJ | J | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | +| Ctrl+Shift+KeyJ | J | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | +| Alt+KeyJ | j | Alt+J | | Alt+J | alt+j | Alt+J | alt+[KeyJ] | | +| Ctrl+Alt+KeyJ | j | Ctrl+Alt+J | | Ctrl+Alt+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | +| Shift+Alt+KeyJ | J | Shift+Alt+J | | Shift+Alt+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | +| Ctrl+Shift+Alt+KeyJ | J | Ctrl+Shift+Alt+J | | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyK | k | K | | K | k | K | [KeyK] | | +| Ctrl+KeyK | k | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | +| Shift+KeyK | K | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | +| Ctrl+Shift+KeyK | K | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | +| Alt+KeyK | k | Alt+K | | Alt+K | alt+k | Alt+K | alt+[KeyK] | | +| Ctrl+Alt+KeyK | k | Ctrl+Alt+K | | Ctrl+Alt+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | +| Shift+Alt+KeyK | K | Shift+Alt+K | | Shift+Alt+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | +| Ctrl+Shift+Alt+KeyK | K | Ctrl+Shift+Alt+K | | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyL | l | L | | L | l | L | [KeyL] | | +| Ctrl+KeyL | l | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | +| Shift+KeyL | L | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | +| Ctrl+Shift+KeyL | L | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | +| Alt+KeyL | l | Alt+L | | Alt+L | alt+l | Alt+L | alt+[KeyL] | | +| Ctrl+Alt+KeyL | l | Ctrl+Alt+L | | Ctrl+Alt+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | +| Shift+Alt+KeyL | L | Shift+Alt+L | | Shift+Alt+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | +| Ctrl+Shift+Alt+KeyL | L | Ctrl+Shift+Alt+L | | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyM | m | M | | M | m | M | [KeyM] | | +| Ctrl+KeyM | m | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | +| Shift+KeyM | M | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | +| Ctrl+Shift+KeyM | M | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | +| Alt+KeyM | m | Alt+M | | Alt+M | alt+m | Alt+M | alt+[KeyM] | | +| Ctrl+Alt+KeyM | m | Ctrl+Alt+M | | Ctrl+Alt+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | +| Shift+Alt+KeyM | M | Shift+Alt+M | | Shift+Alt+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | +| Ctrl+Shift+Alt+KeyM | M | Ctrl+Shift+Alt+M | | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyN | n | N | | N | n | N | [KeyN] | | +| Ctrl+KeyN | n | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | +| Shift+KeyN | N | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | +| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | +| Alt+KeyN | n | Alt+N | | Alt+N | alt+n | Alt+N | alt+[KeyN] | | +| Ctrl+Alt+KeyN | n | Ctrl+Alt+N | | Ctrl+Alt+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | +| Shift+Alt+KeyN | N | Shift+Alt+N | | Shift+Alt+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | +| Ctrl+Shift+Alt+KeyN | N | Ctrl+Shift+Alt+N | | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyO | o | O | | O | o | O | [KeyO] | | +| Ctrl+KeyO | o | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | +| Shift+KeyO | O | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | +| Ctrl+Shift+KeyO | O | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | +| Alt+KeyO | o | Alt+O | | Alt+O | alt+o | Alt+O | alt+[KeyO] | | +| Ctrl+Alt+KeyO | o | Ctrl+Alt+O | | Ctrl+Alt+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | +| Shift+Alt+KeyO | O | Shift+Alt+O | | Shift+Alt+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | +| Ctrl+Shift+Alt+KeyO | O | Ctrl+Shift+Alt+O | | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyP | p | P | | P | p | P | [KeyP] | | +| Ctrl+KeyP | p | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | +| Shift+KeyP | P | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | +| Ctrl+Shift+KeyP | P | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | +| Alt+KeyP | p | Alt+P | | Alt+P | alt+p | Alt+P | alt+[KeyP] | | +| Ctrl+Alt+KeyP | p | Ctrl+Alt+P | | Ctrl+Alt+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | +| Shift+Alt+KeyP | P | Shift+Alt+P | | Shift+Alt+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | +| Ctrl+Shift+Alt+KeyP | P | Ctrl+Shift+Alt+P | | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyQ | q | Q | | Q | q | Q | [KeyQ] | | +| Ctrl+KeyQ | q | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | +| Shift+KeyQ | Q | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | +| Ctrl+Shift+KeyQ | Q | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | +| Alt+KeyQ | q | Alt+Q | | Alt+Q | alt+q | Alt+Q | alt+[KeyQ] | | +| Ctrl+Alt+KeyQ | q | Ctrl+Alt+Q | | Ctrl+Alt+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | +| Shift+Alt+KeyQ | Q | Shift+Alt+Q | | Shift+Alt+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | +| Ctrl+Shift+Alt+KeyQ | Q | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyR | r | R | | R | r | R | [KeyR] | | +| Ctrl+KeyR | r | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | +| Shift+KeyR | R | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | +| Ctrl+Shift+KeyR | R | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | +| Alt+KeyR | r | Alt+R | | Alt+R | alt+r | Alt+R | alt+[KeyR] | | +| Ctrl+Alt+KeyR | r | Ctrl+Alt+R | | Ctrl+Alt+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | +| Shift+Alt+KeyR | R | Shift+Alt+R | | Shift+Alt+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | +| Ctrl+Shift+Alt+KeyR | R | Ctrl+Shift+Alt+R | | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyS | s | S | | S | s | S | [KeyS] | | +| Ctrl+KeyS | s | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | +| Shift+KeyS | S | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | +| Ctrl+Shift+KeyS | S | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | +| Alt+KeyS | s | Alt+S | | Alt+S | alt+s | Alt+S | alt+[KeyS] | | +| Ctrl+Alt+KeyS | s | Ctrl+Alt+S | | Ctrl+Alt+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | +| Shift+Alt+KeyS | S | Shift+Alt+S | | Shift+Alt+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | +| Ctrl+Shift+Alt+KeyS | S | Ctrl+Shift+Alt+S | | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyT | t | T | | T | t | T | [KeyT] | | +| Ctrl+KeyT | t | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | +| Shift+KeyT | T | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | +| Ctrl+Shift+KeyT | T | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | +| Alt+KeyT | t | Alt+T | | Alt+T | alt+t | Alt+T | alt+[KeyT] | | +| Ctrl+Alt+KeyT | t | Ctrl+Alt+T | | Ctrl+Alt+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | +| Shift+Alt+KeyT | T | Shift+Alt+T | | Shift+Alt+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | +| Ctrl+Shift+Alt+KeyT | T | Ctrl+Shift+Alt+T | | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyU | u | U | | U | u | U | [KeyU] | | +| Ctrl+KeyU | u | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | +| Shift+KeyU | U | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | +| Ctrl+Shift+KeyU | U | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | +| Alt+KeyU | u | Alt+U | | Alt+U | alt+u | Alt+U | alt+[KeyU] | | +| Ctrl+Alt+KeyU | u | Ctrl+Alt+U | | Ctrl+Alt+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | +| Shift+Alt+KeyU | U | Shift+Alt+U | | Shift+Alt+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | +| Ctrl+Shift+Alt+KeyU | U | Ctrl+Shift+Alt+U | | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyV | v | V | | V | v | V | [KeyV] | | +| Ctrl+KeyV | v | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | +| Shift+KeyV | V | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | +| Ctrl+Shift+KeyV | V | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | +| Alt+KeyV | v | Alt+V | | Alt+V | alt+v | Alt+V | alt+[KeyV] | | +| Ctrl+Alt+KeyV | v | Ctrl+Alt+V | | Ctrl+Alt+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | +| Shift+Alt+KeyV | V | Shift+Alt+V | | Shift+Alt+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | +| Ctrl+Shift+Alt+KeyV | V | Ctrl+Shift+Alt+V | | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyW | w | W | | W | w | W | [KeyW] | | +| Ctrl+KeyW | w | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | +| Shift+KeyW | W | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | +| Ctrl+Shift+KeyW | W | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | +| Alt+KeyW | w | Alt+W | | Alt+W | alt+w | Alt+W | alt+[KeyW] | | +| Ctrl+Alt+KeyW | w | Ctrl+Alt+W | | Ctrl+Alt+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | +| Shift+Alt+KeyW | W | Shift+Alt+W | | Shift+Alt+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | +| Ctrl+Shift+Alt+KeyW | W | Ctrl+Shift+Alt+W | | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyX | x | X | | X | x | X | [KeyX] | | +| Ctrl+KeyX | x | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | +| Shift+KeyX | X | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | +| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | +| Alt+KeyX | x | Alt+X | | Alt+X | alt+x | Alt+X | alt+[KeyX] | | +| Ctrl+Alt+KeyX | x | Ctrl+Alt+X | | Ctrl+Alt+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | +| Shift+Alt+KeyX | X | Shift+Alt+X | | Shift+Alt+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | +| Ctrl+Shift+Alt+KeyX | X | Ctrl+Shift+Alt+X | | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyY | y | Y | | Y | y | Y | [KeyY] | | +| Ctrl+KeyY | y | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyY] | | +| Shift+KeyY | Y | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyY] | | +| Ctrl+Shift+KeyY | Y | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyY] | | +| Alt+KeyY | y | Alt+Y | | Alt+Y | alt+y | Alt+Y | alt+[KeyY] | | +| Ctrl+Alt+KeyY | y | Ctrl+Alt+Y | | Ctrl+Alt+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyY] | | +| Shift+Alt+KeyY | Y | Shift+Alt+Y | | Shift+Alt+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyY] | | +| Ctrl+Shift+Alt+KeyY | Y | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyY] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyZ | z | Z | | Z | z | Z | [KeyZ] | | +| Ctrl+KeyZ | z | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyZ] | | +| Shift+KeyZ | Z | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyZ] | | +| Ctrl+Shift+KeyZ | Z | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyZ] | | +| Alt+KeyZ | z | Alt+Z | | Alt+Z | alt+z | Alt+Z | alt+[KeyZ] | | +| Ctrl+Alt+KeyZ | z | Ctrl+Alt+Z | | Ctrl+Alt+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyZ] | | +| Shift+Alt+KeyZ | Z | Shift+Alt+Z | | Shift+Alt+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyZ] | | +| Ctrl+Shift+Alt+KeyZ | Z | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyZ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit1 | 1 | 1 | | 1 | 1 | 1 | [Digit1] | | +| Ctrl+Digit1 | 1 | Ctrl+1 | | Ctrl+1 | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | | +| Shift+Digit1 | ! | Shift+1 | | Shift+1 | shift+1 | Shift+1 | shift+[Digit1] | | +| Ctrl+Shift+Digit1 | ! | Ctrl+Shift+1 | | Ctrl+Shift+1 | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | | +| Alt+Digit1 | 1 | Alt+1 | | Alt+1 | alt+1 | Alt+1 | alt+[Digit1] | | +| Ctrl+Alt+Digit1 | 1 | Ctrl+Alt+1 | | Ctrl+Alt+1 | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | | +| Shift+Alt+Digit1 | ! | Shift+Alt+1 | | Shift+Alt+1 | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | | +| Ctrl+Shift+Alt+Digit1 | ! | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit2 | 2 | 2 | | 2 | 2 | 2 | [Digit2] | | +| Ctrl+Digit2 | 2 | Ctrl+2 | | Ctrl+2 | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | | +| Shift+Digit2 | @ | Shift+2 | | Shift+2 | shift+2 | Shift+2 | shift+[Digit2] | | +| Ctrl+Shift+Digit2 | @ | Ctrl+Shift+2 | | Ctrl+Shift+2 | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | | +| Alt+Digit2 | 2 | Alt+2 | | Alt+2 | alt+2 | Alt+2 | alt+[Digit2] | | +| Ctrl+Alt+Digit2 | 2 | Ctrl+Alt+2 | | Ctrl+Alt+2 | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | | +| Shift+Alt+Digit2 | @ | Shift+Alt+2 | | Shift+Alt+2 | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | | +| Ctrl+Shift+Alt+Digit2 | @ | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit3 | 3 | 3 | | 3 | 3 | 3 | [Digit3] | | +| Ctrl+Digit3 | 3 | Ctrl+3 | | Ctrl+3 | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | | +| Shift+Digit3 | # | Shift+3 | | Shift+3 | shift+3 | Shift+3 | shift+[Digit3] | | +| Ctrl+Shift+Digit3 | # | Ctrl+Shift+3 | | Ctrl+Shift+3 | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | | +| Alt+Digit3 | 3 | Alt+3 | | Alt+3 | alt+3 | Alt+3 | alt+[Digit3] | | +| Ctrl+Alt+Digit3 | 3 | Ctrl+Alt+3 | | Ctrl+Alt+3 | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | | +| Shift+Alt+Digit3 | # | Shift+Alt+3 | | Shift+Alt+3 | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | | +| Ctrl+Shift+Alt+Digit3 | # | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit4 | 4 | 4 | | 4 | 4 | 4 | [Digit4] | | +| Ctrl+Digit4 | 4 | Ctrl+4 | | Ctrl+4 | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | | +| Shift+Digit4 | $ | Shift+4 | | Shift+4 | shift+4 | Shift+4 | shift+[Digit4] | | +| Ctrl+Shift+Digit4 | $ | Ctrl+Shift+4 | | Ctrl+Shift+4 | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | | +| Alt+Digit4 | 4 | Alt+4 | | Alt+4 | alt+4 | Alt+4 | alt+[Digit4] | | +| Ctrl+Alt+Digit4 | 4 | Ctrl+Alt+4 | | Ctrl+Alt+4 | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | | +| Shift+Alt+Digit4 | $ | Shift+Alt+4 | | Shift+Alt+4 | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | | +| Ctrl+Shift+Alt+Digit4 | $ | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit5 | 5 | 5 | | 5 | 5 | 5 | [Digit5] | | +| Ctrl+Digit5 | 5 | Ctrl+5 | | Ctrl+5 | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | | +| Shift+Digit5 | % | Shift+5 | | Shift+5 | shift+5 | Shift+5 | shift+[Digit5] | | +| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+5 | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | | +| Alt+Digit5 | 5 | Alt+5 | | Alt+5 | alt+5 | Alt+5 | alt+[Digit5] | | +| Ctrl+Alt+Digit5 | 5 | Ctrl+Alt+5 | | Ctrl+Alt+5 | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | | +| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Alt+5 | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | | +| Ctrl+Shift+Alt+Digit5 | % | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit6 | 6 | 6 | | 6 | 6 | 6 | [Digit6] | | +| Ctrl+Digit6 | 6 | Ctrl+6 | | Ctrl+6 | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | | +| Shift+Digit6 | ^ | Shift+6 | | Shift+6 | shift+6 | Shift+6 | shift+[Digit6] | | +| Ctrl+Shift+Digit6 | ^ | Ctrl+Shift+6 | | Ctrl+Shift+6 | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | | +| Alt+Digit6 | 6 | Alt+6 | | Alt+6 | alt+6 | Alt+6 | alt+[Digit6] | | +| Ctrl+Alt+Digit6 | 6 | Ctrl+Alt+6 | | Ctrl+Alt+6 | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | | +| Shift+Alt+Digit6 | ^ | Shift+Alt+6 | | Shift+Alt+6 | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | | +| Ctrl+Shift+Alt+Digit6 | ^ | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit7 | 7 | 7 | | 7 | 7 | 7 | [Digit7] | | +| Ctrl+Digit7 | 7 | Ctrl+7 | | Ctrl+7 | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | | +| Shift+Digit7 | & | Shift+7 | | Shift+7 | shift+7 | Shift+7 | shift+[Digit7] | | +| Ctrl+Shift+Digit7 | & | Ctrl+Shift+7 | | Ctrl+Shift+7 | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | | +| Alt+Digit7 | 7 | Alt+7 | | Alt+7 | alt+7 | Alt+7 | alt+[Digit7] | | +| Ctrl+Alt+Digit7 | 7 | Ctrl+Alt+7 | | Ctrl+Alt+7 | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | | +| Shift+Alt+Digit7 | & | Shift+Alt+7 | | Shift+Alt+7 | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | | +| Ctrl+Shift+Alt+Digit7 | & | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit8 | 8 | 8 | | 8 | 8 | 8 | [Digit8] | | +| Ctrl+Digit8 | 8 | Ctrl+8 | | Ctrl+8 | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | | +| Shift+Digit8 | * | Shift+8 | | Shift+8 | shift+8 | Shift+8 | shift+[Digit8] | | +| Ctrl+Shift+Digit8 | * | Ctrl+Shift+8 | | Ctrl+Shift+8 | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | | +| Alt+Digit8 | 8 | Alt+8 | | Alt+8 | alt+8 | Alt+8 | alt+[Digit8] | | +| Ctrl+Alt+Digit8 | 8 | Ctrl+Alt+8 | | Ctrl+Alt+8 | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | | +| Shift+Alt+Digit8 | * | Shift+Alt+8 | | Shift+Alt+8 | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | | +| Ctrl+Shift+Alt+Digit8 | * | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit9 | 9 | 9 | | 9 | 9 | 9 | [Digit9] | | +| Ctrl+Digit9 | 9 | Ctrl+9 | | Ctrl+9 | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | | +| Shift+Digit9 | ( | Shift+9 | | Shift+9 | shift+9 | Shift+9 | shift+[Digit9] | | +| Ctrl+Shift+Digit9 | ( | Ctrl+Shift+9 | | Ctrl+Shift+9 | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | | +| Alt+Digit9 | 9 | Alt+9 | | Alt+9 | alt+9 | Alt+9 | alt+[Digit9] | | +| Ctrl+Alt+Digit9 | 9 | Ctrl+Alt+9 | | Ctrl+Alt+9 | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | | +| Shift+Alt+Digit9 | ( | Shift+Alt+9 | | Shift+Alt+9 | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | | +| Ctrl+Shift+Alt+Digit9 | ( | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit0 | 0 | 0 | | 0 | 0 | 0 | [Digit0] | | +| Ctrl+Digit0 | 0 | Ctrl+0 | | Ctrl+0 | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | | +| Shift+Digit0 | ) | Shift+0 | | Shift+0 | shift+0 | Shift+0 | shift+[Digit0] | | +| Ctrl+Shift+Digit0 | ) | Ctrl+Shift+0 | | Ctrl+Shift+0 | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | | +| Alt+Digit0 | 0 | Alt+0 | | Alt+0 | alt+0 | Alt+0 | alt+[Digit0] | | +| Ctrl+Alt+Digit0 | 0 | Ctrl+Alt+0 | | Ctrl+Alt+0 | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | | +| Shift+Alt+Digit0 | ) | Shift+Alt+0 | | Shift+Alt+0 | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | | +| Ctrl+Shift+Alt+Digit0 | ) | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Minus | - | - | | - | - | - | [Minus] | | +| Ctrl+Minus | - | Ctrl+- | | Ctrl+- | ctrl+- | Ctrl+- | ctrl+[Minus] | | +| Shift+Minus | _ | Shift+- | | Shift+- | shift+- | Shift+- | shift+[Minus] | | +| Ctrl+Shift+Minus | _ | Ctrl+Shift+- | | Ctrl+Shift+- | ctrl+shift+- | Ctrl+Shift+- | ctrl+shift+[Minus] | | +| Alt+Minus | - | Alt+- | | Alt+- | alt+- | Alt+- | alt+[Minus] | | +| Ctrl+Alt+Minus | - | Ctrl+Alt+- | | Ctrl+Alt+- | ctrl+alt+- | Ctrl+Alt+- | ctrl+alt+[Minus] | | +| Shift+Alt+Minus | _ | Shift+Alt+- | | Shift+Alt+- | shift+alt+- | Shift+Alt+- | shift+alt+[Minus] | | +| Ctrl+Shift+Alt+Minus | _ | Ctrl+Shift+Alt+- | | Ctrl+Shift+Alt+- | ctrl+shift+alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+[Minus] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Equal | = | = | | = | = | = | [Equal] | | +| Ctrl+Equal | = | Ctrl+= | | Ctrl+= | ctrl+= | Ctrl+= | ctrl+[Equal] | | +| Shift+Equal | + | Shift+= | | Shift+= | shift+= | Shift+= | shift+[Equal] | | +| Ctrl+Shift+Equal | + | Ctrl+Shift+= | | Ctrl+Shift+= | ctrl+shift+= | Ctrl+Shift+= | ctrl+shift+[Equal] | | +| Alt+Equal | = | Alt+= | | Alt+= | alt+= | Alt+= | alt+[Equal] | | +| Ctrl+Alt+Equal | = | Ctrl+Alt+= | | Ctrl+Alt+= | ctrl+alt+= | Ctrl+Alt+= | ctrl+alt+[Equal] | | +| Shift+Alt+Equal | + | Shift+Alt+= | | Shift+Alt+= | shift+alt+= | Shift+Alt+= | shift+alt+[Equal] | | +| Ctrl+Shift+Alt+Equal | + | Ctrl+Shift+Alt+= | | Ctrl+Shift+Alt+= | ctrl+shift+alt+= | Ctrl+Shift+Alt+= | ctrl+shift+alt+[Equal] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketLeft | [ | [ | | [ | [ | [ | [BracketLeft] | | +| Ctrl+BracketLeft | [ | Ctrl+[ | | Ctrl+[ | ctrl+[ | Ctrl+[ | ctrl+[BracketLeft] | | +| Shift+BracketLeft | { | Shift+[ | | Shift+[ | shift+[ | Shift+[ | shift+[BracketLeft] | | +| Ctrl+Shift+BracketLeft | { | Ctrl+Shift+[ | | Ctrl+Shift+[ | ctrl+shift+[ | Ctrl+Shift+[ | ctrl+shift+[BracketLeft] | | +| Alt+BracketLeft | [ | Alt+[ | | Alt+[ | alt+[ | Alt+[ | alt+[BracketLeft] | | +| Ctrl+Alt+BracketLeft | [ | Ctrl+Alt+[ | | Ctrl+Alt+[ | ctrl+alt+[ | Ctrl+Alt+[ | ctrl+alt+[BracketLeft] | | +| Shift+Alt+BracketLeft | { | Shift+Alt+[ | | Shift+Alt+[ | shift+alt+[ | Shift+Alt+[ | shift+alt+[BracketLeft] | | +| Ctrl+Shift+Alt+BracketLeft | { | Ctrl+Shift+Alt+[ | | Ctrl+Shift+Alt+[ | ctrl+shift+alt+[ | Ctrl+Shift+Alt+[ | ctrl+shift+alt+[BracketLeft] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketRight | ] | ] | | ] | ] | ] | [BracketRight] | | +| Ctrl+BracketRight | ] | Ctrl+] | | Ctrl+] | ctrl+] | Ctrl+] | ctrl+[BracketRight] | | +| Shift+BracketRight | } | Shift+] | | Shift+] | shift+] | Shift+] | shift+[BracketRight] | | +| Ctrl+Shift+BracketRight | } | Ctrl+Shift+] | | Ctrl+Shift+] | ctrl+shift+] | Ctrl+Shift+] | ctrl+shift+[BracketRight] | | +| Alt+BracketRight | ] | Alt+] | | Alt+] | alt+] | Alt+] | alt+[BracketRight] | | +| Ctrl+Alt+BracketRight | ] | Ctrl+Alt+] | | Ctrl+Alt+] | ctrl+alt+] | Ctrl+Alt+] | ctrl+alt+[BracketRight] | | +| Shift+Alt+BracketRight | } | Shift+Alt+] | | Shift+Alt+] | shift+alt+] | Shift+Alt+] | shift+alt+[BracketRight] | | +| Ctrl+Shift+Alt+BracketRight | } | Ctrl+Shift+Alt+] | | Ctrl+Shift+Alt+] | ctrl+shift+alt+] | Ctrl+Shift+Alt+] | ctrl+shift+alt+[BracketRight] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backslash | \ | \ | | \ | \ | \ | [Backslash] | | +| Ctrl+Backslash | \ | Ctrl+\ | | Ctrl+\ | ctrl+\ | Ctrl+\ | ctrl+[Backslash] | | +| Shift+Backslash | | | Shift+\ | 1 | Shift+\ | shift+\ | Shift+\ | shift+[Backslash] | | +| Ctrl+Shift+Backslash | | | Ctrl+Shift+\ | | Ctrl+Shift+\ | ctrl+shift+\ | Ctrl+Shift+\ | ctrl+shift+[Backslash] | | +| Alt+Backslash | \ | Alt+\ | | Alt+\ | alt+\ | Alt+\ | alt+[Backslash] | | +| Ctrl+Alt+Backslash | \ | Ctrl+Alt+\ | | Ctrl+Alt+\ | ctrl+alt+\ | Ctrl+Alt+\ | ctrl+alt+[Backslash] | | +| Shift+Alt+Backslash | | | Shift+Alt+\ | | Shift+Alt+\ | shift+alt+\ | Shift+Alt+\ | shift+alt+[Backslash] | | +| Ctrl+Shift+Alt+Backslash | | | Ctrl+Shift+Alt+\ | | Ctrl+Shift+Alt+\ | ctrl+shift+alt+\ | Ctrl+Shift+Alt+\ | ctrl+shift+alt+[Backslash] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlHash | --- | | | null | null | null | null | | +| Ctrl+IntlHash | --- | | | null | null | null | null | | +| Shift+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | +| Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | +| Shift+Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Semicolon | ; | ; | | ; | ; | ; | [Semicolon] | | +| Ctrl+Semicolon | ; | Ctrl+; | | Ctrl+; | ctrl+; | Ctrl+; | ctrl+[Semicolon] | | +| Shift+Semicolon | : | Shift+; | | Shift+; | shift+; | Shift+; | shift+[Semicolon] | | +| Ctrl+Shift+Semicolon | : | Ctrl+Shift+; | | Ctrl+Shift+; | ctrl+shift+; | Ctrl+Shift+; | ctrl+shift+[Semicolon] | | +| Alt+Semicolon | ; | Alt+; | | Alt+; | alt+; | Alt+; | alt+[Semicolon] | | +| Ctrl+Alt+Semicolon | ; | Ctrl+Alt+; | | Ctrl+Alt+; | ctrl+alt+; | Ctrl+Alt+; | ctrl+alt+[Semicolon] | | +| Shift+Alt+Semicolon | : | Shift+Alt+; | | Shift+Alt+; | shift+alt+; | Shift+Alt+; | shift+alt+[Semicolon] | | +| Ctrl+Shift+Alt+Semicolon | : | Ctrl+Shift+Alt+; | | Ctrl+Shift+Alt+; | ctrl+shift+alt+; | Ctrl+Shift+Alt+; | ctrl+shift+alt+[Semicolon] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Quote | ' | ' | | ' | ' | ' | [Quote] | | +| Ctrl+Quote | ' | Ctrl+' | | Ctrl+' | ctrl+' | Ctrl+' | ctrl+[Quote] | | +| Shift+Quote | " | Shift+' | | Shift+' | shift+' | Shift+' | shift+[Quote] | | +| Ctrl+Shift+Quote | " | Ctrl+Shift+' | | Ctrl+Shift+' | ctrl+shift+' | Ctrl+Shift+' | ctrl+shift+[Quote] | | +| Alt+Quote | ' | Alt+' | | Alt+' | alt+' | Alt+' | alt+[Quote] | | +| Ctrl+Alt+Quote | ' | Ctrl+Alt+' | | Ctrl+Alt+' | ctrl+alt+' | Ctrl+Alt+' | ctrl+alt+[Quote] | | +| Shift+Alt+Quote | " | Shift+Alt+' | | Shift+Alt+' | shift+alt+' | Shift+Alt+' | shift+alt+[Quote] | | +| Ctrl+Shift+Alt+Quote | " | Ctrl+Shift+Alt+' | | Ctrl+Shift+Alt+' | ctrl+shift+alt+' | Ctrl+Shift+Alt+' | ctrl+shift+alt+[Quote] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backquote | ` | ` | | ` | ` | ` | [Backquote] | | +| Ctrl+Backquote | ` | Ctrl+` | | Ctrl+` | ctrl+` | Ctrl+` | ctrl+[Backquote] | | +| Shift+Backquote | ~ | Shift+` | | Shift+` | shift+` | Shift+` | shift+[Backquote] | | +| Ctrl+Shift+Backquote | ~ | Ctrl+Shift+` | | Ctrl+Shift+` | ctrl+shift+` | Ctrl+Shift+` | ctrl+shift+[Backquote] | | +| Alt+Backquote | ` | Alt+` | | Alt+` | alt+` | Alt+` | alt+[Backquote] | | +| Ctrl+Alt+Backquote | ` | Ctrl+Alt+` | | Ctrl+Alt+` | ctrl+alt+` | Ctrl+Alt+` | ctrl+alt+[Backquote] | | +| Shift+Alt+Backquote | ~ | Shift+Alt+` | | Shift+Alt+` | shift+alt+` | Shift+Alt+` | shift+alt+[Backquote] | | +| Ctrl+Shift+Alt+Backquote | ~ | Ctrl+Shift+Alt+` | | Ctrl+Shift+Alt+` | ctrl+shift+alt+` | Ctrl+Shift+Alt+` | ctrl+shift+alt+[Backquote] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Comma | , | , | | , | , | , | [Comma] | | +| Ctrl+Comma | , | Ctrl+, | | Ctrl+, | ctrl+, | Ctrl+, | ctrl+[Comma] | | +| Shift+Comma | < | Shift+, | 1 | Shift+, | shift+, | Shift+, | shift+[Comma] | | +| Ctrl+Shift+Comma | < | Ctrl+Shift+, | 1 | Ctrl+Shift+, | ctrl+shift+, | Ctrl+Shift+, | ctrl+shift+[Comma] | | +| Alt+Comma | , | Alt+, | | Alt+, | alt+, | Alt+, | alt+[Comma] | | +| Ctrl+Alt+Comma | , | Ctrl+Alt+, | | Ctrl+Alt+, | ctrl+alt+, | Ctrl+Alt+, | ctrl+alt+[Comma] | | +| Shift+Alt+Comma | < | Shift+Alt+, | 1 | Shift+Alt+, | shift+alt+, | Shift+Alt+, | shift+alt+[Comma] | | +| Ctrl+Shift+Alt+Comma | < | Ctrl+Shift+Alt+, | | Ctrl+Shift+Alt+, | ctrl+shift+alt+, | Ctrl+Shift+Alt+, | ctrl+shift+alt+[Comma] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Period | . | . | | . | . | . | [Period] | | +| Ctrl+Period | . | Ctrl+. | | Ctrl+. | ctrl+. | Ctrl+. | ctrl+[Period] | | +| Shift+Period | > | Shift+. | 1 | Shift+. | shift+. | Shift+. | shift+[Period] | | +| Ctrl+Shift+Period | > | Ctrl+Shift+. | 1 | Ctrl+Shift+. | ctrl+shift+. | Ctrl+Shift+. | ctrl+shift+[Period] | | +| Alt+Period | . | Alt+. | | Alt+. | alt+. | Alt+. | alt+[Period] | | +| Ctrl+Alt+Period | . | Ctrl+Alt+. | | Ctrl+Alt+. | ctrl+alt+. | Ctrl+Alt+. | ctrl+alt+[Period] | | +| Shift+Alt+Period | > | Shift+Alt+. | 1 | Shift+Alt+. | shift+alt+. | Shift+Alt+. | shift+alt+[Period] | | +| Ctrl+Shift+Alt+Period | > | Ctrl+Shift+Alt+. | 1 | Ctrl+Shift+Alt+. | ctrl+shift+alt+. | Ctrl+Shift+Alt+. | ctrl+shift+alt+[Period] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Slash | / | / | | / | / | / | [Slash] | | +| Ctrl+Slash | / | Ctrl+/ | | Ctrl+/ | ctrl+/ | Ctrl+/ | ctrl+[Slash] | | +| Shift+Slash | ? | Shift+/ | | Shift+/ | shift+/ | Shift+/ | shift+[Slash] | | +| Ctrl+Shift+Slash | ? | Ctrl+Shift+/ | | Ctrl+Shift+/ | ctrl+shift+/ | Ctrl+Shift+/ | ctrl+shift+[Slash] | | +| Alt+Slash | / | Alt+/ | | Alt+/ | alt+/ | Alt+/ | alt+[Slash] | | +| Ctrl+Alt+Slash | / | Ctrl+Alt+/ | | Ctrl+Alt+/ | ctrl+alt+/ | Ctrl+Alt+/ | ctrl+alt+[Slash] | | +| Shift+Alt+Slash | ? | Shift+Alt+/ | | Shift+Alt+/ | shift+alt+/ | Shift+Alt+/ | shift+alt+[Slash] | | +| Ctrl+Shift+Alt+Slash | ? | Ctrl+Shift+Alt+/ | | Ctrl+Shift+Alt+/ | ctrl+shift+alt+/ | Ctrl+Shift+Alt+/ | ctrl+shift+alt+[Slash] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | +| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | +| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | +| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | +| Alt+ArrowUp | --- | Alt+UpArrow | | Alt+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | +| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Alt+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | +| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Alt+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | +| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | +| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | +| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | +| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | +| Alt+Numpad0 | --- | Alt+NumPad0 | | Alt+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | +| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | +| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Alt+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | +| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlBackslash | < | Shift+, | 2 | < | [IntlBackslash] | null | [IntlBackslash] | NO | +| Ctrl+IntlBackslash | < | Ctrl+Shift+, | 2 | Ctrl+< | ctrl+[IntlBackslash] | null | ctrl+[IntlBackslash] | NO | +| Shift+IntlBackslash | > | Shift+. | 2 | Shift+< | shift+[IntlBackslash] | null | shift+[IntlBackslash] | NO | +| Ctrl+Shift+IntlBackslash | > | Ctrl+Shift+. | 2 | Ctrl+Shift+< | ctrl+shift+[IntlBackslash] | null | ctrl+shift+[IntlBackslash] | NO | +| Alt+IntlBackslash | < | Shift+Alt+, | 2 | Alt+< | alt+[IntlBackslash] | null | alt+[IntlBackslash] | NO | +| Ctrl+Alt+IntlBackslash | | | Shift+\ | 2 | Ctrl+Alt+< | ctrl+alt+[IntlBackslash] | null | ctrl+alt+[IntlBackslash] | NO | +| Shift+Alt+IntlBackslash | > | Shift+Alt+. | 2 | Shift+Alt+< | shift+alt+[IntlBackslash] | null | shift+alt+[IntlBackslash] | NO | +| Ctrl+Shift+Alt+IntlBackslash | ¦ | Ctrl+Shift+Alt+. | 2 | Ctrl+Shift+Alt+< | ctrl+shift+alt+[IntlBackslash] | null | ctrl+shift+alt+[IntlBackslash] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | +| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | +| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | +| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | +| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | +| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | +| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | +| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | +| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | +| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | +| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | +| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | +| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | +| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | +| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/node/linux_ru.js b/src/vs/workbench/services/keybinding/test/node/linux_ru.js new file mode 100644 index 00000000000..950223704b6 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/linux_ru.js @@ -0,0 +1,1046 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +define({ + Sleep: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + WakeUp: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + KeyA: { + value: 'ф', + withShift: 'Ф', + withAltGr: 'ф', + withShiftAltGr: 'Ф' + }, + KeyB: { + value: 'и', + withShift: 'И', + withAltGr: 'и', + withShiftAltGr: 'И' + }, + KeyC: { + value: 'с', + withShift: 'С', + withAltGr: 'с', + withShiftAltGr: 'С' + }, + KeyD: { + value: 'в', + withShift: 'В', + withAltGr: 'в', + withShiftAltGr: 'В' + }, + KeyE: { + value: 'у', + withShift: 'У', + withAltGr: 'у', + withShiftAltGr: 'У' + }, + KeyF: { + value: 'а', + withShift: 'А', + withAltGr: 'а', + withShiftAltGr: 'А' + }, + KeyG: { + value: 'п', + withShift: 'П', + withAltGr: 'п', + withShiftAltGr: 'П' + }, + KeyH: { + value: 'р', + withShift: 'Р', + withAltGr: 'р', + withShiftAltGr: 'Р' + }, + KeyI: { + value: 'ш', + withShift: 'Ш', + withAltGr: 'ш', + withShiftAltGr: 'Ш' + }, + KeyJ: { + value: 'о', + withShift: 'О', + withAltGr: 'о', + withShiftAltGr: 'О' + }, + KeyK: { + value: 'л', + withShift: 'Л', + withAltGr: 'л', + withShiftAltGr: 'Л' + }, + KeyL: { + value: 'д', + withShift: 'Д', + withAltGr: 'д', + withShiftAltGr: 'Д' + }, + KeyM: { + value: 'ь', + withShift: 'Ь', + withAltGr: 'ь', + withShiftAltGr: 'Ь' + }, + KeyN: { + value: 'т', + withShift: 'Т', + withAltGr: 'т', + withShiftAltGr: 'Т' + }, + KeyO: { + value: 'щ', + withShift: 'Щ', + withAltGr: 'щ', + withShiftAltGr: 'Щ' + }, + KeyP: { + value: 'з', + withShift: 'З', + withAltGr: 'з', + withShiftAltGr: 'З' + }, + KeyQ: { + value: 'й', + withShift: 'Й', + withAltGr: 'й', + withShiftAltGr: 'Й' + }, + KeyR: { + value: 'к', + withShift: 'К', + withAltGr: 'к', + withShiftAltGr: 'К' + }, + KeyS: { + value: 'ы', + withShift: 'Ы', + withAltGr: 'ы', + withShiftAltGr: 'Ы' + }, + KeyT: { + value: 'е', + withShift: 'Е', + withAltGr: 'е', + withShiftAltGr: 'Е' + }, + KeyU: { + value: 'г', + withShift: 'Г', + withAltGr: 'г', + withShiftAltGr: 'Г' + }, + KeyV: { + value: 'м', + withShift: 'М', + withAltGr: 'м', + withShiftAltGr: 'М' + }, + KeyW: { + value: 'ц', + withShift: 'Ц', + withAltGr: 'ц', + withShiftAltGr: 'Ц' + }, + KeyX: { + value: 'ч', + withShift: 'Ч', + withAltGr: 'ч', + withShiftAltGr: 'Ч' + }, + KeyY: { + value: 'н', + withShift: 'Н', + withAltGr: 'н', + withShiftAltGr: 'Н' + }, + KeyZ: { + value: 'я', + withShift: 'Я', + withAltGr: 'я', + withShiftAltGr: 'Я' + }, + Digit1: { + value: '1', + withShift: '!', + withAltGr: '1', + withShiftAltGr: '!' + }, + Digit2: { + value: '2', + withShift: '"', + withAltGr: '2', + withShiftAltGr: '"' + }, + Digit3: { + value: '3', + withShift: '№', + withAltGr: '3', + withShiftAltGr: '№' + }, + Digit4: { + value: '4', + withShift: ';', + withAltGr: '4', + withShiftAltGr: ';' + }, + Digit5: { + value: '5', + withShift: '%', + withAltGr: '5', + withShiftAltGr: '%' + }, + Digit6: { + value: '6', + withShift: ':', + withAltGr: '6', + withShiftAltGr: ':' + }, + Digit7: { + value: '7', + withShift: '?', + withAltGr: '7', + withShiftAltGr: '?' + }, + Digit8: { + value: '8', + withShift: '*', + withAltGr: '8', + withShiftAltGr: '*' + }, + Digit9: { + value: '9', + withShift: '(', + withAltGr: '9', + withShiftAltGr: '(' + }, + Digit0: { + value: '0', + withShift: ')', + withAltGr: '0', + withShiftAltGr: ')' + }, + Enter: { + value: '\r', + withShift: '\r', + withAltGr: '\r', + withShiftAltGr: '\r' + }, + Escape: { + value: '\u001b', + withShift: '\u001b', + withAltGr: '\u001b', + withShiftAltGr: '\u001b' + }, + Backspace: { + value: '\b', + withShift: '\b', + withAltGr: '\b', + withShiftAltGr: '\b' + }, + Tab: { + value: '\t', + withShift: '', + withAltGr: '\t', + withShiftAltGr: '' + }, + Space: { + value: ' ', + withShift: ' ', + withAltGr: ' ', + withShiftAltGr: ' ' + }, + Minus: { + value: '-', + withShift: '_', + withAltGr: '-', + withShiftAltGr: '_' + }, + Equal: { + value: '=', + withShift: '+', + withAltGr: '=', + withShiftAltGr: '+' + }, + BracketLeft: { + value: 'х', + withShift: 'Х', + withAltGr: 'х', + withShiftAltGr: 'Х' + }, + BracketRight: { + value: 'ъ', + withShift: 'Ъ', + withAltGr: 'ъ', + withShiftAltGr: 'Ъ' + }, + Backslash: { + value: '\\', + withShift: '/', + withAltGr: '\\', + withShiftAltGr: '/' + }, + Semicolon: { + value: 'ж', + withShift: 'Ж', + withAltGr: 'ж', + withShiftAltGr: 'Ж' + }, + Quote: { + value: 'э', + withShift: 'Э', + withAltGr: 'э', + withShiftAltGr: 'Э' + }, + Backquote: { + value: 'ё', + withShift: 'Ё', + withAltGr: 'ё', + withShiftAltGr: 'Ё' + }, + Comma: { + value: 'б', + withShift: 'Б', + withAltGr: 'б', + withShiftAltGr: 'Б' + }, + Period: { + value: 'ю', + withShift: 'Ю', + withAltGr: 'ю', + withShiftAltGr: 'Ю' + }, + Slash: { + value: '.', + withShift: ',', + withAltGr: '.', + withShiftAltGr: ',' + }, + CapsLock: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F1: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F2: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F3: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F4: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F5: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F6: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F7: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F8: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F9: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F10: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F11: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F12: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PrintScreen: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ScrollLock: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Pause: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Insert: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Home: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PageUp: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Delete: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + End: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PageDown: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowRight: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowLeft: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowDown: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowUp: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumLock: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadDivide: { + value: '/', + withShift: '/', + withAltGr: '/', + withShiftAltGr: '/' + }, + NumpadMultiply: { + value: '*', + withShift: '*', + withAltGr: '*', + withShiftAltGr: '*' + }, + NumpadSubtract: { + value: '-', + withShift: '-', + withAltGr: '-', + withShiftAltGr: '-' + }, + NumpadAdd: { + value: '+', + withShift: '+', + withAltGr: '+', + withShiftAltGr: '+' + }, + NumpadEnter: { + value: '\r', + withShift: '\r', + withAltGr: '\r', + withShiftAltGr: '\r' + }, + Numpad1: { + value: '', + withShift: '1', + withAltGr: '', + withShiftAltGr: '1' + }, + Numpad2: { + value: '', + withShift: '2', + withAltGr: '', + withShiftAltGr: '2' + }, + Numpad3: { + value: '', + withShift: '3', + withAltGr: '', + withShiftAltGr: '3' + }, + Numpad4: { + value: '', + withShift: '4', + withAltGr: '', + withShiftAltGr: '4' + }, + Numpad5: { + value: '', + withShift: '5', + withAltGr: '', + withShiftAltGr: '5' + }, + Numpad6: { + value: '', + withShift: '6', + withAltGr: '', + withShiftAltGr: '6' + }, + Numpad7: { + value: '', + withShift: '7', + withAltGr: '', + withShiftAltGr: '7' + }, + Numpad8: { + value: '', + withShift: '8', + withAltGr: '', + withShiftAltGr: '8' + }, + Numpad9: { + value: '', + withShift: '9', + withAltGr: '', + withShiftAltGr: '9' + }, + Numpad0: { + value: '', + withShift: '0', + withAltGr: '', + withShiftAltGr: '0' + }, + NumpadDecimal: { + value: '', + withShift: ',', + withAltGr: '', + withShiftAltGr: ',' + }, + IntlBackslash: { + value: '/', + withShift: '|', + withAltGr: '|', + withShiftAltGr: '¦' + }, + ContextMenu: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Power: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadEqual: { + value: '=', + withShift: '=', + withAltGr: '=', + withShiftAltGr: '=' + }, + F13: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F14: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F15: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F16: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F17: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F18: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F19: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F20: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F21: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F22: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F23: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F24: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Open: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Help: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Select: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Again: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Undo: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Cut: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Copy: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Paste: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Find: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeMute: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeUp: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeDown: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadComma: { + value: '.', + withShift: '.', + withAltGr: '.', + withShiftAltGr: '.' + }, + IntlRo: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + KanaMode: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + IntlYen: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Convert: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NonConvert: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang1: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang2: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang3: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang4: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang5: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadParenLeft: { + value: '(', + withShift: '(', + withAltGr: '(', + withShiftAltGr: '(' + }, + NumpadParenRight: { + value: ')', + withShift: ')', + withAltGr: ')', + withShiftAltGr: ')' + }, + ControlLeft: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ShiftLeft: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AltLeft: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MetaLeft: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ControlRight: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ShiftRight: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AltRight: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MetaRight: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrightnessUp: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrightnessDown: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaPlay: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaRecord: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaFastForward: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaRewind: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaTrackNext: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaTrackPrevious: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaStop: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Eject: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaPlayPause: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaSelect: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchMail: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchApp2: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchApp1: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + SelectTask: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchScreenSaver: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserSearch: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserHome: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserBack: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserForward: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserStop: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserRefresh: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserFavorites: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MailReply: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MailForward: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MailSend: { + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + } +}); diff --git a/src/vs/workbench/services/keybinding/test/node/linux_ru.txt b/src/vs/workbench/services/keybinding/test/node/linux_ru.txt new file mode 100644 index 00000000000..389681ee995 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/linux_ru.txt @@ -0,0 +1,523 @@ +isUSStandard: false +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyA | ф | A | | A | a | A | [KeyA] | | +| Ctrl+KeyA | ф | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | +| Shift+KeyA | Ф | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | +| Ctrl+Shift+KeyA | Ф | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | +| Alt+KeyA | ф | Alt+A | | Alt+A | alt+a | Alt+A | alt+[KeyA] | | +| Ctrl+Alt+KeyA | ф | Ctrl+Alt+A | | Ctrl+Alt+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | +| Shift+Alt+KeyA | Ф | Shift+Alt+A | | Shift+Alt+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | +| Ctrl+Shift+Alt+KeyA | Ф | Ctrl+Shift+Alt+A | | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyB | и | B | | B | b | B | [KeyB] | | +| Ctrl+KeyB | и | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | +| Shift+KeyB | И | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | +| Ctrl+Shift+KeyB | И | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | +| Alt+KeyB | и | Alt+B | | Alt+B | alt+b | Alt+B | alt+[KeyB] | | +| Ctrl+Alt+KeyB | и | Ctrl+Alt+B | | Ctrl+Alt+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | +| Shift+Alt+KeyB | И | Shift+Alt+B | | Shift+Alt+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | +| Ctrl+Shift+Alt+KeyB | И | Ctrl+Shift+Alt+B | | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyC | с | C | | C | c | C | [KeyC] | | +| Ctrl+KeyC | с | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | +| Shift+KeyC | С | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | +| Ctrl+Shift+KeyC | С | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | +| Alt+KeyC | с | Alt+C | | Alt+C | alt+c | Alt+C | alt+[KeyC] | | +| Ctrl+Alt+KeyC | с | Ctrl+Alt+C | | Ctrl+Alt+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | +| Shift+Alt+KeyC | С | Shift+Alt+C | | Shift+Alt+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | +| Ctrl+Shift+Alt+KeyC | С | Ctrl+Shift+Alt+C | | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyD | в | D | | D | d | D | [KeyD] | | +| Ctrl+KeyD | в | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | +| Shift+KeyD | В | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | +| Ctrl+Shift+KeyD | В | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | +| Alt+KeyD | в | Alt+D | | Alt+D | alt+d | Alt+D | alt+[KeyD] | | +| Ctrl+Alt+KeyD | в | Ctrl+Alt+D | | Ctrl+Alt+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | +| Shift+Alt+KeyD | В | Shift+Alt+D | | Shift+Alt+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | +| Ctrl+Shift+Alt+KeyD | В | Ctrl+Shift+Alt+D | | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyE | у | E | | E | e | E | [KeyE] | | +| Ctrl+KeyE | у | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | +| Shift+KeyE | У | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | +| Ctrl+Shift+KeyE | У | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | +| Alt+KeyE | у | Alt+E | | Alt+E | alt+e | Alt+E | alt+[KeyE] | | +| Ctrl+Alt+KeyE | у | Ctrl+Alt+E | | Ctrl+Alt+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | +| Shift+Alt+KeyE | У | Shift+Alt+E | | Shift+Alt+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | +| Ctrl+Shift+Alt+KeyE | У | Ctrl+Shift+Alt+E | | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyF | а | F | | F | f | F | [KeyF] | | +| Ctrl+KeyF | а | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | +| Shift+KeyF | А | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | +| Ctrl+Shift+KeyF | А | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | +| Alt+KeyF | а | Alt+F | | Alt+F | alt+f | Alt+F | alt+[KeyF] | | +| Ctrl+Alt+KeyF | а | Ctrl+Alt+F | | Ctrl+Alt+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | +| Shift+Alt+KeyF | А | Shift+Alt+F | | Shift+Alt+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | +| Ctrl+Shift+Alt+KeyF | А | Ctrl+Shift+Alt+F | | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyG | п | G | | G | g | G | [KeyG] | | +| Ctrl+KeyG | п | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | +| Shift+KeyG | П | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | +| Ctrl+Shift+KeyG | П | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | +| Alt+KeyG | п | Alt+G | | Alt+G | alt+g | Alt+G | alt+[KeyG] | | +| Ctrl+Alt+KeyG | п | Ctrl+Alt+G | | Ctrl+Alt+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | +| Shift+Alt+KeyG | П | Shift+Alt+G | | Shift+Alt+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | +| Ctrl+Shift+Alt+KeyG | П | Ctrl+Shift+Alt+G | | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyH | р | H | | H | h | H | [KeyH] | | +| Ctrl+KeyH | р | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | +| Shift+KeyH | Р | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | +| Ctrl+Shift+KeyH | Р | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | +| Alt+KeyH | р | Alt+H | | Alt+H | alt+h | Alt+H | alt+[KeyH] | | +| Ctrl+Alt+KeyH | р | Ctrl+Alt+H | | Ctrl+Alt+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | +| Shift+Alt+KeyH | Р | Shift+Alt+H | | Shift+Alt+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | +| Ctrl+Shift+Alt+KeyH | Р | Ctrl+Shift+Alt+H | | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyI | ш | I | | I | i | I | [KeyI] | | +| Ctrl+KeyI | ш | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | +| Shift+KeyI | Ш | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | +| Ctrl+Shift+KeyI | Ш | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | +| Alt+KeyI | ш | Alt+I | | Alt+I | alt+i | Alt+I | alt+[KeyI] | | +| Ctrl+Alt+KeyI | ш | Ctrl+Alt+I | | Ctrl+Alt+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | +| Shift+Alt+KeyI | Ш | Shift+Alt+I | | Shift+Alt+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | +| Ctrl+Shift+Alt+KeyI | Ш | Ctrl+Shift+Alt+I | | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyJ | о | J | | J | j | J | [KeyJ] | | +| Ctrl+KeyJ | о | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | +| Shift+KeyJ | О | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | +| Ctrl+Shift+KeyJ | О | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | +| Alt+KeyJ | о | Alt+J | | Alt+J | alt+j | Alt+J | alt+[KeyJ] | | +| Ctrl+Alt+KeyJ | о | Ctrl+Alt+J | | Ctrl+Alt+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | +| Shift+Alt+KeyJ | О | Shift+Alt+J | | Shift+Alt+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | +| Ctrl+Shift+Alt+KeyJ | О | Ctrl+Shift+Alt+J | | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyK | л | K | | K | k | K | [KeyK] | | +| Ctrl+KeyK | л | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | +| Shift+KeyK | Л | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | +| Ctrl+Shift+KeyK | Л | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | +| Alt+KeyK | л | Alt+K | | Alt+K | alt+k | Alt+K | alt+[KeyK] | | +| Ctrl+Alt+KeyK | л | Ctrl+Alt+K | | Ctrl+Alt+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | +| Shift+Alt+KeyK | Л | Shift+Alt+K | | Shift+Alt+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | +| Ctrl+Shift+Alt+KeyK | Л | Ctrl+Shift+Alt+K | | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyL | д | L | | L | l | L | [KeyL] | | +| Ctrl+KeyL | д | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | +| Shift+KeyL | Д | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | +| Ctrl+Shift+KeyL | Д | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | +| Alt+KeyL | д | Alt+L | | Alt+L | alt+l | Alt+L | alt+[KeyL] | | +| Ctrl+Alt+KeyL | д | Ctrl+Alt+L | | Ctrl+Alt+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | +| Shift+Alt+KeyL | Д | Shift+Alt+L | | Shift+Alt+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | +| Ctrl+Shift+Alt+KeyL | Д | Ctrl+Shift+Alt+L | | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyM | ь | M | | M | m | M | [KeyM] | | +| Ctrl+KeyM | ь | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | +| Shift+KeyM | Ь | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | +| Ctrl+Shift+KeyM | Ь | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | +| Alt+KeyM | ь | Alt+M | | Alt+M | alt+m | Alt+M | alt+[KeyM] | | +| Ctrl+Alt+KeyM | ь | Ctrl+Alt+M | | Ctrl+Alt+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | +| Shift+Alt+KeyM | Ь | Shift+Alt+M | | Shift+Alt+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | +| Ctrl+Shift+Alt+KeyM | Ь | Ctrl+Shift+Alt+M | | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyN | т | N | | N | n | N | [KeyN] | | +| Ctrl+KeyN | т | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | +| Shift+KeyN | Т | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | +| Ctrl+Shift+KeyN | Т | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | +| Alt+KeyN | т | Alt+N | | Alt+N | alt+n | Alt+N | alt+[KeyN] | | +| Ctrl+Alt+KeyN | т | Ctrl+Alt+N | | Ctrl+Alt+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | +| Shift+Alt+KeyN | Т | Shift+Alt+N | | Shift+Alt+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | +| Ctrl+Shift+Alt+KeyN | Т | Ctrl+Shift+Alt+N | | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyO | щ | O | | O | o | O | [KeyO] | | +| Ctrl+KeyO | щ | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | +| Shift+KeyO | Щ | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | +| Ctrl+Shift+KeyO | Щ | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | +| Alt+KeyO | щ | Alt+O | | Alt+O | alt+o | Alt+O | alt+[KeyO] | | +| Ctrl+Alt+KeyO | щ | Ctrl+Alt+O | | Ctrl+Alt+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | +| Shift+Alt+KeyO | Щ | Shift+Alt+O | | Shift+Alt+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | +| Ctrl+Shift+Alt+KeyO | Щ | Ctrl+Shift+Alt+O | | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyP | з | P | | P | p | P | [KeyP] | | +| Ctrl+KeyP | з | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | +| Shift+KeyP | З | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | +| Ctrl+Shift+KeyP | З | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | +| Alt+KeyP | з | Alt+P | | Alt+P | alt+p | Alt+P | alt+[KeyP] | | +| Ctrl+Alt+KeyP | з | Ctrl+Alt+P | | Ctrl+Alt+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | +| Shift+Alt+KeyP | З | Shift+Alt+P | | Shift+Alt+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | +| Ctrl+Shift+Alt+KeyP | З | Ctrl+Shift+Alt+P | | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyQ | й | Q | | Q | q | Q | [KeyQ] | | +| Ctrl+KeyQ | й | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | +| Shift+KeyQ | Й | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | +| Ctrl+Shift+KeyQ | Й | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | +| Alt+KeyQ | й | Alt+Q | | Alt+Q | alt+q | Alt+Q | alt+[KeyQ] | | +| Ctrl+Alt+KeyQ | й | Ctrl+Alt+Q | | Ctrl+Alt+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | +| Shift+Alt+KeyQ | Й | Shift+Alt+Q | | Shift+Alt+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | +| Ctrl+Shift+Alt+KeyQ | Й | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyR | к | R | | R | r | R | [KeyR] | | +| Ctrl+KeyR | к | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | +| Shift+KeyR | К | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | +| Ctrl+Shift+KeyR | К | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | +| Alt+KeyR | к | Alt+R | | Alt+R | alt+r | Alt+R | alt+[KeyR] | | +| Ctrl+Alt+KeyR | к | Ctrl+Alt+R | | Ctrl+Alt+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | +| Shift+Alt+KeyR | К | Shift+Alt+R | | Shift+Alt+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | +| Ctrl+Shift+Alt+KeyR | К | Ctrl+Shift+Alt+R | | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyS | ы | S | | S | s | S | [KeyS] | | +| Ctrl+KeyS | ы | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | +| Shift+KeyS | Ы | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | +| Ctrl+Shift+KeyS | Ы | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | +| Alt+KeyS | ы | Alt+S | | Alt+S | alt+s | Alt+S | alt+[KeyS] | | +| Ctrl+Alt+KeyS | ы | Ctrl+Alt+S | | Ctrl+Alt+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | +| Shift+Alt+KeyS | Ы | Shift+Alt+S | | Shift+Alt+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | +| Ctrl+Shift+Alt+KeyS | Ы | Ctrl+Shift+Alt+S | | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyT | е | T | | T | t | T | [KeyT] | | +| Ctrl+KeyT | е | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | +| Shift+KeyT | Е | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | +| Ctrl+Shift+KeyT | Е | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | +| Alt+KeyT | е | Alt+T | | Alt+T | alt+t | Alt+T | alt+[KeyT] | | +| Ctrl+Alt+KeyT | е | Ctrl+Alt+T | | Ctrl+Alt+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | +| Shift+Alt+KeyT | Е | Shift+Alt+T | | Shift+Alt+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | +| Ctrl+Shift+Alt+KeyT | Е | Ctrl+Shift+Alt+T | | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyU | г | U | | U | u | U | [KeyU] | | +| Ctrl+KeyU | г | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | +| Shift+KeyU | Г | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | +| Ctrl+Shift+KeyU | Г | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | +| Alt+KeyU | г | Alt+U | | Alt+U | alt+u | Alt+U | alt+[KeyU] | | +| Ctrl+Alt+KeyU | г | Ctrl+Alt+U | | Ctrl+Alt+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | +| Shift+Alt+KeyU | Г | Shift+Alt+U | | Shift+Alt+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | +| Ctrl+Shift+Alt+KeyU | Г | Ctrl+Shift+Alt+U | | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyV | м | V | | V | v | V | [KeyV] | | +| Ctrl+KeyV | м | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | +| Shift+KeyV | М | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | +| Ctrl+Shift+KeyV | М | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | +| Alt+KeyV | м | Alt+V | | Alt+V | alt+v | Alt+V | alt+[KeyV] | | +| Ctrl+Alt+KeyV | м | Ctrl+Alt+V | | Ctrl+Alt+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | +| Shift+Alt+KeyV | М | Shift+Alt+V | | Shift+Alt+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | +| Ctrl+Shift+Alt+KeyV | М | Ctrl+Shift+Alt+V | | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyW | ц | W | | W | w | W | [KeyW] | | +| Ctrl+KeyW | ц | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | +| Shift+KeyW | Ц | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | +| Ctrl+Shift+KeyW | Ц | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | +| Alt+KeyW | ц | Alt+W | | Alt+W | alt+w | Alt+W | alt+[KeyW] | | +| Ctrl+Alt+KeyW | ц | Ctrl+Alt+W | | Ctrl+Alt+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | +| Shift+Alt+KeyW | Ц | Shift+Alt+W | | Shift+Alt+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | +| Ctrl+Shift+Alt+KeyW | Ц | Ctrl+Shift+Alt+W | | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyX | ч | X | | X | x | X | [KeyX] | | +| Ctrl+KeyX | ч | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | +| Shift+KeyX | Ч | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | +| Ctrl+Shift+KeyX | Ч | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | +| Alt+KeyX | ч | Alt+X | | Alt+X | alt+x | Alt+X | alt+[KeyX] | | +| Ctrl+Alt+KeyX | ч | Ctrl+Alt+X | | Ctrl+Alt+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | +| Shift+Alt+KeyX | Ч | Shift+Alt+X | | Shift+Alt+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | +| Ctrl+Shift+Alt+KeyX | Ч | Ctrl+Shift+Alt+X | | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyY | н | Y | | Y | y | Y | [KeyY] | | +| Ctrl+KeyY | н | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyY] | | +| Shift+KeyY | Н | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyY] | | +| Ctrl+Shift+KeyY | Н | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyY] | | +| Alt+KeyY | н | Alt+Y | | Alt+Y | alt+y | Alt+Y | alt+[KeyY] | | +| Ctrl+Alt+KeyY | н | Ctrl+Alt+Y | | Ctrl+Alt+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyY] | | +| Shift+Alt+KeyY | Н | Shift+Alt+Y | | Shift+Alt+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyY] | | +| Ctrl+Shift+Alt+KeyY | Н | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyY] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyZ | я | Z | | Z | z | Z | [KeyZ] | | +| Ctrl+KeyZ | я | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyZ] | | +| Shift+KeyZ | Я | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyZ] | | +| Ctrl+Shift+KeyZ | Я | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyZ] | | +| Alt+KeyZ | я | Alt+Z | | Alt+Z | alt+z | Alt+Z | alt+[KeyZ] | | +| Ctrl+Alt+KeyZ | я | Ctrl+Alt+Z | | Ctrl+Alt+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyZ] | | +| Shift+Alt+KeyZ | Я | Shift+Alt+Z | | Shift+Alt+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyZ] | | +| Ctrl+Shift+Alt+KeyZ | Я | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyZ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit1 | 1 | 1 | | 1 | 1 | 1 | [Digit1] | | +| Ctrl+Digit1 | 1 | Ctrl+1 | | Ctrl+1 | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | | +| Shift+Digit1 | ! | Shift+1 | | Shift+1 | shift+1 | Shift+1 | shift+[Digit1] | | +| Ctrl+Shift+Digit1 | ! | Ctrl+Shift+1 | | Ctrl+Shift+1 | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | | +| Alt+Digit1 | 1 | Alt+1 | | Alt+1 | alt+1 | Alt+1 | alt+[Digit1] | | +| Ctrl+Alt+Digit1 | 1 | Ctrl+Alt+1 | | Ctrl+Alt+1 | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | | +| Shift+Alt+Digit1 | ! | Shift+Alt+1 | | Shift+Alt+1 | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | | +| Ctrl+Shift+Alt+Digit1 | ! | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit2 | 2 | 2 | | 2 | 2 | 2 | [Digit2] | | +| Ctrl+Digit2 | 2 | Ctrl+2 | | Ctrl+2 | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | | +| Shift+Digit2 | " | Shift+2 | | Shift+2 | shift+2 | Shift+2 | shift+[Digit2] | | +| | | Shift+' | | | | | | | +| Ctrl+Shift+Digit2 | " | Ctrl+Shift+2 | | Ctrl+Shift+2 | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | | +| | | Ctrl+Shift+' | | | | | | | +| Alt+Digit2 | 2 | Alt+2 | | Alt+2 | alt+2 | Alt+2 | alt+[Digit2] | | +| Ctrl+Alt+Digit2 | 2 | Ctrl+Alt+2 | | Ctrl+Alt+2 | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | | +| Shift+Alt+Digit2 | " | Shift+Alt+2 | | Shift+Alt+2 | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | | +| | | Shift+Alt+' | | | | | | | +| Ctrl+Shift+Alt+Digit2 | " | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | | +| | | Ctrl+Shift+Alt+' | | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit3 | 3 | 3 | | 3 | 3 | 3 | [Digit3] | | +| Ctrl+Digit3 | 3 | Ctrl+3 | | Ctrl+3 | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | | +| Shift+Digit3 | № | Shift+3 | | Shift+3 | shift+3 | Shift+3 | shift+[Digit3] | | +| Ctrl+Shift+Digit3 | № | Ctrl+Shift+3 | | Ctrl+Shift+3 | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | | +| Alt+Digit3 | 3 | Alt+3 | | Alt+3 | alt+3 | Alt+3 | alt+[Digit3] | | +| Ctrl+Alt+Digit3 | 3 | Ctrl+Alt+3 | | Ctrl+Alt+3 | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | | +| Shift+Alt+Digit3 | № | Shift+Alt+3 | | Shift+Alt+3 | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | | +| Ctrl+Shift+Alt+Digit3 | № | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit4 | 4 | 4 | | 4 | 4 | 4 | [Digit4] | | +| Ctrl+Digit4 | 4 | Ctrl+4 | | Ctrl+4 | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | | +| Shift+Digit4 | ; | Shift+4 | | Shift+4 | shift+4 | Shift+4 | shift+[Digit4] | | +| | | ; | | | | | | | +| Ctrl+Shift+Digit4 | ; | Ctrl+Shift+4 | | Ctrl+Shift+4 | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | | +| | | Ctrl+; | | | | | | | +| Alt+Digit4 | 4 | Alt+4 | | Alt+4 | alt+4 | Alt+4 | alt+[Digit4] | | +| Ctrl+Alt+Digit4 | 4 | Ctrl+Alt+4 | | Ctrl+Alt+4 | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | | +| Shift+Alt+Digit4 | ; | Shift+Alt+4 | | Shift+Alt+4 | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | | +| | | Alt+; | | | | | | | +| Ctrl+Shift+Alt+Digit4 | ; | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | | +| | | Ctrl+Alt+; | | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit5 | 5 | 5 | | 5 | 5 | 5 | [Digit5] | | +| Ctrl+Digit5 | 5 | Ctrl+5 | | Ctrl+5 | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | | +| Shift+Digit5 | % | Shift+5 | | Shift+5 | shift+5 | Shift+5 | shift+[Digit5] | | +| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+5 | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | | +| Alt+Digit5 | 5 | Alt+5 | | Alt+5 | alt+5 | Alt+5 | alt+[Digit5] | | +| Ctrl+Alt+Digit5 | 5 | Ctrl+Alt+5 | | Ctrl+Alt+5 | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | | +| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Alt+5 | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | | +| Ctrl+Shift+Alt+Digit5 | % | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit6 | 6 | 6 | | 6 | 6 | 6 | [Digit6] | | +| Ctrl+Digit6 | 6 | Ctrl+6 | | Ctrl+6 | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | | +| Shift+Digit6 | : | Shift+6 | | Shift+6 | shift+6 | Shift+6 | shift+[Digit6] | | +| | | Shift+; | | | | | | | +| Ctrl+Shift+Digit6 | : | Ctrl+Shift+6 | | Ctrl+Shift+6 | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | | +| | | Ctrl+Shift+; | | | | | | | +| Alt+Digit6 | 6 | Alt+6 | | Alt+6 | alt+6 | Alt+6 | alt+[Digit6] | | +| Ctrl+Alt+Digit6 | 6 | Ctrl+Alt+6 | | Ctrl+Alt+6 | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | | +| Shift+Alt+Digit6 | : | Shift+Alt+6 | | Shift+Alt+6 | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | | +| | | Shift+Alt+; | | | | | | | +| Ctrl+Shift+Alt+Digit6 | : | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | | +| | | Ctrl+Shift+Alt+; | | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit7 | 7 | 7 | | 7 | 7 | 7 | [Digit7] | | +| Ctrl+Digit7 | 7 | Ctrl+7 | | Ctrl+7 | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | | +| Shift+Digit7 | ? | Shift+7 | | Shift+7 | shift+7 | Shift+7 | shift+[Digit7] | | +| | | Shift+/ | | | | | | | +| Ctrl+Shift+Digit7 | ? | Ctrl+Shift+7 | | Ctrl+Shift+7 | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | | +| | | Ctrl+Shift+/ | | | | | | | +| Alt+Digit7 | 7 | Alt+7 | | Alt+7 | alt+7 | Alt+7 | alt+[Digit7] | | +| Ctrl+Alt+Digit7 | 7 | Ctrl+Alt+7 | | Ctrl+Alt+7 | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | | +| Shift+Alt+Digit7 | ? | Shift+Alt+7 | | Shift+Alt+7 | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | | +| | | Shift+Alt+/ | | | | | | | +| Ctrl+Shift+Alt+Digit7 | ? | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | | +| | | Ctrl+Shift+Alt+/ | | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit8 | 8 | 8 | | 8 | 8 | 8 | [Digit8] | | +| Ctrl+Digit8 | 8 | Ctrl+8 | | Ctrl+8 | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | | +| Shift+Digit8 | * | Shift+8 | | Shift+8 | shift+8 | Shift+8 | shift+[Digit8] | | +| Ctrl+Shift+Digit8 | * | Ctrl+Shift+8 | | Ctrl+Shift+8 | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | | +| Alt+Digit8 | 8 | Alt+8 | | Alt+8 | alt+8 | Alt+8 | alt+[Digit8] | | +| Ctrl+Alt+Digit8 | 8 | Ctrl+Alt+8 | | Ctrl+Alt+8 | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | | +| Shift+Alt+Digit8 | * | Shift+Alt+8 | | Shift+Alt+8 | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | | +| Ctrl+Shift+Alt+Digit8 | * | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit9 | 9 | 9 | | 9 | 9 | 9 | [Digit9] | | +| Ctrl+Digit9 | 9 | Ctrl+9 | | Ctrl+9 | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | | +| Shift+Digit9 | ( | Shift+9 | | Shift+9 | shift+9 | Shift+9 | shift+[Digit9] | | +| Ctrl+Shift+Digit9 | ( | Ctrl+Shift+9 | | Ctrl+Shift+9 | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | | +| Alt+Digit9 | 9 | Alt+9 | | Alt+9 | alt+9 | Alt+9 | alt+[Digit9] | | +| Ctrl+Alt+Digit9 | 9 | Ctrl+Alt+9 | | Ctrl+Alt+9 | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | | +| Shift+Alt+Digit9 | ( | Shift+Alt+9 | | Shift+Alt+9 | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | | +| Ctrl+Shift+Alt+Digit9 | ( | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit0 | 0 | 0 | | 0 | 0 | 0 | [Digit0] | | +| Ctrl+Digit0 | 0 | Ctrl+0 | | Ctrl+0 | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | | +| Shift+Digit0 | ) | Shift+0 | | Shift+0 | shift+0 | Shift+0 | shift+[Digit0] | | +| Ctrl+Shift+Digit0 | ) | Ctrl+Shift+0 | | Ctrl+Shift+0 | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | | +| Alt+Digit0 | 0 | Alt+0 | | Alt+0 | alt+0 | Alt+0 | alt+[Digit0] | | +| Ctrl+Alt+Digit0 | 0 | Ctrl+Alt+0 | | Ctrl+Alt+0 | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | | +| Shift+Alt+Digit0 | ) | Shift+Alt+0 | | Shift+Alt+0 | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | | +| Ctrl+Shift+Alt+Digit0 | ) | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Minus | - | - | | - | - | null | [Minus] | | +| Ctrl+Minus | - | Ctrl+- | | Ctrl+- | ctrl+- | null | ctrl+[Minus] | | +| Shift+Minus | _ | Shift+- | | Shift+- | shift+- | null | shift+[Minus] | | +| Ctrl+Shift+Minus | _ | Ctrl+Shift+- | | Ctrl+Shift+- | ctrl+shift+- | null | ctrl+shift+[Minus] | | +| Alt+Minus | - | Alt+- | | Alt+- | alt+- | null | alt+[Minus] | | +| Ctrl+Alt+Minus | - | Ctrl+Alt+- | | Ctrl+Alt+- | ctrl+alt+- | null | ctrl+alt+[Minus] | | +| Shift+Alt+Minus | _ | Shift+Alt+- | | Shift+Alt+- | shift+alt+- | null | shift+alt+[Minus] | | +| Ctrl+Shift+Alt+Minus | _ | Ctrl+Shift+Alt+- | | Ctrl+Shift+Alt+- | ctrl+shift+alt+- | null | ctrl+shift+alt+[Minus] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Equal | = | = | | = | = | null | [Equal] | | +| Ctrl+Equal | = | Ctrl+= | | Ctrl+= | ctrl+= | null | ctrl+[Equal] | | +| Shift+Equal | + | Shift+= | | Shift+= | shift+= | null | shift+[Equal] | | +| Ctrl+Shift+Equal | + | Ctrl+Shift+= | | Ctrl+Shift+= | ctrl+shift+= | null | ctrl+shift+[Equal] | | +| Alt+Equal | = | Alt+= | | Alt+= | alt+= | null | alt+[Equal] | | +| Ctrl+Alt+Equal | = | Ctrl+Alt+= | | Ctrl+Alt+= | ctrl+alt+= | null | ctrl+alt+[Equal] | | +| Shift+Alt+Equal | + | Shift+Alt+= | | Shift+Alt+= | shift+alt+= | null | shift+alt+[Equal] | | +| Ctrl+Shift+Alt+Equal | + | Ctrl+Shift+Alt+= | | Ctrl+Shift+Alt+= | ctrl+shift+alt+= | null | ctrl+shift+alt+[Equal] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketLeft | х | | | х | [BracketLeft] | null | [BracketLeft] | NO | +| Ctrl+BracketLeft | х | | | Ctrl+х | ctrl+[BracketLeft] | null | ctrl+[BracketLeft] | NO | +| Shift+BracketLeft | Х | | | Shift+х | shift+[BracketLeft] | null | shift+[BracketLeft] | NO | +| Ctrl+Shift+BracketLeft | Х | | | Ctrl+Shift+х | ctrl+shift+[BracketLeft] | null | ctrl+shift+[BracketLeft] | NO | +| Alt+BracketLeft | х | | | Alt+х | alt+[BracketLeft] | null | alt+[BracketLeft] | NO | +| Ctrl+Alt+BracketLeft | х | | | Ctrl+Alt+х | ctrl+alt+[BracketLeft] | null | ctrl+alt+[BracketLeft] | NO | +| Shift+Alt+BracketLeft | Х | | | Shift+Alt+х | shift+alt+[BracketLeft] | null | shift+alt+[BracketLeft] | NO | +| Ctrl+Shift+Alt+BracketLeft | Х | | | Ctrl+Shift+Alt+х | ctrl+shift+alt+[BracketLeft] | null | ctrl+shift+alt+[BracketLeft] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketRight | ъ | | | ъ | [BracketRight] | null | [BracketRight] | NO | +| Ctrl+BracketRight | ъ | | | Ctrl+ъ | ctrl+[BracketRight] | null | ctrl+[BracketRight] | NO | +| Shift+BracketRight | Ъ | | | Shift+ъ | shift+[BracketRight] | null | shift+[BracketRight] | NO | +| Ctrl+Shift+BracketRight | Ъ | | | Ctrl+Shift+ъ | ctrl+shift+[BracketRight] | null | ctrl+shift+[BracketRight] | NO | +| Alt+BracketRight | ъ | | | Alt+ъ | alt+[BracketRight] | null | alt+[BracketRight] | NO | +| Ctrl+Alt+BracketRight | ъ | | | Ctrl+Alt+ъ | ctrl+alt+[BracketRight] | null | ctrl+alt+[BracketRight] | NO | +| Shift+Alt+BracketRight | Ъ | | | Shift+Alt+ъ | shift+alt+[BracketRight] | null | shift+alt+[BracketRight] | NO | +| Ctrl+Shift+Alt+BracketRight | Ъ | | | Ctrl+Shift+Alt+ъ | ctrl+shift+alt+[BracketRight] | null | ctrl+shift+alt+[BracketRight] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backslash | \ | \ | | \ | [Backslash] | null | [Backslash] | NO | +| Ctrl+Backslash | \ | Ctrl+\ | | Ctrl+\ | ctrl+[Backslash] | null | ctrl+[Backslash] | NO | +| Shift+Backslash | / | / | 1 | Shift+\ | shift+[Backslash] | null | shift+[Backslash] | NO | +| Ctrl+Shift+Backslash | / | Ctrl+/ | 1 | Ctrl+Shift+\ | ctrl+shift+[Backslash] | null | ctrl+shift+[Backslash] | NO | +| Alt+Backslash | \ | Alt+\ | | Alt+\ | alt+[Backslash] | null | alt+[Backslash] | NO | +| Ctrl+Alt+Backslash | \ | Ctrl+Alt+\ | | Ctrl+Alt+\ | ctrl+alt+[Backslash] | null | ctrl+alt+[Backslash] | NO | +| Shift+Alt+Backslash | / | Alt+/ | 1 | Shift+Alt+\ | shift+alt+[Backslash] | null | shift+alt+[Backslash] | NO | +| Ctrl+Shift+Alt+Backslash | / | Ctrl+Alt+/ | 1 | Ctrl+Shift+Alt+\ | ctrl+shift+alt+[Backslash] | null | ctrl+shift+alt+[Backslash] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlHash | --- | | | null | null | null | null | | +| Ctrl+IntlHash | --- | | | null | null | null | null | | +| Shift+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | +| Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | +| Shift+Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Semicolon | ж | | | ж | [Semicolon] | null | [Semicolon] | NO | +| Ctrl+Semicolon | ж | | | Ctrl+ж | ctrl+[Semicolon] | null | ctrl+[Semicolon] | NO | +| Shift+Semicolon | Ж | | | Shift+ж | shift+[Semicolon] | null | shift+[Semicolon] | NO | +| Ctrl+Shift+Semicolon | Ж | | | Ctrl+Shift+ж | ctrl+shift+[Semicolon] | null | ctrl+shift+[Semicolon] | NO | +| Alt+Semicolon | ж | | | Alt+ж | alt+[Semicolon] | null | alt+[Semicolon] | NO | +| Ctrl+Alt+Semicolon | ж | | | Ctrl+Alt+ж | ctrl+alt+[Semicolon] | null | ctrl+alt+[Semicolon] | NO | +| Shift+Alt+Semicolon | Ж | | | Shift+Alt+ж | shift+alt+[Semicolon] | null | shift+alt+[Semicolon] | NO | +| Ctrl+Shift+Alt+Semicolon | Ж | | | Ctrl+Shift+Alt+ж | ctrl+shift+alt+[Semicolon] | null | ctrl+shift+alt+[Semicolon] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Quote | э | | | э | [Quote] | null | [Quote] | NO | +| Ctrl+Quote | э | | | Ctrl+э | ctrl+[Quote] | null | ctrl+[Quote] | NO | +| Shift+Quote | Э | | | Shift+э | shift+[Quote] | null | shift+[Quote] | NO | +| Ctrl+Shift+Quote | Э | | | Ctrl+Shift+э | ctrl+shift+[Quote] | null | ctrl+shift+[Quote] | NO | +| Alt+Quote | э | | | Alt+э | alt+[Quote] | null | alt+[Quote] | NO | +| Ctrl+Alt+Quote | э | | | Ctrl+Alt+э | ctrl+alt+[Quote] | null | ctrl+alt+[Quote] | NO | +| Shift+Alt+Quote | Э | | | Shift+Alt+э | shift+alt+[Quote] | null | shift+alt+[Quote] | NO | +| Ctrl+Shift+Alt+Quote | Э | | | Ctrl+Shift+Alt+э | ctrl+shift+alt+[Quote] | null | ctrl+shift+alt+[Quote] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backquote | ё | | | ё | [Backquote] | null | [Backquote] | NO | +| Ctrl+Backquote | ё | | | Ctrl+ё | ctrl+[Backquote] | null | ctrl+[Backquote] | NO | +| Shift+Backquote | Ё | | | Shift+ё | shift+[Backquote] | null | shift+[Backquote] | NO | +| Ctrl+Shift+Backquote | Ё | | | Ctrl+Shift+ё | ctrl+shift+[Backquote] | null | ctrl+shift+[Backquote] | NO | +| Alt+Backquote | ё | | | Alt+ё | alt+[Backquote] | null | alt+[Backquote] | NO | +| Ctrl+Alt+Backquote | ё | | | Ctrl+Alt+ё | ctrl+alt+[Backquote] | null | ctrl+alt+[Backquote] | NO | +| Shift+Alt+Backquote | Ё | | | Shift+Alt+ё | shift+alt+[Backquote] | null | shift+alt+[Backquote] | NO | +| Ctrl+Shift+Alt+Backquote | Ё | | | Ctrl+Shift+Alt+ё | ctrl+shift+alt+[Backquote] | null | ctrl+shift+alt+[Backquote] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Comma | б | | | б | [Comma] | null | [Comma] | NO | +| Ctrl+Comma | б | | | Ctrl+б | ctrl+[Comma] | null | ctrl+[Comma] | NO | +| Shift+Comma | Б | | | Shift+б | shift+[Comma] | null | shift+[Comma] | NO | +| Ctrl+Shift+Comma | Б | | | Ctrl+Shift+б | ctrl+shift+[Comma] | null | ctrl+shift+[Comma] | NO | +| Alt+Comma | б | | | Alt+б | alt+[Comma] | null | alt+[Comma] | NO | +| Ctrl+Alt+Comma | б | | | Ctrl+Alt+б | ctrl+alt+[Comma] | null | ctrl+alt+[Comma] | NO | +| Shift+Alt+Comma | Б | | | Shift+Alt+б | shift+alt+[Comma] | null | shift+alt+[Comma] | NO | +| Ctrl+Shift+Alt+Comma | Б | | | Ctrl+Shift+Alt+б | ctrl+shift+alt+[Comma] | null | ctrl+shift+alt+[Comma] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Period | ю | | | ю | [Period] | null | [Period] | NO | +| Ctrl+Period | ю | | | Ctrl+ю | ctrl+[Period] | null | ctrl+[Period] | NO | +| Shift+Period | Ю | | | Shift+ю | shift+[Period] | null | shift+[Period] | NO | +| Ctrl+Shift+Period | Ю | | | Ctrl+Shift+ю | ctrl+shift+[Period] | null | ctrl+shift+[Period] | NO | +| Alt+Period | ю | | | Alt+ю | alt+[Period] | null | alt+[Period] | NO | +| Ctrl+Alt+Period | ю | | | Ctrl+Alt+ю | ctrl+alt+[Period] | null | ctrl+alt+[Period] | NO | +| Shift+Alt+Period | Ю | | | Shift+Alt+ю | shift+alt+[Period] | null | shift+alt+[Period] | NO | +| Ctrl+Shift+Alt+Period | Ю | | | Ctrl+Shift+Alt+ю | ctrl+shift+alt+[Period] | null | ctrl+shift+alt+[Period] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Slash | . | . | | . | [Slash] | null | [Slash] | NO | +| Ctrl+Slash | . | Ctrl+. | | Ctrl+. | ctrl+[Slash] | null | ctrl+[Slash] | NO | +| Shift+Slash | , | , | | Shift+. | shift+[Slash] | null | shift+[Slash] | NO | +| Ctrl+Shift+Slash | , | Ctrl+, | | Ctrl+Shift+. | ctrl+shift+[Slash] | null | ctrl+shift+[Slash] | NO | +| Alt+Slash | . | Alt+. | | Alt+. | alt+[Slash] | null | alt+[Slash] | NO | +| Ctrl+Alt+Slash | . | Ctrl+Alt+. | | Ctrl+Alt+. | ctrl+alt+[Slash] | null | ctrl+alt+[Slash] | NO | +| Shift+Alt+Slash | , | Alt+, | | Shift+Alt+. | shift+alt+[Slash] | null | shift+alt+[Slash] | NO | +| Ctrl+Shift+Alt+Slash | , | Ctrl+Alt+, | | Ctrl+Shift+Alt+. | ctrl+shift+alt+[Slash] | null | ctrl+shift+alt+[Slash] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | +| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | +| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | +| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | +| Alt+ArrowUp | --- | Alt+UpArrow | | Alt+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | +| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Alt+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | +| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Alt+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | +| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | +| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | +| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | +| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | +| Alt+Numpad0 | --- | Alt+NumPad0 | | Alt+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | +| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | +| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Alt+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | +| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlBackslash | / | / | 2 | / | [IntlBackslash] | null | [IntlBackslash] | NO | +| Ctrl+IntlBackslash | / | Ctrl+/ | 2 | Ctrl+/ | ctrl+[IntlBackslash] | null | ctrl+[IntlBackslash] | NO | +| Shift+IntlBackslash | | | Shift+\ | | Shift+/ | shift+[IntlBackslash] | null | shift+[IntlBackslash] | NO | +| Ctrl+Shift+IntlBackslash | | | Ctrl+Shift+\ | | Ctrl+Shift+/ | ctrl+shift+[IntlBackslash] | null | ctrl+shift+[IntlBackslash] | NO | +| Alt+IntlBackslash | / | Alt+/ | 2 | Alt+/ | alt+[IntlBackslash] | null | alt+[IntlBackslash] | NO | +| Ctrl+Alt+IntlBackslash | | | Ctrl+Alt+/ | 2 | Ctrl+Alt+/ | ctrl+alt+[IntlBackslash] | null | ctrl+alt+[IntlBackslash] | NO | +| Shift+Alt+IntlBackslash | | | Shift+Alt+\ | | Shift+Alt+/ | shift+alt+[IntlBackslash] | null | shift+alt+[IntlBackslash] | NO | +| Ctrl+Shift+Alt+IntlBackslash | ¦ | Ctrl+Shift+Alt+\ | | Ctrl+Shift+Alt+/ | ctrl+shift+alt+[IntlBackslash] | null | ctrl+shift+alt+[IntlBackslash] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | +| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | +| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | +| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | +| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | +| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | +| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | +| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | +| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | +| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | +| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | +| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | +| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | +| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | +| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/node/macLinuxFallbackKeyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/node/macLinuxFallbackKeyboardMapper.test.ts new file mode 100644 index 00000000000..649227a8921 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/macLinuxFallbackKeyboardMapper.test.ts @@ -0,0 +1,352 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyChord, KeyCode, KeyMod, ScanCode } from 'vs/base/common/keyCodes'; +import { SimpleKeybinding, createKeybinding, ScanCodeBinding } from 'vs/base/common/keybindings'; +import { OperatingSystem } from 'vs/base/common/platform'; +import { MacLinuxFallbackKeyboardMapper } from 'vs/workbench/services/keybinding/common/macLinuxFallbackKeyboardMapper'; +import { IResolvedKeybinding, assertResolveKeybinding, assertResolveKeyboardEvent, assertResolveUserBinding } from 'vs/workbench/services/keybinding/test/node/keyboardMapperTestUtils'; + +suite('keyboardMapper - MAC fallback', () => { + + const mapper = new MacLinuxFallbackKeyboardMapper(OperatingSystem.Macintosh); + + function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void { + assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Macintosh)!, expected); + } + + test('resolveKeybinding Cmd+Z', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.KeyZ, + [{ + label: '⌘Z', + ariaLabel: 'Command+Z', + electronAccelerator: 'Cmd+Z', + userSettingsLabel: 'cmd+z', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['meta+Z'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Cmd+K Cmd+=', () => { + _assertResolveKeybinding( + KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Equal), + [{ + label: '⌘K ⌘=', + ariaLabel: 'Command+K Command+=', + electronAccelerator: null, + userSettingsLabel: 'cmd+k cmd+=', + isWYSIWYG: true, + isChord: true, + dispatchParts: ['meta+K', 'meta+='], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveKeyboardEvent Cmd+Z', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: true, + keyCode: KeyCode.KeyZ, + code: null! + }, + { + label: '⌘Z', + ariaLabel: 'Command+Z', + electronAccelerator: 'Cmd+Z', + userSettingsLabel: 'cmd+z', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['meta+Z'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveUserBinding empty', () => { + assertResolveUserBinding(mapper, [], []); + }); + + test('resolveUserBinding Cmd+[Comma] Cmd+/', () => { + assertResolveUserBinding( + mapper, [ + new ScanCodeBinding(false, false, false, true, ScanCode.Comma), + new SimpleKeybinding(false, false, false, true, KeyCode.Slash), + ], + [{ + label: '⌘, ⌘/', + ariaLabel: 'Command+, Command+/', + electronAccelerator: null, + userSettingsLabel: 'cmd+, cmd+/', + isWYSIWYG: true, + isChord: true, + dispatchParts: ['meta+,', 'meta+/'], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveKeyboardEvent Single Modifier Meta+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: true, + keyCode: KeyCode.Meta, + code: null! + }, + { + label: '⌘', + ariaLabel: 'Command', + electronAccelerator: null, + userSettingsLabel: 'cmd', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['meta'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier Shift+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: true, + altKey: false, + metaKey: false, + keyCode: KeyCode.Shift, + code: null! + }, + { + label: '⇧', + ariaLabel: 'Shift', + electronAccelerator: null, + userSettingsLabel: 'shift', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['shift'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier Alt+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: true, + metaKey: false, + keyCode: KeyCode.Alt, + code: null! + }, + { + label: '⌥', + ariaLabel: 'Option', + electronAccelerator: null, + userSettingsLabel: 'alt', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['alt'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier Meta+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: true, + keyCode: KeyCode.Meta, + code: null! + }, + { + label: '⌘', + ariaLabel: 'Command', + electronAccelerator: null, + userSettingsLabel: 'cmd', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['meta'], + } + ); + }); + + test('resolveKeyboardEvent Only Modifiers Ctrl+Shift+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: true, + altKey: false, + metaKey: false, + keyCode: KeyCode.Shift, + code: null! + }, + { + label: '⌃⇧', + ariaLabel: 'Control+Shift', + electronAccelerator: null, + userSettingsLabel: 'ctrl+shift', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: [null], + } + ); + }); +}); + +suite('keyboardMapper - LINUX fallback', () => { + + const mapper = new MacLinuxFallbackKeyboardMapper(OperatingSystem.Linux); + + function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void { + assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Linux)!, expected); + } + + test('resolveKeybinding Ctrl+Z', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.KeyZ, + [{ + label: 'Ctrl+Z', + ariaLabel: 'Control+Z', + electronAccelerator: 'Ctrl+Z', + userSettingsLabel: 'ctrl+z', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+Z'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+K Ctrl+=', () => { + _assertResolveKeybinding( + KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Equal), + [{ + label: 'Ctrl+K Ctrl+=', + ariaLabel: 'Control+K Control+=', + electronAccelerator: null, + userSettingsLabel: 'ctrl+k ctrl+=', + isWYSIWYG: true, + isChord: true, + dispatchParts: ['ctrl+K', 'ctrl+='], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveKeyboardEvent Ctrl+Z', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: KeyCode.KeyZ, + code: null! + }, + { + label: 'Ctrl+Z', + ariaLabel: 'Control+Z', + electronAccelerator: 'Ctrl+Z', + userSettingsLabel: 'ctrl+z', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+Z'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveUserBinding Ctrl+[Comma] Ctrl+/', () => { + assertResolveUserBinding( + mapper, [ + new ScanCodeBinding(true, false, false, false, ScanCode.Comma), + new SimpleKeybinding(true, false, false, false, KeyCode.Slash), + ], + [{ + label: 'Ctrl+, Ctrl+/', + ariaLabel: 'Control+, Control+/', + electronAccelerator: null, + userSettingsLabel: 'ctrl+, ctrl+/', + isWYSIWYG: true, + isChord: true, + dispatchParts: ['ctrl+,', 'ctrl+/'], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveUserBinding Ctrl+[Comma]', () => { + assertResolveUserBinding( + mapper, [ + new ScanCodeBinding(true, false, false, false, ScanCode.Comma), + ], + [{ + label: 'Ctrl+,', + ariaLabel: 'Control+,', + electronAccelerator: 'Ctrl+,', + userSettingsLabel: 'ctrl+,', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+,'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeyboardEvent Single Modifier Ctrl+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: KeyCode.Ctrl, + code: null! + }, + { + label: 'Ctrl', + ariaLabel: 'Control', + electronAccelerator: null, + userSettingsLabel: 'ctrl', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['ctrl'], + } + ); + }); +}); diff --git a/src/vs/workbench/services/keybinding/test/node/macLinuxKeyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/node/macLinuxKeyboardMapper.test.ts new file mode 100644 index 00000000000..5c7c6021539 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/macLinuxKeyboardMapper.test.ts @@ -0,0 +1,1730 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { KeyChord, KeyCode, KeyMod, ScanCode, ScanCodeUtils } from 'vs/base/common/keyCodes'; +import { SimpleKeybinding, createKeybinding, createSimpleKeybinding, ScanCodeBinding } from 'vs/base/common/keybindings'; +import { UserSettingsLabelProvider } from 'vs/base/common/keybindingLabels'; +import { OperatingSystem } from 'vs/base/common/platform'; +import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding'; +import { MacLinuxKeyboardMapper } from 'vs/workbench/services/keybinding/common/macLinuxKeyboardMapper'; +import { IResolvedKeybinding, assertMapping, assertResolveKeybinding, assertResolveKeyboardEvent, assertResolveUserBinding, readRawMapping } from 'vs/workbench/services/keybinding/test/node/keyboardMapperTestUtils'; +import { IMacLinuxKeyboardMapping } from 'vs/platform/keyboardLayout/common/keyboardLayout'; + +const WRITE_FILE_IF_DIFFERENT = false; + +async function createKeyboardMapper(isUSStandard: boolean, file: string, OS: OperatingSystem): Promise { + const rawMappings = await readRawMapping(file); + return new MacLinuxKeyboardMapper(isUSStandard, rawMappings, OS); +} + +suite('keyboardMapper - MAC de_ch', () => { + + let mapper: MacLinuxKeyboardMapper; + + suiteSetup(async () => { + const _mapper = await createKeyboardMapper(false, 'mac_de_ch', OperatingSystem.Macintosh); + mapper = _mapper; + }); + + test('mapping', () => { + return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'mac_de_ch.txt'); + }); + + function assertKeybindingTranslation(kb: number, expected: string | string[]): void { + _assertKeybindingTranslation(mapper, OperatingSystem.Macintosh, kb, expected); + } + + function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void { + assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Macintosh)!, expected); + } + + test('kb => hw', () => { + // unchanged + assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.Digit1, 'cmd+Digit1'); + assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.KeyB, 'cmd+KeyB'); + assertKeybindingTranslation(KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyB, 'shift+cmd+KeyB'); + assertKeybindingTranslation(KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyB, 'ctrl+shift+alt+cmd+KeyB'); + + // flips Y and Z + assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.KeyZ, 'cmd+KeyY'); + assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.KeyY, 'cmd+KeyZ'); + + // Ctrl+/ + assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.Slash, 'shift+cmd+Digit7'); + }); + + test('resolveKeybinding Cmd+A', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.KeyA, + [{ + label: '⌘A', + ariaLabel: 'Command+A', + electronAccelerator: 'Cmd+A', + userSettingsLabel: 'cmd+a', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['meta+[KeyA]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Cmd+B', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.KeyB, + [{ + label: '⌘B', + ariaLabel: 'Command+B', + electronAccelerator: 'Cmd+B', + userSettingsLabel: 'cmd+b', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['meta+[KeyB]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Cmd+Z', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.KeyZ, + [{ + label: '⌘Z', + ariaLabel: 'Command+Z', + electronAccelerator: 'Cmd+Z', + userSettingsLabel: 'cmd+z', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['meta+[KeyY]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeyboardEvent Cmd+[KeyY]', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: true, + keyCode: -1, + code: 'KeyY' + }, + { + label: '⌘Z', + ariaLabel: 'Command+Z', + electronAccelerator: 'Cmd+Z', + userSettingsLabel: 'cmd+z', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['meta+[KeyY]'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveKeybinding Cmd+]', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.BracketRight, + [{ + label: '⌃⌥⌘6', + ariaLabel: 'Control+Option+Command+6', + electronAccelerator: 'Ctrl+Alt+Cmd+6', + userSettingsLabel: 'ctrl+alt+cmd+6', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+alt+meta+[Digit6]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeyboardEvent Cmd+[BracketRight]', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: true, + keyCode: -1, + code: 'BracketRight' + }, + { + label: '⌘¨', + ariaLabel: 'Command+¨', + electronAccelerator: null, + userSettingsLabel: 'cmd+[BracketRight]', + isWYSIWYG: false, + isChord: false, + dispatchParts: ['meta+[BracketRight]'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveKeybinding Shift+]', () => { + _assertResolveKeybinding( + KeyMod.Shift | KeyCode.BracketRight, + [{ + label: '⌃⌥9', + ariaLabel: 'Control+Option+9', + electronAccelerator: 'Ctrl+Alt+9', + userSettingsLabel: 'ctrl+alt+9', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+alt+[Digit9]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Cmd+/', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.Slash, + [{ + label: '⇧⌘7', + ariaLabel: 'Shift+Command+7', + electronAccelerator: 'Shift+Cmd+7', + userSettingsLabel: 'shift+cmd+7', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['shift+meta+[Digit7]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Cmd+Shift+/', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Slash, + [{ + label: '⇧⌘\'', + ariaLabel: 'Shift+Command+\'', + electronAccelerator: null, + userSettingsLabel: 'shift+cmd+[Minus]', + isWYSIWYG: false, + isChord: false, + dispatchParts: ['shift+meta+[Minus]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Cmd+K Cmd+\\', () => { + _assertResolveKeybinding( + KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Backslash), + [{ + label: '⌘K ⌃⇧⌥⌘7', + ariaLabel: 'Command+K Control+Shift+Option+Command+7', + electronAccelerator: null, + userSettingsLabel: 'cmd+k ctrl+shift+alt+cmd+7', + isWYSIWYG: true, + isChord: true, + dispatchParts: ['meta+[KeyK]', 'ctrl+shift+alt+meta+[Digit7]'], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveKeybinding Cmd+K Cmd+=', () => { + _assertResolveKeybinding( + KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Equal), + [{ + label: '⌘K ⇧⌘0', + ariaLabel: 'Command+K Shift+Command+0', + electronAccelerator: null, + userSettingsLabel: 'cmd+k shift+cmd+0', + isWYSIWYG: true, + isChord: true, + dispatchParts: ['meta+[KeyK]', 'shift+meta+[Digit0]'], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveKeybinding Cmd+DownArrow', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.DownArrow, + [{ + label: '⌘↓', + ariaLabel: 'Command+DownArrow', + electronAccelerator: 'Cmd+Down', + userSettingsLabel: 'cmd+down', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['meta+[ArrowDown]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Cmd+NUMPAD_0', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.Numpad0, + [{ + label: '⌘NumPad0', + ariaLabel: 'Command+NumPad0', + electronAccelerator: null, + userSettingsLabel: 'cmd+numpad0', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['meta+[Numpad0]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+Home', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.Home, + [{ + label: '⌘Home', + ariaLabel: 'Command+Home', + electronAccelerator: 'Cmd+Home', + userSettingsLabel: 'cmd+home', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['meta+[Home]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeyboardEvent Ctrl+[Home]', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: true, + keyCode: -1, + code: 'Home' + }, + { + label: '⌘Home', + ariaLabel: 'Command+Home', + electronAccelerator: 'Cmd+Home', + userSettingsLabel: 'cmd+home', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['meta+[Home]'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveUserBinding empty', () => { + assertResolveUserBinding(mapper, [], []); + }); + + test('resolveUserBinding Cmd+[Comma] Cmd+/', () => { + assertResolveUserBinding( + mapper, + [ + new ScanCodeBinding(false, false, false, true, ScanCode.Comma), + new SimpleKeybinding(false, false, false, true, KeyCode.Slash), + ], + [{ + label: '⌘, ⇧⌘7', + ariaLabel: 'Command+, Shift+Command+7', + electronAccelerator: null, + userSettingsLabel: 'cmd+[Comma] shift+cmd+7', + isWYSIWYG: false, + isChord: true, + dispatchParts: ['meta+[Comma]', 'shift+meta+[Digit7]'], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveKeyboardEvent Single Modifier MetaLeft+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: true, + keyCode: -1, + code: 'MetaLeft' + }, + { + label: '⌘', + ariaLabel: 'Command', + electronAccelerator: null, + userSettingsLabel: 'cmd', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['meta'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier MetaRight+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: true, + keyCode: -1, + code: 'MetaRight' + }, + { + label: '⌘', + ariaLabel: 'Command', + electronAccelerator: null, + userSettingsLabel: 'cmd', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['meta'], + } + ); + }); +}); + +suite('keyboardMapper - MAC en_us', () => { + + let mapper: MacLinuxKeyboardMapper; + + suiteSetup(async () => { + const _mapper = await createKeyboardMapper(true, 'mac_en_us', OperatingSystem.Macintosh); + mapper = _mapper; + }); + + test('mapping', () => { + return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'mac_en_us.txt'); + }); + + test('resolveUserBinding Cmd+[Comma] Cmd+/', () => { + assertResolveUserBinding( + mapper, + [ + new ScanCodeBinding(false, false, false, true, ScanCode.Comma), + new SimpleKeybinding(false, false, false, true, KeyCode.Slash), + ], + [{ + label: '⌘, ⌘/', + ariaLabel: 'Command+, Command+/', + electronAccelerator: null, + userSettingsLabel: 'cmd+, cmd+/', + isWYSIWYG: true, + isChord: true, + dispatchParts: ['meta+[Comma]', 'meta+[Slash]'], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveKeyboardEvent Single Modifier MetaLeft+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: true, + keyCode: -1, + code: 'MetaLeft' + }, + { + label: '⌘', + ariaLabel: 'Command', + electronAccelerator: null, + userSettingsLabel: 'cmd', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['meta'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier MetaRight+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: true, + keyCode: -1, + code: 'MetaRight' + }, + { + label: '⌘', + ariaLabel: 'Command', + electronAccelerator: null, + userSettingsLabel: 'cmd', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['meta'], + } + ); + }); +}); + +suite('keyboardMapper - LINUX de_ch', () => { + + let mapper: MacLinuxKeyboardMapper; + + suiteSetup(async () => { + const _mapper = await createKeyboardMapper(false, 'linux_de_ch', OperatingSystem.Linux); + mapper = _mapper; + }); + + test('mapping', () => { + return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'linux_de_ch.txt'); + }); + + function assertKeybindingTranslation(kb: number, expected: string | string[]): void { + _assertKeybindingTranslation(mapper, OperatingSystem.Linux, kb, expected); + } + + function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void { + assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Linux)!, expected); + } + + test('kb => hw', () => { + // unchanged + assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.Digit1, 'ctrl+Digit1'); + assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.KeyB, 'ctrl+KeyB'); + assertKeybindingTranslation(KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyB, 'ctrl+shift+KeyB'); + assertKeybindingTranslation(KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyB, 'ctrl+shift+alt+meta+KeyB'); + + // flips Y and Z + assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.KeyZ, 'ctrl+KeyY'); + assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.KeyY, 'ctrl+KeyZ'); + + // Ctrl+/ + assertKeybindingTranslation(KeyMod.CtrlCmd | KeyCode.Slash, 'ctrl+shift+Digit7'); + }); + + test('resolveKeybinding Ctrl+A', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.KeyA, + [{ + label: 'Ctrl+A', + ariaLabel: 'Control+A', + electronAccelerator: 'Ctrl+A', + userSettingsLabel: 'ctrl+a', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[KeyA]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+Z', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.KeyZ, + [{ + label: 'Ctrl+Z', + ariaLabel: 'Control+Z', + electronAccelerator: 'Ctrl+Z', + userSettingsLabel: 'ctrl+z', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[KeyY]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeyboardEvent Ctrl+[KeyY]', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'KeyY' + }, + { + label: 'Ctrl+Z', + ariaLabel: 'Control+Z', + electronAccelerator: 'Ctrl+Z', + userSettingsLabel: 'ctrl+z', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[KeyY]'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveKeybinding Ctrl+]', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.BracketRight, + [] + ); + }); + + test('resolveKeyboardEvent Ctrl+[BracketRight]', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'BracketRight' + }, + { + label: 'Ctrl+¨', + ariaLabel: 'Control+¨', + electronAccelerator: null, + userSettingsLabel: 'ctrl+[BracketRight]', + isWYSIWYG: false, + isChord: false, + dispatchParts: ['ctrl+[BracketRight]'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveKeybinding Shift+]', () => { + _assertResolveKeybinding( + KeyMod.Shift | KeyCode.BracketRight, + [{ + label: 'Ctrl+Alt+0', + ariaLabel: 'Control+Alt+0', + electronAccelerator: 'Ctrl+Alt+0', + userSettingsLabel: 'ctrl+alt+0', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+alt+[Digit0]'], + singleModifierDispatchParts: [null], + }, { + label: 'Ctrl+Alt+$', + ariaLabel: 'Control+Alt+$', + electronAccelerator: null, + userSettingsLabel: 'ctrl+alt+[Backslash]', + isWYSIWYG: false, + isChord: false, + dispatchParts: ['ctrl+alt+[Backslash]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+/', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.Slash, + [{ + label: 'Ctrl+Shift+7', + ariaLabel: 'Control+Shift+7', + electronAccelerator: 'Ctrl+Shift+7', + userSettingsLabel: 'ctrl+shift+7', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+shift+[Digit7]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+Shift+/', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Slash, + [{ + label: 'Ctrl+Shift+\'', + ariaLabel: 'Control+Shift+\'', + electronAccelerator: null, + userSettingsLabel: 'ctrl+shift+[Minus]', + isWYSIWYG: false, + isChord: false, + dispatchParts: ['ctrl+shift+[Minus]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+K Ctrl+\\', () => { + _assertResolveKeybinding( + KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Backslash), + [] + ); + }); + + test('resolveKeybinding Ctrl+K Ctrl+=', () => { + _assertResolveKeybinding( + KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Equal), + [{ + label: 'Ctrl+K Ctrl+Shift+0', + ariaLabel: 'Control+K Control+Shift+0', + electronAccelerator: null, + userSettingsLabel: 'ctrl+k ctrl+shift+0', + isWYSIWYG: true, + isChord: true, + dispatchParts: ['ctrl+[KeyK]', 'ctrl+shift+[Digit0]'], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveKeybinding Ctrl+DownArrow', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.DownArrow, + [{ + label: 'Ctrl+DownArrow', + ariaLabel: 'Control+DownArrow', + electronAccelerator: 'Ctrl+Down', + userSettingsLabel: 'ctrl+down', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[ArrowDown]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+NUMPAD_0', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.Numpad0, + [{ + label: 'Ctrl+NumPad0', + ariaLabel: 'Control+NumPad0', + electronAccelerator: null, + userSettingsLabel: 'ctrl+numpad0', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[Numpad0]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+Home', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.Home, + [{ + label: 'Ctrl+Home', + ariaLabel: 'Control+Home', + electronAccelerator: 'Ctrl+Home', + userSettingsLabel: 'ctrl+home', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[Home]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeyboardEvent Ctrl+[Home]', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'Home' + }, + { + label: 'Ctrl+Home', + ariaLabel: 'Control+Home', + electronAccelerator: 'Ctrl+Home', + userSettingsLabel: 'ctrl+home', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[Home]'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveKeyboardEvent Ctrl+[KeyX]', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'KeyX' + }, + { + label: 'Ctrl+X', + ariaLabel: 'Control+X', + electronAccelerator: 'Ctrl+X', + userSettingsLabel: 'ctrl+x', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[KeyX]'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveUserBinding Ctrl+[Comma] Ctrl+/', () => { + assertResolveUserBinding( + mapper, [ + new ScanCodeBinding(true, false, false, false, ScanCode.Comma), + new SimpleKeybinding(true, false, false, false, KeyCode.Slash), + ], + [{ + label: 'Ctrl+, Ctrl+Shift+7', + ariaLabel: 'Control+, Control+Shift+7', + electronAccelerator: null, + userSettingsLabel: 'ctrl+[Comma] ctrl+shift+7', + isWYSIWYG: false, + isChord: true, + dispatchParts: ['ctrl+[Comma]', 'ctrl+shift+[Digit7]'], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveKeyboardEvent Single Modifier ControlLeft+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'ControlLeft' + }, + { + label: 'Ctrl', + ariaLabel: 'Control', + electronAccelerator: null, + userSettingsLabel: 'ctrl', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['ctrl'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier ControlRight+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'ControlRight' + }, + { + label: 'Ctrl', + ariaLabel: 'Control', + electronAccelerator: null, + userSettingsLabel: 'ctrl', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['ctrl'], + } + ); + }); +}); + +suite('keyboardMapper - LINUX en_us', () => { + + let mapper: MacLinuxKeyboardMapper; + + suiteSetup(async () => { + const _mapper = await createKeyboardMapper(true, 'linux_en_us', OperatingSystem.Linux); + mapper = _mapper; + }); + + test('mapping', () => { + return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'linux_en_us.txt'); + }); + + function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void { + assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Linux)!, expected); + } + + test('resolveKeybinding Ctrl+A', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.KeyA, + [{ + label: 'Ctrl+A', + ariaLabel: 'Control+A', + electronAccelerator: 'Ctrl+A', + userSettingsLabel: 'ctrl+a', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[KeyA]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+Z', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.KeyZ, + [{ + label: 'Ctrl+Z', + ariaLabel: 'Control+Z', + electronAccelerator: 'Ctrl+Z', + userSettingsLabel: 'ctrl+z', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[KeyZ]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeyboardEvent Ctrl+[KeyZ]', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'KeyZ' + }, + { + label: 'Ctrl+Z', + ariaLabel: 'Control+Z', + electronAccelerator: 'Ctrl+Z', + userSettingsLabel: 'ctrl+z', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[KeyZ]'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveKeybinding Ctrl+]', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.BracketRight, + [{ + label: 'Ctrl+]', + ariaLabel: 'Control+]', + electronAccelerator: 'Ctrl+]', + userSettingsLabel: 'ctrl+]', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[BracketRight]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeyboardEvent Ctrl+[BracketRight]', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'BracketRight' + }, + { + label: 'Ctrl+]', + ariaLabel: 'Control+]', + electronAccelerator: 'Ctrl+]', + userSettingsLabel: 'ctrl+]', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[BracketRight]'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveKeybinding Shift+]', () => { + _assertResolveKeybinding( + KeyMod.Shift | KeyCode.BracketRight, + [{ + label: 'Shift+]', + ariaLabel: 'Shift+]', + electronAccelerator: 'Shift+]', + userSettingsLabel: 'shift+]', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['shift+[BracketRight]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+/', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.Slash, + [{ + label: 'Ctrl+/', + ariaLabel: 'Control+/', + electronAccelerator: 'Ctrl+/', + userSettingsLabel: 'ctrl+/', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[Slash]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+Shift+/', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Slash, + [{ + label: 'Ctrl+Shift+/', + ariaLabel: 'Control+Shift+/', + electronAccelerator: 'Ctrl+Shift+/', + userSettingsLabel: 'ctrl+shift+/', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+shift+[Slash]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+K Ctrl+\\', () => { + _assertResolveKeybinding( + KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Backslash), + [{ + label: 'Ctrl+K Ctrl+\\', + ariaLabel: 'Control+K Control+\\', + electronAccelerator: null, + userSettingsLabel: 'ctrl+k ctrl+\\', + isWYSIWYG: true, + isChord: true, + dispatchParts: ['ctrl+[KeyK]', 'ctrl+[Backslash]'], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveKeybinding Ctrl+K Ctrl+=', () => { + _assertResolveKeybinding( + KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Equal), + [{ + label: 'Ctrl+K Ctrl+=', + ariaLabel: 'Control+K Control+=', + electronAccelerator: null, + userSettingsLabel: 'ctrl+k ctrl+=', + isWYSIWYG: true, + isChord: true, + dispatchParts: ['ctrl+[KeyK]', 'ctrl+[Equal]'], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveKeybinding Ctrl+DownArrow', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.DownArrow, + [{ + label: 'Ctrl+DownArrow', + ariaLabel: 'Control+DownArrow', + electronAccelerator: 'Ctrl+Down', + userSettingsLabel: 'ctrl+down', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[ArrowDown]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+NUMPAD_0', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.Numpad0, + [{ + label: 'Ctrl+NumPad0', + ariaLabel: 'Control+NumPad0', + electronAccelerator: null, + userSettingsLabel: 'ctrl+numpad0', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[Numpad0]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+Home', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.Home, + [{ + label: 'Ctrl+Home', + ariaLabel: 'Control+Home', + electronAccelerator: 'Ctrl+Home', + userSettingsLabel: 'ctrl+home', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[Home]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeyboardEvent Ctrl+[Home]', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'Home' + }, + { + label: 'Ctrl+Home', + ariaLabel: 'Control+Home', + electronAccelerator: 'Ctrl+Home', + userSettingsLabel: 'ctrl+home', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[Home]'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveKeybinding Ctrl+Shift+,', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Comma, + [{ + label: 'Ctrl+Shift+,', + ariaLabel: 'Control+Shift+,', + electronAccelerator: 'Ctrl+Shift+,', + userSettingsLabel: 'ctrl+shift+,', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+shift+[Comma]'], + singleModifierDispatchParts: [null], + }, { + label: 'Ctrl+<', + ariaLabel: 'Control+<', + electronAccelerator: null, + userSettingsLabel: 'ctrl+[IntlBackslash]', + isWYSIWYG: false, + isChord: false, + dispatchParts: ['ctrl+[IntlBackslash]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('issue #23393: resolveKeybinding Ctrl+Enter', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.Enter, + [{ + label: 'Ctrl+Enter', + ariaLabel: 'Control+Enter', + electronAccelerator: 'Ctrl+Enter', + userSettingsLabel: 'ctrl+enter', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[Enter]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('issue #23393: resolveKeyboardEvent Ctrl+[NumpadEnter]', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'NumpadEnter' + }, + { + label: 'Ctrl+Enter', + ariaLabel: 'Control+Enter', + electronAccelerator: 'Ctrl+Enter', + userSettingsLabel: 'ctrl+enter', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[Enter]'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveUserBinding Ctrl+[Comma] Ctrl+/', () => { + assertResolveUserBinding( + mapper, [ + new ScanCodeBinding(true, false, false, false, ScanCode.Comma), + new SimpleKeybinding(true, false, false, false, KeyCode.Slash), + ], + [{ + label: 'Ctrl+, Ctrl+/', + ariaLabel: 'Control+, Control+/', + electronAccelerator: null, + userSettingsLabel: 'ctrl+, ctrl+/', + isWYSIWYG: true, + isChord: true, + dispatchParts: ['ctrl+[Comma]', 'ctrl+[Slash]'], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveUserBinding Ctrl+[Comma]', () => { + assertResolveUserBinding( + mapper, [ + new ScanCodeBinding(true, false, false, false, ScanCode.Comma) + ], + [{ + label: 'Ctrl+,', + ariaLabel: 'Control+,', + electronAccelerator: 'Ctrl+,', + userSettingsLabel: 'ctrl+,', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[Comma]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeyboardEvent Single Modifier ControlLeft+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'ControlLeft' + }, + { + label: 'Ctrl', + ariaLabel: 'Control', + electronAccelerator: null, + userSettingsLabel: 'ctrl', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['ctrl'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier ControlRight+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'ControlRight' + }, + { + label: 'Ctrl', + ariaLabel: 'Control', + electronAccelerator: null, + userSettingsLabel: 'ctrl', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['ctrl'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier ShiftLeft+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: true, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'ShiftLeft' + }, + { + label: 'Shift', + ariaLabel: 'Shift', + electronAccelerator: null, + userSettingsLabel: 'shift', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['shift'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier ShiftRight+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: true, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'ShiftRight' + }, + { + label: 'Shift', + ariaLabel: 'Shift', + electronAccelerator: null, + userSettingsLabel: 'shift', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['shift'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier AltLeft+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: true, + metaKey: false, + keyCode: -1, + code: 'AltLeft' + }, + { + label: 'Alt', + ariaLabel: 'Alt', + electronAccelerator: null, + userSettingsLabel: 'alt', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['alt'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier AltRight+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: true, + metaKey: false, + keyCode: -1, + code: 'AltRight' + }, + { + label: 'Alt', + ariaLabel: 'Alt', + electronAccelerator: null, + userSettingsLabel: 'alt', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['alt'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier MetaLeft+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: true, + keyCode: -1, + code: 'MetaLeft' + }, + { + label: 'Super', + ariaLabel: 'Super', + electronAccelerator: null, + userSettingsLabel: 'meta', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['meta'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier MetaRight+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: true, + keyCode: -1, + code: 'MetaRight' + }, + { + label: 'Super', + ariaLabel: 'Super', + electronAccelerator: null, + userSettingsLabel: 'meta', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['meta'], + } + ); + }); + + test('resolveKeyboardEvent Only Modifiers Ctrl+Shift+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: true, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'ShiftLeft' + }, + { + label: 'Ctrl+Shift', + ariaLabel: 'Control+Shift', + electronAccelerator: null, + userSettingsLabel: 'ctrl+shift', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: [null], + } + ); + }); +}); + +suite('keyboardMapper', () => { + + test('issue #23706: Linux UK layout: Ctrl + Apostrophe also toggles terminal', () => { + const mapper = new MacLinuxKeyboardMapper(false, { + 'Backquote': { + 'value': '`', + 'withShift': '¬', + 'withAltGr': '|', + 'withShiftAltGr': '|' + } + }, OperatingSystem.Linux); + + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'Backquote' + }, + { + label: 'Ctrl+`', + ariaLabel: 'Control+`', + electronAccelerator: null, + userSettingsLabel: 'ctrl+`', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[Backquote]'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('issue #24064: NumLock/NumPad keys stopped working in 1.11 on Linux', () => { + const mapper = new MacLinuxKeyboardMapper(false, {}, OperatingSystem.Linux); + + function assertNumpadKeyboardEvent(keyCode: KeyCode, code: string, label: string, electronAccelerator: string | null, userSettingsLabel: string, dispatch: string): void { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: keyCode, + code: code + }, + { + label: label, + ariaLabel: label, + electronAccelerator: electronAccelerator, + userSettingsLabel: userSettingsLabel, + isWYSIWYG: true, + isChord: false, + dispatchParts: [dispatch], + singleModifierDispatchParts: [null], + } + ); + } + + assertNumpadKeyboardEvent(KeyCode.End, 'Numpad1', 'End', 'End', 'end', '[End]'); + assertNumpadKeyboardEvent(KeyCode.DownArrow, 'Numpad2', 'DownArrow', 'Down', 'down', '[ArrowDown]'); + assertNumpadKeyboardEvent(KeyCode.PageDown, 'Numpad3', 'PageDown', 'PageDown', 'pagedown', '[PageDown]'); + assertNumpadKeyboardEvent(KeyCode.LeftArrow, 'Numpad4', 'LeftArrow', 'Left', 'left', '[ArrowLeft]'); + assertNumpadKeyboardEvent(KeyCode.Unknown, 'Numpad5', 'NumPad5', null!, 'numpad5', '[Numpad5]'); + assertNumpadKeyboardEvent(KeyCode.RightArrow, 'Numpad6', 'RightArrow', 'Right', 'right', '[ArrowRight]'); + assertNumpadKeyboardEvent(KeyCode.Home, 'Numpad7', 'Home', 'Home', 'home', '[Home]'); + assertNumpadKeyboardEvent(KeyCode.UpArrow, 'Numpad8', 'UpArrow', 'Up', 'up', '[ArrowUp]'); + assertNumpadKeyboardEvent(KeyCode.PageUp, 'Numpad9', 'PageUp', 'PageUp', 'pageup', '[PageUp]'); + assertNumpadKeyboardEvent(KeyCode.Insert, 'Numpad0', 'Insert', 'Insert', 'insert', '[Insert]'); + assertNumpadKeyboardEvent(KeyCode.Delete, 'NumpadDecimal', 'Delete', 'Delete', 'delete', '[Delete]'); + }); + + test('issue #24107: Delete, Insert, Home, End, PgUp, PgDn, and arrow keys no longer work editor in 1.11', () => { + const mapper = new MacLinuxKeyboardMapper(false, {}, OperatingSystem.Linux); + + function assertKeyboardEvent(keyCode: KeyCode, code: string, label: string, electronAccelerator: string, userSettingsLabel: string, dispatch: string): void { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: keyCode, + code: code + }, + { + label: label, + ariaLabel: label, + electronAccelerator: electronAccelerator, + userSettingsLabel: userSettingsLabel, + isWYSIWYG: true, + isChord: false, + dispatchParts: [dispatch], + singleModifierDispatchParts: [null], + } + ); + } + + // https://github.com/microsoft/vscode/issues/24107#issuecomment-292318497 + assertKeyboardEvent(KeyCode.UpArrow, 'Lang3', 'UpArrow', 'Up', 'up', '[ArrowUp]'); + assertKeyboardEvent(KeyCode.DownArrow, 'NumpadEnter', 'DownArrow', 'Down', 'down', '[ArrowDown]'); + assertKeyboardEvent(KeyCode.LeftArrow, 'Convert', 'LeftArrow', 'Left', 'left', '[ArrowLeft]'); + assertKeyboardEvent(KeyCode.RightArrow, 'NonConvert', 'RightArrow', 'Right', 'right', '[ArrowRight]'); + assertKeyboardEvent(KeyCode.Delete, 'PrintScreen', 'Delete', 'Delete', 'delete', '[Delete]'); + assertKeyboardEvent(KeyCode.Insert, 'NumpadDivide', 'Insert', 'Insert', 'insert', '[Insert]'); + assertKeyboardEvent(KeyCode.End, 'Unknown', 'End', 'End', 'end', '[End]'); + assertKeyboardEvent(KeyCode.Home, 'IntlRo', 'Home', 'Home', 'home', '[Home]'); + assertKeyboardEvent(KeyCode.PageDown, 'ControlRight', 'PageDown', 'PageDown', 'pagedown', '[PageDown]'); + assertKeyboardEvent(KeyCode.PageUp, 'Lang4', 'PageUp', 'PageUp', 'pageup', '[PageUp]'); + + // https://github.com/microsoft/vscode/issues/24107#issuecomment-292323924 + assertKeyboardEvent(KeyCode.PageDown, 'ControlRight', 'PageDown', 'PageDown', 'pagedown', '[PageDown]'); + assertKeyboardEvent(KeyCode.PageUp, 'Lang4', 'PageUp', 'PageUp', 'pageup', '[PageUp]'); + assertKeyboardEvent(KeyCode.End, '', 'End', 'End', 'end', '[End]'); + assertKeyboardEvent(KeyCode.Home, 'IntlRo', 'Home', 'Home', 'home', '[Home]'); + assertKeyboardEvent(KeyCode.Delete, 'PrintScreen', 'Delete', 'Delete', 'delete', '[Delete]'); + assertKeyboardEvent(KeyCode.Insert, 'NumpadDivide', 'Insert', 'Insert', 'insert', '[Insert]'); + assertKeyboardEvent(KeyCode.RightArrow, 'NonConvert', 'RightArrow', 'Right', 'right', '[ArrowRight]'); + assertKeyboardEvent(KeyCode.LeftArrow, 'Convert', 'LeftArrow', 'Left', 'left', '[ArrowLeft]'); + assertKeyboardEvent(KeyCode.DownArrow, 'NumpadEnter', 'DownArrow', 'Down', 'down', '[ArrowDown]'); + assertKeyboardEvent(KeyCode.UpArrow, 'Lang3', 'UpArrow', 'Up', 'up', '[ArrowUp]'); + }); +}); + +suite('keyboardMapper - LINUX ru', () => { + + let mapper: MacLinuxKeyboardMapper; + + suiteSetup(async () => { + const _mapper = await createKeyboardMapper(false, 'linux_ru', OperatingSystem.Linux); + mapper = _mapper; + }); + + test('mapping', () => { + return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'linux_ru.txt'); + }); + + function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void { + assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Linux)!, expected); + } + + test('resolveKeybinding Ctrl+S', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.KeyS, + [{ + label: 'Ctrl+S', + ariaLabel: 'Control+S', + electronAccelerator: 'Ctrl+S', + userSettingsLabel: 'ctrl+s', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+[KeyS]'], + singleModifierDispatchParts: [null], + }] + ); + }); +}); + +suite('keyboardMapper - LINUX en_uk', () => { + + let mapper: MacLinuxKeyboardMapper; + + suiteSetup(async () => { + const _mapper = await createKeyboardMapper(false, 'linux_en_uk', OperatingSystem.Linux); + mapper = _mapper; + }); + + test('mapping', () => { + return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'linux_en_uk.txt'); + }); + + test('issue #24522: resolveKeyboardEvent Ctrl+Alt+[Minus]', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: true, + metaKey: false, + keyCode: -1, + code: 'Minus' + }, + { + label: 'Ctrl+Alt+-', + ariaLabel: 'Control+Alt+-', + electronAccelerator: null, + userSettingsLabel: 'ctrl+alt+[Minus]', + isWYSIWYG: false, + isChord: false, + dispatchParts: ['ctrl+alt+[Minus]'], + singleModifierDispatchParts: [null], + } + ); + }); +}); + +suite('keyboardMapper - MAC zh_hant', () => { + + let mapper: MacLinuxKeyboardMapper; + + suiteSetup(async () => { + const _mapper = await createKeyboardMapper(false, 'mac_zh_hant', OperatingSystem.Macintosh); + mapper = _mapper; + }); + + test('mapping', () => { + return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'mac_zh_hant.txt'); + }); + + function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void { + assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Macintosh)!, expected); + } + + test('issue #28237 resolveKeybinding Cmd+C', () => { + _assertResolveKeybinding( + KeyMod.CtrlCmd | KeyCode.KeyC, + [{ + label: '⌘C', + ariaLabel: 'Command+C', + electronAccelerator: 'Cmd+C', + userSettingsLabel: 'cmd+c', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['meta+[KeyC]'], + singleModifierDispatchParts: [null], + }] + ); + }); +}); + +suite('keyboardMapper - MAC zh_hant2', () => { + + let mapper: MacLinuxKeyboardMapper; + + suiteSetup(async () => { + const _mapper = await createKeyboardMapper(false, 'mac_zh_hant2', OperatingSystem.Macintosh); + mapper = _mapper; + }); + + test('mapping', () => { + return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'mac_zh_hant2.txt'); + }); +}); + +function _assertKeybindingTranslation(mapper: MacLinuxKeyboardMapper, OS: OperatingSystem, kb: number, _expected: string | string[]): void { + let expected: string[]; + if (typeof _expected === 'string') { + expected = [_expected]; + } else if (Array.isArray(_expected)) { + expected = _expected; + } else { + expected = []; + } + + const runtimeKeybinding = createSimpleKeybinding(kb, OS); + + const keybindingLabel = new USLayoutResolvedKeybinding(runtimeKeybinding.toChord(), OS).getUserSettingsLabel(); + + const actualHardwareKeypresses = mapper.simpleKeybindingToScanCodeBinding(runtimeKeybinding); + if (actualHardwareKeypresses.length === 0) { + assert.deepStrictEqual([], expected, `simpleKeybindingToHardwareKeypress -- "${keybindingLabel}" -- actual: "[]" -- expected: "${expected}"`); + return; + } + + const actual = actualHardwareKeypresses + .map(k => UserSettingsLabelProvider.toLabel(OS, [k], (keybinding) => ScanCodeUtils.toString(keybinding.scanCode))); + assert.deepStrictEqual(actual, expected, `simpleKeybindingToHardwareKeypress -- "${keybindingLabel}" -- actual: "${actual}" -- expected: "${expected}"`); +} diff --git a/src/vs/workbench/services/keybinding/test/node/mac_de_ch.js b/src/vs/workbench/services/keybinding/test/node/mac_de_ch.js new file mode 100644 index 00000000000..6da177d6785 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/mac_de_ch.js @@ -0,0 +1,1188 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +define({ + KeyA: { + value: 'a', + valueIsDeadKey: false, + withShift: 'A', + withShiftIsDeadKey: false, + withAltGr: 'å', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Å', + withShiftAltGrIsDeadKey: false + }, + KeyB: { + value: 'b', + valueIsDeadKey: false, + withShift: 'B', + withShiftIsDeadKey: false, + withAltGr: '∫', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + KeyC: { + value: 'c', + valueIsDeadKey: false, + withShift: 'C', + withShiftIsDeadKey: false, + withAltGr: '©', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + KeyD: { + value: 'd', + valueIsDeadKey: false, + withShift: 'D', + withShiftIsDeadKey: false, + withAltGr: '∂', + withAltGrIsDeadKey: false, + withShiftAltGr: 'fl', + withShiftAltGrIsDeadKey: false + }, + KeyE: { + value: 'e', + valueIsDeadKey: false, + withShift: 'E', + withShiftIsDeadKey: false, + withAltGr: '€', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ë', + withShiftAltGrIsDeadKey: false + }, + KeyF: { + value: 'f', + valueIsDeadKey: false, + withShift: 'F', + withShiftIsDeadKey: false, + withAltGr: 'ƒ', + withAltGrIsDeadKey: false, + withShiftAltGr: '‡', + withShiftAltGrIsDeadKey: false + }, + KeyG: { + value: 'g', + valueIsDeadKey: false, + withShift: 'G', + withShiftIsDeadKey: false, + withAltGr: '@', + withAltGrIsDeadKey: false, + withShiftAltGr: '‚', + withShiftAltGrIsDeadKey: false + }, + KeyH: { + value: 'h', + valueIsDeadKey: false, + withShift: 'H', + withShiftIsDeadKey: false, + withAltGr: 'ª', + withAltGrIsDeadKey: false, + withShiftAltGr: '·', + withShiftAltGrIsDeadKey: false + }, + KeyI: { + value: 'i', + valueIsDeadKey: false, + withShift: 'I', + withShiftIsDeadKey: false, + withAltGr: '¡', + withAltGrIsDeadKey: false, + withShiftAltGr: 'ı', + withShiftAltGrIsDeadKey: false + }, + KeyJ: { + value: 'j', + valueIsDeadKey: false, + withShift: 'J', + withShiftIsDeadKey: false, + withAltGr: 'º', + withAltGrIsDeadKey: false, + withShiftAltGr: '˜', + withShiftAltGrIsDeadKey: false + }, + KeyK: { + value: 'k', + valueIsDeadKey: false, + withShift: 'K', + withShiftIsDeadKey: false, + withAltGr: '∆', + withAltGrIsDeadKey: false, + withShiftAltGr: '¯', + withShiftAltGrIsDeadKey: false + }, + KeyL: { + value: 'l', + valueIsDeadKey: false, + withShift: 'L', + withShiftIsDeadKey: false, + withAltGr: '¬', + withAltGrIsDeadKey: false, + withShiftAltGr: 'ˆ', + withShiftAltGrIsDeadKey: false + }, + KeyM: { + value: 'm', + valueIsDeadKey: false, + withShift: 'M', + withShiftIsDeadKey: false, + withAltGr: 'µ', + withAltGrIsDeadKey: false, + withShiftAltGr: '˚', + withShiftAltGrIsDeadKey: false + }, + KeyN: { + value: 'n', + valueIsDeadKey: false, + withShift: 'N', + withShiftIsDeadKey: false, + withAltGr: '~', + withAltGrIsDeadKey: true, + withShiftAltGr: '˙', + withShiftAltGrIsDeadKey: false + }, + KeyO: { + value: 'o', + valueIsDeadKey: false, + withShift: 'O', + withShiftIsDeadKey: false, + withAltGr: 'ø', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ø', + withShiftAltGrIsDeadKey: false + }, + KeyP: { + value: 'p', + valueIsDeadKey: false, + withShift: 'P', + withShiftIsDeadKey: false, + withAltGr: 'π', + withAltGrIsDeadKey: false, + withShiftAltGr: '∏', + withShiftAltGrIsDeadKey: false + }, + KeyQ: { + value: 'q', + valueIsDeadKey: false, + withShift: 'Q', + withShiftIsDeadKey: false, + withAltGr: 'œ', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Œ', + withShiftAltGrIsDeadKey: false + }, + KeyR: { + value: 'r', + valueIsDeadKey: false, + withShift: 'R', + withShiftIsDeadKey: false, + withAltGr: '®', + withAltGrIsDeadKey: false, + withShiftAltGr: 'È', + withShiftAltGrIsDeadKey: false + }, + KeyS: { + value: 's', + valueIsDeadKey: false, + withShift: 'S', + withShiftIsDeadKey: false, + withAltGr: 'ß', + withAltGrIsDeadKey: false, + withShiftAltGr: 'fi', + withShiftAltGrIsDeadKey: false + }, + KeyT: { + value: 't', + valueIsDeadKey: false, + withShift: 'T', + withShiftIsDeadKey: false, + withAltGr: '†', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Î', + withShiftAltGrIsDeadKey: false + }, + KeyU: { + value: 'u', + valueIsDeadKey: false, + withShift: 'U', + withShiftIsDeadKey: false, + withAltGr: '°', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ù', + withShiftAltGrIsDeadKey: false + }, + KeyV: { + value: 'v', + valueIsDeadKey: false, + withShift: 'V', + withShiftIsDeadKey: false, + withAltGr: '√', + withAltGrIsDeadKey: false, + withShiftAltGr: '◊', + withShiftAltGrIsDeadKey: false + }, + KeyW: { + value: 'w', + valueIsDeadKey: false, + withShift: 'W', + withShiftIsDeadKey: false, + withAltGr: '∑', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Á', + withShiftAltGrIsDeadKey: false + }, + KeyX: { + value: 'x', + valueIsDeadKey: false, + withShift: 'X', + withShiftIsDeadKey: false, + withAltGr: '≈', + withAltGrIsDeadKey: false, + withShiftAltGr: '™', + withShiftAltGrIsDeadKey: false + }, + KeyY: { + value: 'z', + valueIsDeadKey: false, + withShift: 'Z', + withShiftIsDeadKey: false, + withAltGr: 'Ω', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Í', + withShiftAltGrIsDeadKey: false + }, + KeyZ: { + value: 'y', + valueIsDeadKey: false, + withShift: 'Y', + withShiftIsDeadKey: false, + withAltGr: '¥', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ÿ', + withShiftAltGrIsDeadKey: false + }, + Digit1: { + value: '1', + valueIsDeadKey: false, + withShift: '+', + withShiftIsDeadKey: false, + withAltGr: '±', + withAltGrIsDeadKey: false, + withShiftAltGr: '∞', + withShiftAltGrIsDeadKey: false + }, + Digit2: { + value: '2', + valueIsDeadKey: false, + withShift: '"', + withShiftIsDeadKey: false, + withAltGr: '“', + withAltGrIsDeadKey: false, + withShiftAltGr: '”', + withShiftAltGrIsDeadKey: false + }, + Digit3: { + value: '3', + valueIsDeadKey: false, + withShift: '*', + withShiftIsDeadKey: false, + withAltGr: '#', + withAltGrIsDeadKey: false, + withShiftAltGr: '‹', + withShiftAltGrIsDeadKey: false + }, + Digit4: { + value: '4', + valueIsDeadKey: false, + withShift: 'ç', + withShiftIsDeadKey: false, + withAltGr: 'Ç', + withAltGrIsDeadKey: false, + withShiftAltGr: '⁄', + withShiftAltGrIsDeadKey: false + }, + Digit5: { + value: '5', + valueIsDeadKey: false, + withShift: '%', + withShiftIsDeadKey: false, + withAltGr: '[', + withAltGrIsDeadKey: false, + withShiftAltGr: '[', + withShiftAltGrIsDeadKey: false + }, + Digit6: { + value: '6', + valueIsDeadKey: false, + withShift: '&', + withShiftIsDeadKey: false, + withAltGr: ']', + withAltGrIsDeadKey: false, + withShiftAltGr: ']', + withShiftAltGrIsDeadKey: false + }, + Digit7: { + value: '7', + valueIsDeadKey: false, + withShift: '/', + withShiftIsDeadKey: false, + withAltGr: '|', + withAltGrIsDeadKey: false, + withShiftAltGr: '\\', + withShiftAltGrIsDeadKey: false + }, + Digit8: { + value: '8', + valueIsDeadKey: false, + withShift: '(', + withShiftIsDeadKey: false, + withAltGr: '{', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ò', + withShiftAltGrIsDeadKey: false + }, + Digit9: { + value: '9', + valueIsDeadKey: false, + withShift: ')', + withShiftIsDeadKey: false, + withAltGr: '}', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ô', + withShiftAltGrIsDeadKey: false + }, + Digit0: { + value: '0', + valueIsDeadKey: false, + withShift: '=', + withShiftIsDeadKey: false, + withAltGr: '≠', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ú', + withShiftAltGrIsDeadKey: false + }, + Enter: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Escape: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Backspace: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Tab: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Space: { + value: ' ', + valueIsDeadKey: false, + withShift: ' ', + withShiftIsDeadKey: false, + withAltGr: ' ', + withAltGrIsDeadKey: false, + withShiftAltGr: ' ', + withShiftAltGrIsDeadKey: false + }, + Minus: { + value: '\'', + valueIsDeadKey: false, + withShift: '?', + withShiftIsDeadKey: false, + withAltGr: '¿', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Equal: { + value: '^', + valueIsDeadKey: true, + withShift: '`', + withShiftIsDeadKey: true, + withAltGr: '´', + withAltGrIsDeadKey: true, + withShiftAltGr: '^', + withShiftAltGrIsDeadKey: false + }, + BracketLeft: { + value: 'ü', + valueIsDeadKey: false, + withShift: 'è', + withShiftIsDeadKey: false, + withAltGr: '§', + withAltGrIsDeadKey: false, + withShiftAltGr: 'ÿ', + withShiftAltGrIsDeadKey: false + }, + BracketRight: { + value: '¨', + valueIsDeadKey: true, + withShift: '!', + withShiftIsDeadKey: false, + withAltGr: '‘', + withAltGrIsDeadKey: false, + withShiftAltGr: '’', + withShiftAltGrIsDeadKey: false + }, + Backslash: { + value: '$', + valueIsDeadKey: false, + withShift: '£', + withShiftIsDeadKey: false, + withAltGr: '¶', + withAltGrIsDeadKey: false, + withShiftAltGr: '•', + withShiftAltGrIsDeadKey: false + }, + Semicolon: { + value: 'ö', + valueIsDeadKey: false, + withShift: 'é', + withShiftIsDeadKey: false, + withAltGr: '¢', + withAltGrIsDeadKey: false, + withShiftAltGr: '˘', + withShiftAltGrIsDeadKey: false + }, + Quote: { + value: 'ä', + valueIsDeadKey: false, + withShift: 'à', + withShiftIsDeadKey: false, + withAltGr: 'æ', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Æ', + withShiftAltGrIsDeadKey: false + }, + Backquote: { + value: '<', + valueIsDeadKey: false, + withShift: '>', + withShiftIsDeadKey: false, + withAltGr: '≤', + withAltGrIsDeadKey: false, + withShiftAltGr: '≥', + withShiftAltGrIsDeadKey: false + }, + Comma: { + value: ',', + valueIsDeadKey: false, + withShift: ';', + withShiftIsDeadKey: false, + withAltGr: '«', + withAltGrIsDeadKey: false, + withShiftAltGr: '»', + withShiftAltGrIsDeadKey: false + }, + Period: { + value: '.', + valueIsDeadKey: false, + withShift: ':', + withShiftIsDeadKey: false, + withAltGr: '…', + withAltGrIsDeadKey: false, + withShiftAltGr: '÷', + withShiftAltGrIsDeadKey: false + }, + Slash: { + value: '-', + valueIsDeadKey: false, + withShift: '_', + withShiftIsDeadKey: false, + withAltGr: '–', + withAltGrIsDeadKey: false, + withShiftAltGr: '—', + withShiftAltGrIsDeadKey: false + }, + CapsLock: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F1: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F2: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F3: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F4: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F5: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F6: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F7: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F8: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F9: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F10: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F11: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F12: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Insert: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Home: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + PageUp: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Delete: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + End: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + PageDown: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowDown: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowUp: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumLock: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumpadDivide: { + value: '/', + valueIsDeadKey: false, + withShift: '/', + withShiftIsDeadKey: false, + withAltGr: '/', + withAltGrIsDeadKey: false, + withShiftAltGr: '/', + withShiftAltGrIsDeadKey: false + }, + NumpadMultiply: { + value: '*', + valueIsDeadKey: false, + withShift: '*', + withShiftIsDeadKey: false, + withAltGr: '*', + withAltGrIsDeadKey: false, + withShiftAltGr: '*', + withShiftAltGrIsDeadKey: false + }, + NumpadSubtract: { + value: '-', + valueIsDeadKey: false, + withShift: '-', + withShiftIsDeadKey: false, + withAltGr: '-', + withAltGrIsDeadKey: false, + withShiftAltGr: '-', + withShiftAltGrIsDeadKey: false + }, + NumpadAdd: { + value: '+', + valueIsDeadKey: false, + withShift: '+', + withShiftIsDeadKey: false, + withAltGr: '+', + withAltGrIsDeadKey: false, + withShiftAltGr: '+', + withShiftAltGrIsDeadKey: false + }, + NumpadEnter: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Numpad1: { + value: '1', + valueIsDeadKey: false, + withShift: '1', + withShiftIsDeadKey: false, + withAltGr: '1', + withAltGrIsDeadKey: false, + withShiftAltGr: '1', + withShiftAltGrIsDeadKey: false + }, + Numpad2: { + value: '2', + valueIsDeadKey: false, + withShift: '2', + withShiftIsDeadKey: false, + withAltGr: '2', + withAltGrIsDeadKey: false, + withShiftAltGr: '2', + withShiftAltGrIsDeadKey: false + }, + Numpad3: { + value: '3', + valueIsDeadKey: false, + withShift: '3', + withShiftIsDeadKey: false, + withAltGr: '3', + withAltGrIsDeadKey: false, + withShiftAltGr: '3', + withShiftAltGrIsDeadKey: false + }, + Numpad4: { + value: '4', + valueIsDeadKey: false, + withShift: '4', + withShiftIsDeadKey: false, + withAltGr: '4', + withAltGrIsDeadKey: false, + withShiftAltGr: '4', + withShiftAltGrIsDeadKey: false + }, + Numpad5: { + value: '5', + valueIsDeadKey: false, + withShift: '5', + withShiftIsDeadKey: false, + withAltGr: '5', + withAltGrIsDeadKey: false, + withShiftAltGr: '5', + withShiftAltGrIsDeadKey: false + }, + Numpad6: { + value: '6', + valueIsDeadKey: false, + withShift: '6', + withShiftIsDeadKey: false, + withAltGr: '6', + withAltGrIsDeadKey: false, + withShiftAltGr: '6', + withShiftAltGrIsDeadKey: false + }, + Numpad7: { + value: '7', + valueIsDeadKey: false, + withShift: '7', + withShiftIsDeadKey: false, + withAltGr: '7', + withAltGrIsDeadKey: false, + withShiftAltGr: '7', + withShiftAltGrIsDeadKey: false + }, + Numpad8: { + value: '8', + valueIsDeadKey: false, + withShift: '8', + withShiftIsDeadKey: false, + withAltGr: '8', + withAltGrIsDeadKey: false, + withShiftAltGr: '8', + withShiftAltGrIsDeadKey: false + }, + Numpad9: { + value: '9', + valueIsDeadKey: false, + withShift: '9', + withShiftIsDeadKey: false, + withAltGr: '9', + withAltGrIsDeadKey: false, + withShiftAltGr: '9', + withShiftAltGrIsDeadKey: false + }, + Numpad0: { + value: '0', + valueIsDeadKey: false, + withShift: '0', + withShiftIsDeadKey: false, + withAltGr: '0', + withAltGrIsDeadKey: false, + withShiftAltGr: '0', + withShiftAltGrIsDeadKey: false + }, + NumpadDecimal: { + value: '.', + valueIsDeadKey: false, + withShift: ',', + withShiftIsDeadKey: false, + withAltGr: '.', + withAltGrIsDeadKey: false, + withShiftAltGr: '.', + withShiftAltGrIsDeadKey: false + }, + IntlBackslash: { + value: '§', + valueIsDeadKey: false, + withShift: '°', + withShiftIsDeadKey: false, + withAltGr: 'fi', + withAltGrIsDeadKey: false, + withShiftAltGr: '‰', + withShiftAltGrIsDeadKey: false + }, + ContextMenu: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumpadEqual: { + value: '=', + valueIsDeadKey: false, + withShift: '=', + withShiftIsDeadKey: false, + withAltGr: '=', + withAltGrIsDeadKey: false, + withShiftAltGr: '=', + withShiftAltGrIsDeadKey: false + }, + F13: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F14: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F15: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F16: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F17: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F18: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F19: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F20: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AudioVolumeMute: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AudioVolumeUp: { + value: '', + valueIsDeadKey: false, + withShift: '=', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '=', + withShiftAltGrIsDeadKey: false + }, + AudioVolumeDown: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumpadComma: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + IntlRo: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + KanaMode: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + IntlYen: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ControlLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ShiftLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AltLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + MetaLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ControlRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ShiftRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AltRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + MetaRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + } +}); diff --git a/src/vs/workbench/services/keybinding/test/node/mac_de_ch.txt b/src/vs/workbench/services/keybinding/test/node/mac_de_ch.txt new file mode 100644 index 00000000000..60627a704dc --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/mac_de_ch.txt @@ -0,0 +1,529 @@ +isUSStandard: false +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyA | a | A | | A | a | A | [KeyA] | | +| Ctrl+KeyA | a | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | +| Shift+KeyA | A | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | +| Ctrl+Shift+KeyA | A | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | +| Alt+KeyA | a | Alt+A | | Option+A | alt+a | Alt+A | alt+[KeyA] | | +| Ctrl+Alt+KeyA | å | Ctrl+Alt+A | | Ctrl+Option+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | +| Shift+Alt+KeyA | A | Shift+Alt+A | | Shift+Option+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | +| Ctrl+Shift+Alt+KeyA | Å | Ctrl+Shift+Alt+A | | Ctrl+Shift+Option+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyB | b | B | | B | b | B | [KeyB] | | +| Ctrl+KeyB | b | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | +| Shift+KeyB | B | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | +| Ctrl+Shift+KeyB | B | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | +| Alt+KeyB | b | Alt+B | | Option+B | alt+b | Alt+B | alt+[KeyB] | | +| Ctrl+Alt+KeyB | ∫ | Ctrl+Alt+B | | Ctrl+Option+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | +| Shift+Alt+KeyB | B | Shift+Alt+B | | Shift+Option+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | +| Ctrl+Shift+Alt+KeyB | --- | Ctrl+Shift+Alt+B | | Ctrl+Shift+Option+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyC | c | C | | C | c | C | [KeyC] | | +| Ctrl+KeyC | c | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | +| Shift+KeyC | C | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | +| Ctrl+Shift+KeyC | C | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | +| Alt+KeyC | c | Alt+C | | Option+C | alt+c | Alt+C | alt+[KeyC] | | +| Ctrl+Alt+KeyC | © | Ctrl+Alt+C | | Ctrl+Option+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | +| Shift+Alt+KeyC | C | Shift+Alt+C | | Shift+Option+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | +| Ctrl+Shift+Alt+KeyC | --- | Ctrl+Shift+Alt+C | | Ctrl+Shift+Option+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyD | d | D | | D | d | D | [KeyD] | | +| Ctrl+KeyD | d | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | +| Shift+KeyD | D | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | +| Ctrl+Shift+KeyD | D | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | +| Alt+KeyD | d | Alt+D | | Option+D | alt+d | Alt+D | alt+[KeyD] | | +| Ctrl+Alt+KeyD | ∂ | Ctrl+Alt+D | | Ctrl+Option+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | +| Shift+Alt+KeyD | D | Shift+Alt+D | | Shift+Option+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | +| Ctrl+Shift+Alt+KeyD | fl | Ctrl+Shift+Alt+D | | Ctrl+Shift+Option+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyE | e | E | | E | e | E | [KeyE] | | +| Ctrl+KeyE | e | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | +| Shift+KeyE | E | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | +| Ctrl+Shift+KeyE | E | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | +| Alt+KeyE | e | Alt+E | | Option+E | alt+e | Alt+E | alt+[KeyE] | | +| Ctrl+Alt+KeyE | € | Ctrl+Alt+E | | Ctrl+Option+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | +| Shift+Alt+KeyE | E | Shift+Alt+E | | Shift+Option+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | +| Ctrl+Shift+Alt+KeyE | Ë | Ctrl+Shift+Alt+E | | Ctrl+Shift+Option+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyF | f | F | | F | f | F | [KeyF] | | +| Ctrl+KeyF | f | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | +| Shift+KeyF | F | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | +| Ctrl+Shift+KeyF | F | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | +| Alt+KeyF | f | Alt+F | | Option+F | alt+f | Alt+F | alt+[KeyF] | | +| Ctrl+Alt+KeyF | ƒ | Ctrl+Alt+F | | Ctrl+Option+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | +| Shift+Alt+KeyF | F | Shift+Alt+F | | Shift+Option+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | +| Ctrl+Shift+Alt+KeyF | ‡ | Ctrl+Shift+Alt+F | | Ctrl+Shift+Option+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyG | g | G | | G | g | G | [KeyG] | | +| Ctrl+KeyG | g | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | +| Shift+KeyG | G | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | +| Ctrl+Shift+KeyG | G | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | +| Alt+KeyG | g | Alt+G | | Option+G | alt+g | Alt+G | alt+[KeyG] | | +| Ctrl+Alt+KeyG | @ | Ctrl+Alt+G | | Ctrl+Option+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | +| Shift+Alt+KeyG | G | Shift+Alt+G | | Shift+Option+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | +| Ctrl+Shift+Alt+KeyG | ‚ | Ctrl+Shift+Alt+G | | Ctrl+Shift+Option+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyH | h | H | | H | h | H | [KeyH] | | +| Ctrl+KeyH | h | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | +| Shift+KeyH | H | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | +| Ctrl+Shift+KeyH | H | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | +| Alt+KeyH | h | Alt+H | | Option+H | alt+h | Alt+H | alt+[KeyH] | | +| Ctrl+Alt+KeyH | ª | Ctrl+Alt+H | | Ctrl+Option+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | +| Shift+Alt+KeyH | H | Shift+Alt+H | | Shift+Option+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | +| Ctrl+Shift+Alt+KeyH | · | Ctrl+Shift+Alt+H | | Ctrl+Shift+Option+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyI | i | I | | I | i | I | [KeyI] | | +| Ctrl+KeyI | i | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | +| Shift+KeyI | I | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | +| Ctrl+Shift+KeyI | I | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | +| Alt+KeyI | i | Alt+I | | Option+I | alt+i | Alt+I | alt+[KeyI] | | +| Ctrl+Alt+KeyI | ¡ | Ctrl+Alt+I | | Ctrl+Option+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | +| Shift+Alt+KeyI | I | Shift+Alt+I | | Shift+Option+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | +| Ctrl+Shift+Alt+KeyI | ı | Ctrl+Shift+Alt+I | | Ctrl+Shift+Option+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyJ | j | J | | J | j | J | [KeyJ] | | +| Ctrl+KeyJ | j | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | +| Shift+KeyJ | J | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | +| Ctrl+Shift+KeyJ | J | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | +| Alt+KeyJ | j | Alt+J | | Option+J | alt+j | Alt+J | alt+[KeyJ] | | +| Ctrl+Alt+KeyJ | º | Ctrl+Alt+J | | Ctrl+Option+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | +| Shift+Alt+KeyJ | J | Shift+Alt+J | | Shift+Option+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | +| Ctrl+Shift+Alt+KeyJ | ˜ | Ctrl+Shift+Alt+J | | Ctrl+Shift+Option+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyK | k | K | | K | k | K | [KeyK] | | +| Ctrl+KeyK | k | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | +| Shift+KeyK | K | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | +| Ctrl+Shift+KeyK | K | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | +| Alt+KeyK | k | Alt+K | | Option+K | alt+k | Alt+K | alt+[KeyK] | | +| Ctrl+Alt+KeyK | ∆ | Ctrl+Alt+K | | Ctrl+Option+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | +| Shift+Alt+KeyK | K | Shift+Alt+K | | Shift+Option+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | +| Ctrl+Shift+Alt+KeyK | ¯ | Ctrl+Shift+Alt+K | | Ctrl+Shift+Option+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyL | l | L | | L | l | L | [KeyL] | | +| Ctrl+KeyL | l | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | +| Shift+KeyL | L | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | +| Ctrl+Shift+KeyL | L | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | +| Alt+KeyL | l | Alt+L | | Option+L | alt+l | Alt+L | alt+[KeyL] | | +| Ctrl+Alt+KeyL | ¬ | Ctrl+Alt+L | | Ctrl+Option+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | +| Shift+Alt+KeyL | L | Shift+Alt+L | | Shift+Option+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | +| Ctrl+Shift+Alt+KeyL | ˆ | Ctrl+Shift+Alt+L | | Ctrl+Shift+Option+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyM | m | M | | M | m | M | [KeyM] | | +| Ctrl+KeyM | m | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | +| Shift+KeyM | M | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | +| Ctrl+Shift+KeyM | M | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | +| Alt+KeyM | m | Alt+M | | Option+M | alt+m | Alt+M | alt+[KeyM] | | +| Ctrl+Alt+KeyM | µ | Ctrl+Alt+M | | Ctrl+Option+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | +| Shift+Alt+KeyM | M | Shift+Alt+M | | Shift+Option+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | +| Ctrl+Shift+Alt+KeyM | ˚ | Ctrl+Shift+Alt+M | | Ctrl+Shift+Option+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyN | n | N | | N | n | N | [KeyN] | | +| Ctrl+KeyN | n | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | +| Shift+KeyN | N | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | +| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | +| Alt+KeyN | n | Alt+N | | Option+N | alt+n | Alt+N | alt+[KeyN] | | +| Ctrl+Alt+KeyN | ~ | Ctrl+Alt+N | | Ctrl+Option+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | +| | | Shift+` | | | | | | | +| Shift+Alt+KeyN | N | Shift+Alt+N | | Shift+Option+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | +| Ctrl+Shift+Alt+KeyN | ˙ | Ctrl+Shift+Alt+N | | Ctrl+Shift+Option+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyO | o | O | | O | o | O | [KeyO] | | +| Ctrl+KeyO | o | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | +| Shift+KeyO | O | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | +| Ctrl+Shift+KeyO | O | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | +| Alt+KeyO | o | Alt+O | | Option+O | alt+o | Alt+O | alt+[KeyO] | | +| Ctrl+Alt+KeyO | ø | Ctrl+Alt+O | | Ctrl+Option+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | +| Shift+Alt+KeyO | O | Shift+Alt+O | | Shift+Option+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | +| Ctrl+Shift+Alt+KeyO | Ø | Ctrl+Shift+Alt+O | | Ctrl+Shift+Option+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyP | p | P | | P | p | P | [KeyP] | | +| Ctrl+KeyP | p | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | +| Shift+KeyP | P | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | +| Ctrl+Shift+KeyP | P | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | +| Alt+KeyP | p | Alt+P | | Option+P | alt+p | Alt+P | alt+[KeyP] | | +| Ctrl+Alt+KeyP | π | Ctrl+Alt+P | | Ctrl+Option+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | +| Shift+Alt+KeyP | P | Shift+Alt+P | | Shift+Option+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | +| Ctrl+Shift+Alt+KeyP | ∏ | Ctrl+Shift+Alt+P | | Ctrl+Shift+Option+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyQ | q | Q | | Q | q | Q | [KeyQ] | | +| Ctrl+KeyQ | q | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | +| Shift+KeyQ | Q | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | +| Ctrl+Shift+KeyQ | Q | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | +| Alt+KeyQ | q | Alt+Q | | Option+Q | alt+q | Alt+Q | alt+[KeyQ] | | +| Ctrl+Alt+KeyQ | œ | Ctrl+Alt+Q | | Ctrl+Option+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | +| Shift+Alt+KeyQ | Q | Shift+Alt+Q | | Shift+Option+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | +| Ctrl+Shift+Alt+KeyQ | Œ | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Option+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyR | r | R | | R | r | R | [KeyR] | | +| Ctrl+KeyR | r | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | +| Shift+KeyR | R | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | +| Ctrl+Shift+KeyR | R | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | +| Alt+KeyR | r | Alt+R | | Option+R | alt+r | Alt+R | alt+[KeyR] | | +| Ctrl+Alt+KeyR | ® | Ctrl+Alt+R | | Ctrl+Option+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | +| Shift+Alt+KeyR | R | Shift+Alt+R | | Shift+Option+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | +| Ctrl+Shift+Alt+KeyR | È | Ctrl+Shift+Alt+R | | Ctrl+Shift+Option+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyS | s | S | | S | s | S | [KeyS] | | +| Ctrl+KeyS | s | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | +| Shift+KeyS | S | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | +| Ctrl+Shift+KeyS | S | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | +| Alt+KeyS | s | Alt+S | | Option+S | alt+s | Alt+S | alt+[KeyS] | | +| Ctrl+Alt+KeyS | ß | Ctrl+Alt+S | | Ctrl+Option+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | +| Shift+Alt+KeyS | S | Shift+Alt+S | | Shift+Option+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | +| Ctrl+Shift+Alt+KeyS | fi | Ctrl+Shift+Alt+S | | Ctrl+Shift+Option+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyT | t | T | | T | t | T | [KeyT] | | +| Ctrl+KeyT | t | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | +| Shift+KeyT | T | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | +| Ctrl+Shift+KeyT | T | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | +| Alt+KeyT | t | Alt+T | | Option+T | alt+t | Alt+T | alt+[KeyT] | | +| Ctrl+Alt+KeyT | † | Ctrl+Alt+T | | Ctrl+Option+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | +| Shift+Alt+KeyT | T | Shift+Alt+T | | Shift+Option+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | +| Ctrl+Shift+Alt+KeyT | Î | Ctrl+Shift+Alt+T | | Ctrl+Shift+Option+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyU | u | U | | U | u | U | [KeyU] | | +| Ctrl+KeyU | u | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | +| Shift+KeyU | U | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | +| Ctrl+Shift+KeyU | U | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | +| Alt+KeyU | u | Alt+U | | Option+U | alt+u | Alt+U | alt+[KeyU] | | +| Ctrl+Alt+KeyU | ° | Ctrl+Alt+U | | Ctrl+Option+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | +| Shift+Alt+KeyU | U | Shift+Alt+U | | Shift+Option+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | +| Ctrl+Shift+Alt+KeyU | Ù | Ctrl+Shift+Alt+U | | Ctrl+Shift+Option+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyV | v | V | | V | v | V | [KeyV] | | +| Ctrl+KeyV | v | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | +| Shift+KeyV | V | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | +| Ctrl+Shift+KeyV | V | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | +| Alt+KeyV | v | Alt+V | | Option+V | alt+v | Alt+V | alt+[KeyV] | | +| Ctrl+Alt+KeyV | √ | Ctrl+Alt+V | | Ctrl+Option+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | +| Shift+Alt+KeyV | V | Shift+Alt+V | | Shift+Option+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | +| Ctrl+Shift+Alt+KeyV | ◊ | Ctrl+Shift+Alt+V | | Ctrl+Shift+Option+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyW | w | W | | W | w | W | [KeyW] | | +| Ctrl+KeyW | w | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | +| Shift+KeyW | W | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | +| Ctrl+Shift+KeyW | W | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | +| Alt+KeyW | w | Alt+W | | Option+W | alt+w | Alt+W | alt+[KeyW] | | +| Ctrl+Alt+KeyW | ∑ | Ctrl+Alt+W | | Ctrl+Option+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | +| Shift+Alt+KeyW | W | Shift+Alt+W | | Shift+Option+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | +| Ctrl+Shift+Alt+KeyW | Á | Ctrl+Shift+Alt+W | | Ctrl+Shift+Option+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyX | x | X | | X | x | X | [KeyX] | | +| Ctrl+KeyX | x | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | +| Shift+KeyX | X | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | +| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | +| Alt+KeyX | x | Alt+X | | Option+X | alt+x | Alt+X | alt+[KeyX] | | +| Ctrl+Alt+KeyX | ≈ | Ctrl+Alt+X | | Ctrl+Option+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | +| Shift+Alt+KeyX | X | Shift+Alt+X | | Shift+Option+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | +| Ctrl+Shift+Alt+KeyX | ™ | Ctrl+Shift+Alt+X | | Ctrl+Shift+Option+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyY | z | Z | | Z | z | Z | [KeyY] | | +| Ctrl+KeyY | z | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyY] | | +| Shift+KeyY | Z | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyY] | | +| Ctrl+Shift+KeyY | Z | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyY] | | +| Alt+KeyY | z | Alt+Z | | Option+Z | alt+z | Alt+Z | alt+[KeyY] | | +| Ctrl+Alt+KeyY | Ω | Ctrl+Alt+Z | | Ctrl+Option+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyY] | | +| Shift+Alt+KeyY | Z | Shift+Alt+Z | | Shift+Option+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyY] | | +| Ctrl+Shift+Alt+KeyY | Í | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Option+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyY] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyZ | y | Y | | Y | y | Y | [KeyZ] | | +| Ctrl+KeyZ | y | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyZ] | | +| Shift+KeyZ | Y | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyZ] | | +| Ctrl+Shift+KeyZ | Y | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyZ] | | +| Alt+KeyZ | y | Alt+Y | | Option+Y | alt+y | Alt+Y | alt+[KeyZ] | | +| Ctrl+Alt+KeyZ | ¥ | Ctrl+Alt+Y | | Ctrl+Option+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyZ] | | +| Shift+Alt+KeyZ | Y | Shift+Alt+Y | | Shift+Option+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyZ] | | +| Ctrl+Shift+Alt+KeyZ | Ÿ | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Option+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyZ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit1 | 1 | 1 | | 1 | 1 | 1 | [Digit1] | | +| Ctrl+Digit1 | 1 | Ctrl+1 | | Ctrl+1 | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | | +| Shift+Digit1 | + | Shift+1 | | Shift+1 | shift+1 | Shift+1 | shift+[Digit1] | | +| | | Shift+= | | | | | | | +| Ctrl+Shift+Digit1 | + | Ctrl+Shift+1 | | Ctrl+Shift+1 | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | | +| | | Ctrl+Shift+= | | | | | | | +| Alt+Digit1 | 1 | Alt+1 | | Option+1 | alt+1 | Alt+1 | alt+[Digit1] | | +| Ctrl+Alt+Digit1 | ± | Ctrl+Alt+1 | | Ctrl+Option+1 | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | | +| Shift+Alt+Digit1 | + | Shift+Alt+1 | | Shift+Option+1 | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | | +| | | Shift+Alt+= | | | | | | | +| Ctrl+Shift+Alt+Digit1 | ∞ | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Option+1 | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | | +| | | Ctrl+Shift+Alt+= | | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit2 | 2 | 2 | | 2 | 2 | 2 | [Digit2] | | +| Ctrl+Digit2 | 2 | Ctrl+2 | | Ctrl+2 | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | | +| Shift+Digit2 | " | Shift+2 | | Shift+2 | shift+2 | Shift+2 | shift+[Digit2] | | +| | | Shift+' | | | | | | | +| Ctrl+Shift+Digit2 | " | Ctrl+Shift+2 | | Ctrl+Shift+2 | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | | +| | | Ctrl+Shift+' | | | | | | | +| Alt+Digit2 | 2 | Alt+2 | | Option+2 | alt+2 | Alt+2 | alt+[Digit2] | | +| Ctrl+Alt+Digit2 | “ | Ctrl+Alt+2 | | Ctrl+Option+2 | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | | +| Shift+Alt+Digit2 | " | Shift+Alt+2 | | Shift+Option+2 | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | | +| | | Shift+Alt+' | | | | | | | +| Ctrl+Shift+Alt+Digit2 | ” | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Option+2 | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | | +| | | Ctrl+Shift+Alt+' | | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit3 | 3 | 3 | | 3 | 3 | 3 | [Digit3] | | +| Ctrl+Digit3 | 3 | Ctrl+3 | | Ctrl+3 | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | | +| Shift+Digit3 | * | Shift+3 | | Shift+3 | shift+3 | Shift+3 | shift+[Digit3] | | +| Ctrl+Shift+Digit3 | * | Ctrl+Shift+3 | | Ctrl+Shift+3 | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | | +| Alt+Digit3 | 3 | Alt+3 | | Option+3 | alt+3 | Alt+3 | alt+[Digit3] | | +| Ctrl+Alt+Digit3 | # | Ctrl+Alt+3 | | Ctrl+Option+3 | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | | +| Shift+Alt+Digit3 | * | Shift+Alt+3 | | Shift+Option+3 | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | | +| Ctrl+Shift+Alt+Digit3 | ‹ | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Option+3 | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit4 | 4 | 4 | | 4 | 4 | 4 | [Digit4] | | +| Ctrl+Digit4 | 4 | Ctrl+4 | | Ctrl+4 | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | | +| Shift+Digit4 | ç | Shift+4 | | Shift+4 | shift+4 | Shift+4 | shift+[Digit4] | | +| Ctrl+Shift+Digit4 | ç | Ctrl+Shift+4 | | Ctrl+Shift+4 | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | | +| Alt+Digit4 | 4 | Alt+4 | | Option+4 | alt+4 | Alt+4 | alt+[Digit4] | | +| Ctrl+Alt+Digit4 | Ç | Ctrl+Alt+4 | | Ctrl+Option+4 | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | | +| Shift+Alt+Digit4 | ç | Shift+Alt+4 | | Shift+Option+4 | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | | +| Ctrl+Shift+Alt+Digit4 | ⁄ | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Option+4 | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit5 | 5 | 5 | | 5 | 5 | 5 | [Digit5] | | +| Ctrl+Digit5 | 5 | Ctrl+5 | | Ctrl+5 | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | | +| Shift+Digit5 | % | Shift+5 | | Shift+5 | shift+5 | Shift+5 | shift+[Digit5] | | +| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+5 | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | | +| Alt+Digit5 | 5 | Alt+5 | | Option+5 | alt+5 | Alt+5 | alt+[Digit5] | | +| Ctrl+Alt+Digit5 | [ | Ctrl+Alt+5 | | Ctrl+Option+5 | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | | +| | | [ | | | | | | | +| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Option+5 | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | | +| Ctrl+Shift+Alt+Digit5 | [ | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Option+5 | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit6 | 6 | 6 | | 6 | 6 | 6 | [Digit6] | | +| Ctrl+Digit6 | 6 | Ctrl+6 | | Ctrl+6 | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | | +| Shift+Digit6 | & | Shift+6 | | Shift+6 | shift+6 | Shift+6 | shift+[Digit6] | | +| Ctrl+Shift+Digit6 | & | Ctrl+Shift+6 | | Ctrl+Shift+6 | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | | +| Alt+Digit6 | 6 | Alt+6 | | Option+6 | alt+6 | Alt+6 | alt+[Digit6] | | +| Ctrl+Alt+Digit6 | ] | Ctrl+Alt+6 | | Ctrl+Option+6 | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | | +| | | ] | | | | | | | +| Shift+Alt+Digit6 | & | Shift+Alt+6 | | Shift+Option+6 | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | | +| Ctrl+Shift+Alt+Digit6 | ] | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Option+6 | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit7 | 7 | 7 | | 7 | 7 | 7 | [Digit7] | | +| Ctrl+Digit7 | 7 | Ctrl+7 | | Ctrl+7 | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | | +| Shift+Digit7 | / | Shift+7 | | Shift+7 | shift+7 | Shift+7 | shift+[Digit7] | | +| | | / | | | | | | | +| Ctrl+Shift+Digit7 | / | Ctrl+Shift+7 | | Ctrl+Shift+7 | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | | +| | | Ctrl+/ | | | | | | | +| Alt+Digit7 | 7 | Alt+7 | | Option+7 | alt+7 | Alt+7 | alt+[Digit7] | | +| Ctrl+Alt+Digit7 | | | Ctrl+Alt+7 | | Ctrl+Option+7 | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | | +| | | Shift+\ | | | | | | | +| Shift+Alt+Digit7 | / | Shift+Alt+7 | | Shift+Option+7 | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | | +| | | Alt+/ | | | | | | | +| Ctrl+Shift+Alt+Digit7 | \ | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Option+7 | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | | +| | | \ | | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit8 | 8 | 8 | | 8 | 8 | 8 | [Digit8] | | +| Ctrl+Digit8 | 8 | Ctrl+8 | | Ctrl+8 | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | | +| Shift+Digit8 | ( | Shift+8 | | Shift+8 | shift+8 | Shift+8 | shift+[Digit8] | | +| Ctrl+Shift+Digit8 | ( | Ctrl+Shift+8 | | Ctrl+Shift+8 | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | | +| Alt+Digit8 | 8 | Alt+8 | | Option+8 | alt+8 | Alt+8 | alt+[Digit8] | | +| Ctrl+Alt+Digit8 | { | Ctrl+Alt+8 | | Ctrl+Option+8 | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | | +| | | Shift+[ | | | | | | | +| Shift+Alt+Digit8 | ( | Shift+Alt+8 | | Shift+Option+8 | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | | +| Ctrl+Shift+Alt+Digit8 | Ò | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Option+8 | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit9 | 9 | 9 | | 9 | 9 | 9 | [Digit9] | | +| Ctrl+Digit9 | 9 | Ctrl+9 | | Ctrl+9 | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | | +| Shift+Digit9 | ) | Shift+9 | | Shift+9 | shift+9 | Shift+9 | shift+[Digit9] | | +| Ctrl+Shift+Digit9 | ) | Ctrl+Shift+9 | | Ctrl+Shift+9 | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | | +| Alt+Digit9 | 9 | Alt+9 | | Option+9 | alt+9 | Alt+9 | alt+[Digit9] | | +| Ctrl+Alt+Digit9 | } | Ctrl+Alt+9 | | Ctrl+Option+9 | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | | +| | | Shift+] | | | | | | | +| Shift+Alt+Digit9 | ) | Shift+Alt+9 | | Shift+Option+9 | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | | +| Ctrl+Shift+Alt+Digit9 | Ô | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Option+9 | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit0 | 0 | 0 | | 0 | 0 | 0 | [Digit0] | | +| Ctrl+Digit0 | 0 | Ctrl+0 | | Ctrl+0 | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | | +| Shift+Digit0 | = | Shift+0 | | Shift+0 | shift+0 | Shift+0 | shift+[Digit0] | | +| | | = | | | | | | | +| Ctrl+Shift+Digit0 | = | Ctrl+Shift+0 | | Ctrl+Shift+0 | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | | +| | | Ctrl+= | | | | | | | +| Alt+Digit0 | 0 | Alt+0 | | Option+0 | alt+0 | Alt+0 | alt+[Digit0] | | +| Ctrl+Alt+Digit0 | ≠ | Ctrl+Alt+0 | | Ctrl+Option+0 | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | | +| Shift+Alt+Digit0 | = | Shift+Alt+0 | | Shift+Option+0 | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | | +| | | Alt+= | | | | | | | +| Ctrl+Shift+Alt+Digit0 | Ú | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Option+0 | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | | +| | | Ctrl+Alt+= | | | | | | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Minus | ' | ' | | ' | [Minus] | null | [Minus] | NO | +| Ctrl+Minus | ' | Ctrl+' | | Ctrl+' | ctrl+[Minus] | null | ctrl+[Minus] | NO | +| Shift+Minus | ? | Shift+/ | | Shift+' | shift+[Minus] | null | shift+[Minus] | NO | +| Ctrl+Shift+Minus | ? | Ctrl+Shift+/ | | Ctrl+Shift+' | ctrl+shift+[Minus] | null | ctrl+shift+[Minus] | NO | +| Alt+Minus | ' | Alt+' | | Option+' | alt+[Minus] | null | alt+[Minus] | NO | +| Ctrl+Alt+Minus | ¿ | Ctrl+Alt+' | | Ctrl+Option+' | ctrl+alt+[Minus] | null | ctrl+alt+[Minus] | NO | +| Shift+Alt+Minus | ? | Shift+Alt+/ | | Shift+Option+' | shift+alt+[Minus] | null | shift+alt+[Minus] | NO | +| Ctrl+Shift+Alt+Minus |  | Ctrl+Shift+Alt+/ | | Ctrl+Shift+Option+' | ctrl+shift+alt+[Minus] | null | ctrl+shift+alt+[Minus] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Equal | ^ | | | ^ | [Equal] | null | [Equal] | NO | +| Ctrl+Equal | ^ | | | Ctrl+^ | ctrl+[Equal] | null | ctrl+[Equal] | NO | +| Shift+Equal | ` | ` | | Shift+^ | shift+[Equal] | null | shift+[Equal] | NO | +| Ctrl+Shift+Equal | ` | Ctrl+` | | Ctrl+Shift+^ | ctrl+shift+[Equal] | null | ctrl+shift+[Equal] | NO | +| Alt+Equal | ^ | | | Option+^ | alt+[Equal] | null | alt+[Equal] | NO | +| Ctrl+Alt+Equal | ´ | | | Ctrl+Option+^ | ctrl+alt+[Equal] | null | ctrl+alt+[Equal] | NO | +| Shift+Alt+Equal | ` | Alt+` | | Shift+Option+^ | shift+alt+[Equal] | null | shift+alt+[Equal] | NO | +| Ctrl+Shift+Alt+Equal | ^ | Ctrl+Alt+` | | Ctrl+Shift+Option+^ | ctrl+shift+alt+[Equal] | null | ctrl+shift+alt+[Equal] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketLeft | ü | | | ü | [BracketLeft] | null | [BracketLeft] | NO | +| Ctrl+BracketLeft | ü | | | Ctrl+ü | ctrl+[BracketLeft] | null | ctrl+[BracketLeft] | NO | +| Shift+BracketLeft | è | | | Shift+ü | shift+[BracketLeft] | null | shift+[BracketLeft] | NO | +| Ctrl+Shift+BracketLeft | è | | | Ctrl+Shift+ü | ctrl+shift+[BracketLeft] | null | ctrl+shift+[BracketLeft] | NO | +| Alt+BracketLeft | ü | | | Option+ü | alt+[BracketLeft] | null | alt+[BracketLeft] | NO | +| Ctrl+Alt+BracketLeft | § | | | Ctrl+Option+ü | ctrl+alt+[BracketLeft] | null | ctrl+alt+[BracketLeft] | NO | +| Shift+Alt+BracketLeft | è | | | Shift+Option+ü | shift+alt+[BracketLeft] | null | shift+alt+[BracketLeft] | NO | +| Ctrl+Shift+Alt+BracketLeft | ÿ | | | Ctrl+Shift+Option+ü | ctrl+shift+alt+[BracketLeft] | null | ctrl+shift+alt+[BracketLeft] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketRight | ¨ | | | ¨ | [BracketRight] | null | [BracketRight] | NO | +| Ctrl+BracketRight | ¨ | | | Ctrl+¨ | ctrl+[BracketRight] | null | ctrl+[BracketRight] | NO | +| Shift+BracketRight | ! | | | Shift+¨ | shift+[BracketRight] | null | shift+[BracketRight] | NO | +| Ctrl+Shift+BracketRight | ! | | | Ctrl+Shift+¨ | ctrl+shift+[BracketRight] | null | ctrl+shift+[BracketRight] | NO | +| Alt+BracketRight | ¨ | | | Option+¨ | alt+[BracketRight] | null | alt+[BracketRight] | NO | +| Ctrl+Alt+BracketRight | ‘ | | | Ctrl+Option+¨ | ctrl+alt+[BracketRight] | null | ctrl+alt+[BracketRight] | NO | +| Shift+Alt+BracketRight | ! | | | Shift+Option+¨ | shift+alt+[BracketRight] | null | shift+alt+[BracketRight] | NO | +| Ctrl+Shift+Alt+BracketRight | ’ | | | Ctrl+Shift+Option+¨ | ctrl+shift+alt+[BracketRight] | null | ctrl+shift+alt+[BracketRight] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backslash | $ | | | $ | [Backslash] | null | [Backslash] | NO | +| Ctrl+Backslash | $ | | | Ctrl+$ | ctrl+[Backslash] | null | ctrl+[Backslash] | NO | +| Shift+Backslash | £ | | | Shift+$ | shift+[Backslash] | null | shift+[Backslash] | NO | +| Ctrl+Shift+Backslash | £ | | | Ctrl+Shift+$ | ctrl+shift+[Backslash] | null | ctrl+shift+[Backslash] | NO | +| Alt+Backslash | $ | | | Option+$ | alt+[Backslash] | null | alt+[Backslash] | NO | +| Ctrl+Alt+Backslash | ¶ | | | Ctrl+Option+$ | ctrl+alt+[Backslash] | null | ctrl+alt+[Backslash] | NO | +| Shift+Alt+Backslash | £ | | | Shift+Option+$ | shift+alt+[Backslash] | null | shift+alt+[Backslash] | NO | +| Ctrl+Shift+Alt+Backslash | • | | | Ctrl+Shift+Option+$ | ctrl+shift+alt+[Backslash] | null | ctrl+shift+alt+[Backslash] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlHash | --- | | | null | null | null | null | | +| Ctrl+IntlHash | --- | | | null | null | null | null | | +| Shift+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | +| Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | +| Shift+Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Semicolon | ö | | | ö | [Semicolon] | null | [Semicolon] | NO | +| Ctrl+Semicolon | ö | | | Ctrl+ö | ctrl+[Semicolon] | null | ctrl+[Semicolon] | NO | +| Shift+Semicolon | é | | | Shift+ö | shift+[Semicolon] | null | shift+[Semicolon] | NO | +| Ctrl+Shift+Semicolon | é | | | Ctrl+Shift+ö | ctrl+shift+[Semicolon] | null | ctrl+shift+[Semicolon] | NO | +| Alt+Semicolon | ö | | | Option+ö | alt+[Semicolon] | null | alt+[Semicolon] | NO | +| Ctrl+Alt+Semicolon | ¢ | | | Ctrl+Option+ö | ctrl+alt+[Semicolon] | null | ctrl+alt+[Semicolon] | NO | +| Shift+Alt+Semicolon | é | | | Shift+Option+ö | shift+alt+[Semicolon] | null | shift+alt+[Semicolon] | NO | +| Ctrl+Shift+Alt+Semicolon | ˘ | | | Ctrl+Shift+Option+ö | ctrl+shift+alt+[Semicolon] | null | ctrl+shift+alt+[Semicolon] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Quote | ä | | | ä | [Quote] | null | [Quote] | NO | +| Ctrl+Quote | ä | | | Ctrl+ä | ctrl+[Quote] | null | ctrl+[Quote] | NO | +| Shift+Quote | à | | | Shift+ä | shift+[Quote] | null | shift+[Quote] | NO | +| Ctrl+Shift+Quote | à | | | Ctrl+Shift+ä | ctrl+shift+[Quote] | null | ctrl+shift+[Quote] | NO | +| Alt+Quote | ä | | | Option+ä | alt+[Quote] | null | alt+[Quote] | NO | +| Ctrl+Alt+Quote | æ | | | Ctrl+Option+ä | ctrl+alt+[Quote] | null | ctrl+alt+[Quote] | NO | +| Shift+Alt+Quote | à | | | Shift+Option+ä | shift+alt+[Quote] | null | shift+alt+[Quote] | NO | +| Ctrl+Shift+Alt+Quote | Æ | | | Ctrl+Shift+Option+ä | ctrl+shift+alt+[Quote] | null | ctrl+shift+alt+[Quote] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backquote | < | Shift+, | | < | [Backquote] | null | [Backquote] | NO | +| Ctrl+Backquote | < | Ctrl+Shift+, | | Ctrl+< | ctrl+[Backquote] | null | ctrl+[Backquote] | NO | +| Shift+Backquote | > | Shift+. | | Shift+< | shift+[Backquote] | null | shift+[Backquote] | NO | +| Ctrl+Shift+Backquote | > | Ctrl+Shift+. | | Ctrl+Shift+< | ctrl+shift+[Backquote] | null | ctrl+shift+[Backquote] | NO | +| Alt+Backquote | < | Shift+Alt+, | | Option+< | alt+[Backquote] | null | alt+[Backquote] | NO | +| Ctrl+Alt+Backquote | ≤ | Ctrl+Shift+Alt+, | | Ctrl+Option+< | ctrl+alt+[Backquote] | null | ctrl+alt+[Backquote] | NO | +| Shift+Alt+Backquote | > | Shift+Alt+. | | Shift+Option+< | shift+alt+[Backquote] | null | shift+alt+[Backquote] | NO | +| Ctrl+Shift+Alt+Backquote | ≥ | Ctrl+Shift+Alt+. | | Ctrl+Shift+Option+< | ctrl+shift+alt+[Backquote] | null | ctrl+shift+alt+[Backquote] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Comma | , | , | | , | [Comma] | null | [Comma] | NO | +| Ctrl+Comma | , | Ctrl+, | | Ctrl+, | ctrl+[Comma] | null | ctrl+[Comma] | NO | +| Shift+Comma | ; | ; | | Shift+, | shift+[Comma] | null | shift+[Comma] | NO | +| Ctrl+Shift+Comma | ; | Ctrl+; | | Ctrl+Shift+, | ctrl+shift+[Comma] | null | ctrl+shift+[Comma] | NO | +| Alt+Comma | , | Alt+, | | Option+, | alt+[Comma] | null | alt+[Comma] | NO | +| Ctrl+Alt+Comma | « | Ctrl+Alt+, | | Ctrl+Option+, | ctrl+alt+[Comma] | null | ctrl+alt+[Comma] | NO | +| Shift+Alt+Comma | ; | Alt+; | | Shift+Option+, | shift+alt+[Comma] | null | shift+alt+[Comma] | NO | +| Ctrl+Shift+Alt+Comma | » | Ctrl+Alt+; | | Ctrl+Shift+Option+, | ctrl+shift+alt+[Comma] | null | ctrl+shift+alt+[Comma] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Period | . | . | | . | [Period] | null | [Period] | NO | +| Ctrl+Period | . | Ctrl+. | | Ctrl+. | ctrl+[Period] | null | ctrl+[Period] | NO | +| Shift+Period | : | Shift+; | | Shift+. | shift+[Period] | null | shift+[Period] | NO | +| Ctrl+Shift+Period | : | Ctrl+Shift+; | | Ctrl+Shift+. | ctrl+shift+[Period] | null | ctrl+shift+[Period] | NO | +| Alt+Period | . | Alt+. | | Option+. | alt+[Period] | null | alt+[Period] | NO | +| Ctrl+Alt+Period | … | Ctrl+Alt+. | | Ctrl+Option+. | ctrl+alt+[Period] | null | ctrl+alt+[Period] | NO | +| Shift+Alt+Period | : | Shift+Alt+; | | Shift+Option+. | shift+alt+[Period] | null | shift+alt+[Period] | NO | +| Ctrl+Shift+Alt+Period | ÷ | Ctrl+Shift+Alt+; | | Ctrl+Shift+Option+. | ctrl+shift+alt+[Period] | null | ctrl+shift+alt+[Period] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Slash | - | - | | - | - | - | [Slash] | | +| Ctrl+Slash | - | Ctrl+- | | Ctrl+- | ctrl+- | Ctrl+- | ctrl+[Slash] | | +| Shift+Slash | _ | Shift+- | | Shift+- | shift+- | Shift+- | shift+[Slash] | | +| Ctrl+Shift+Slash | _ | Ctrl+Shift+- | | Ctrl+Shift+- | ctrl+shift+- | Ctrl+Shift+- | ctrl+shift+[Slash] | | +| Alt+Slash | - | Alt+- | | Option+- | alt+- | Alt+- | alt+[Slash] | | +| Ctrl+Alt+Slash | – | Ctrl+Alt+- | | Ctrl+Option+- | ctrl+alt+- | Ctrl+Alt+- | ctrl+alt+[Slash] | | +| Shift+Alt+Slash | _ | Shift+Alt+- | | Shift+Option+- | shift+alt+- | Shift+Alt+- | shift+alt+[Slash] | | +| Ctrl+Shift+Alt+Slash | — | Ctrl+Shift+Alt+- | | Ctrl+Shift+Option+- | ctrl+shift+alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+[Slash] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | +| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | +| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | +| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | +| Alt+ArrowUp | --- | Alt+UpArrow | | Option+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | +| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Option+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | +| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Option+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | +| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Option+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | +| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | +| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | +| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | +| Alt+Numpad0 | --- | Alt+NumPad0 | | Option+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | +| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Option+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | +| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Option+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | +| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Option+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlBackslash | § | | | § | [IntlBackslash] | null | [IntlBackslash] | NO | +| Ctrl+IntlBackslash | § | | | Ctrl+§ | ctrl+[IntlBackslash] | null | ctrl+[IntlBackslash] | NO | +| Shift+IntlBackslash | ° | | | Shift+§ | shift+[IntlBackslash] | null | shift+[IntlBackslash] | NO | +| Ctrl+Shift+IntlBackslash | ° | | | Ctrl+Shift+§ | ctrl+shift+[IntlBackslash] | null | ctrl+shift+[IntlBackslash] | NO | +| Alt+IntlBackslash | § | | | Option+§ | alt+[IntlBackslash] | null | alt+[IntlBackslash] | NO | +| Ctrl+Alt+IntlBackslash | fi | | | Ctrl+Option+§ | ctrl+alt+[IntlBackslash] | null | ctrl+alt+[IntlBackslash] | NO | +| Shift+Alt+IntlBackslash | ° | | | Shift+Option+§ | shift+alt+[IntlBackslash] | null | shift+alt+[IntlBackslash] | NO | +| Ctrl+Shift+Alt+IntlBackslash | ‰ | | | Ctrl+Shift+Option+§ | ctrl+shift+alt+[IntlBackslash] | null | ctrl+shift+alt+[IntlBackslash] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | +| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | +| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | +| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | +| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | +| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | +| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | +| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | +| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | +| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | +| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | +| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | +| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | +| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | +| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/node/mac_en_us.js b/src/vs/workbench/services/keybinding/test/node/mac_en_us.js new file mode 100644 index 00000000000..1b62128a42d --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/mac_en_us.js @@ -0,0 +1,1188 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +define({ + KeyA: { + value: 'a', + valueIsDeadKey: false, + withShift: 'A', + withShiftIsDeadKey: false, + withAltGr: 'å', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Å', + withShiftAltGrIsDeadKey: false + }, + KeyB: { + value: 'b', + valueIsDeadKey: false, + withShift: 'B', + withShiftIsDeadKey: false, + withAltGr: '∫', + withAltGrIsDeadKey: false, + withShiftAltGr: 'ı', + withShiftAltGrIsDeadKey: false + }, + KeyC: { + value: 'c', + valueIsDeadKey: false, + withShift: 'C', + withShiftIsDeadKey: false, + withAltGr: 'ç', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ç', + withShiftAltGrIsDeadKey: false + }, + KeyD: { + value: 'd', + valueIsDeadKey: false, + withShift: 'D', + withShiftIsDeadKey: false, + withAltGr: '∂', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Î', + withShiftAltGrIsDeadKey: false + }, + KeyE: { + value: 'e', + valueIsDeadKey: false, + withShift: 'E', + withShiftIsDeadKey: false, + withAltGr: '´', + withAltGrIsDeadKey: true, + withShiftAltGr: '´', + withShiftAltGrIsDeadKey: false + }, + KeyF: { + value: 'f', + valueIsDeadKey: false, + withShift: 'F', + withShiftIsDeadKey: false, + withAltGr: 'ƒ', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ï', + withShiftAltGrIsDeadKey: false + }, + KeyG: { + value: 'g', + valueIsDeadKey: false, + withShift: 'G', + withShiftIsDeadKey: false, + withAltGr: '©', + withAltGrIsDeadKey: false, + withShiftAltGr: '˝', + withShiftAltGrIsDeadKey: false + }, + KeyH: { + value: 'h', + valueIsDeadKey: false, + withShift: 'H', + withShiftIsDeadKey: false, + withAltGr: '˙', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ó', + withShiftAltGrIsDeadKey: false + }, + KeyI: { + value: 'i', + valueIsDeadKey: false, + withShift: 'I', + withShiftIsDeadKey: false, + withAltGr: 'ˆ', + withAltGrIsDeadKey: true, + withShiftAltGr: 'ˆ', + withShiftAltGrIsDeadKey: false + }, + KeyJ: { + value: 'j', + valueIsDeadKey: false, + withShift: 'J', + withShiftIsDeadKey: false, + withAltGr: '∆', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ô', + withShiftAltGrIsDeadKey: false + }, + KeyK: { + value: 'k', + valueIsDeadKey: false, + withShift: 'K', + withShiftIsDeadKey: false, + withAltGr: '˚', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + KeyL: { + value: 'l', + valueIsDeadKey: false, + withShift: 'L', + withShiftIsDeadKey: false, + withAltGr: '¬', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ò', + withShiftAltGrIsDeadKey: false + }, + KeyM: { + value: 'm', + valueIsDeadKey: false, + withShift: 'M', + withShiftIsDeadKey: false, + withAltGr: 'µ', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Â', + withShiftAltGrIsDeadKey: false + }, + KeyN: { + value: 'n', + valueIsDeadKey: false, + withShift: 'N', + withShiftIsDeadKey: false, + withAltGr: '˜', + withAltGrIsDeadKey: true, + withShiftAltGr: '˜', + withShiftAltGrIsDeadKey: false + }, + KeyO: { + value: 'o', + valueIsDeadKey: false, + withShift: 'O', + withShiftIsDeadKey: false, + withAltGr: 'ø', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ø', + withShiftAltGrIsDeadKey: false + }, + KeyP: { + value: 'p', + valueIsDeadKey: false, + withShift: 'P', + withShiftIsDeadKey: false, + withAltGr: 'π', + withAltGrIsDeadKey: false, + withShiftAltGr: '∏', + withShiftAltGrIsDeadKey: false + }, + KeyQ: { + value: 'q', + valueIsDeadKey: false, + withShift: 'Q', + withShiftIsDeadKey: false, + withAltGr: 'œ', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Œ', + withShiftAltGrIsDeadKey: false + }, + KeyR: { + value: 'r', + valueIsDeadKey: false, + withShift: 'R', + withShiftIsDeadKey: false, + withAltGr: '®', + withAltGrIsDeadKey: false, + withShiftAltGr: '‰', + withShiftAltGrIsDeadKey: false + }, + KeyS: { + value: 's', + valueIsDeadKey: false, + withShift: 'S', + withShiftIsDeadKey: false, + withAltGr: 'ß', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Í', + withShiftAltGrIsDeadKey: false + }, + KeyT: { + value: 't', + valueIsDeadKey: false, + withShift: 'T', + withShiftIsDeadKey: false, + withAltGr: '†', + withAltGrIsDeadKey: false, + withShiftAltGr: 'ˇ', + withShiftAltGrIsDeadKey: false + }, + KeyU: { + value: 'u', + valueIsDeadKey: false, + withShift: 'U', + withShiftIsDeadKey: false, + withAltGr: '¨', + withAltGrIsDeadKey: true, + withShiftAltGr: '¨', + withShiftAltGrIsDeadKey: false + }, + KeyV: { + value: 'v', + valueIsDeadKey: false, + withShift: 'V', + withShiftIsDeadKey: false, + withAltGr: '√', + withAltGrIsDeadKey: false, + withShiftAltGr: '◊', + withShiftAltGrIsDeadKey: false + }, + KeyW: { + value: 'w', + valueIsDeadKey: false, + withShift: 'W', + withShiftIsDeadKey: false, + withAltGr: '∑', + withAltGrIsDeadKey: false, + withShiftAltGr: '„', + withShiftAltGrIsDeadKey: false + }, + KeyX: { + value: 'x', + valueIsDeadKey: false, + withShift: 'X', + withShiftIsDeadKey: false, + withAltGr: '≈', + withAltGrIsDeadKey: false, + withShiftAltGr: '˛', + withShiftAltGrIsDeadKey: false + }, + KeyY: { + value: 'y', + valueIsDeadKey: false, + withShift: 'Y', + withShiftIsDeadKey: false, + withAltGr: '¥', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Á', + withShiftAltGrIsDeadKey: false + }, + KeyZ: { + value: 'z', + valueIsDeadKey: false, + withShift: 'Z', + withShiftIsDeadKey: false, + withAltGr: 'Ω', + withAltGrIsDeadKey: false, + withShiftAltGr: '¸', + withShiftAltGrIsDeadKey: false + }, + Digit1: { + value: '1', + valueIsDeadKey: false, + withShift: '!', + withShiftIsDeadKey: false, + withAltGr: '¡', + withAltGrIsDeadKey: false, + withShiftAltGr: '⁄', + withShiftAltGrIsDeadKey: false + }, + Digit2: { + value: '2', + valueIsDeadKey: false, + withShift: '@', + withShiftIsDeadKey: false, + withAltGr: '™', + withAltGrIsDeadKey: false, + withShiftAltGr: '€', + withShiftAltGrIsDeadKey: false + }, + Digit3: { + value: '3', + valueIsDeadKey: false, + withShift: '#', + withShiftIsDeadKey: false, + withAltGr: '£', + withAltGrIsDeadKey: false, + withShiftAltGr: '‹', + withShiftAltGrIsDeadKey: false + }, + Digit4: { + value: '4', + valueIsDeadKey: false, + withShift: '$', + withShiftIsDeadKey: false, + withAltGr: '¢', + withAltGrIsDeadKey: false, + withShiftAltGr: '›', + withShiftAltGrIsDeadKey: false + }, + Digit5: { + value: '5', + valueIsDeadKey: false, + withShift: '%', + withShiftIsDeadKey: false, + withAltGr: '∞', + withAltGrIsDeadKey: false, + withShiftAltGr: 'fi', + withShiftAltGrIsDeadKey: false + }, + Digit6: { + value: '6', + valueIsDeadKey: false, + withShift: '^', + withShiftIsDeadKey: false, + withAltGr: '§', + withAltGrIsDeadKey: false, + withShiftAltGr: 'fl', + withShiftAltGrIsDeadKey: false + }, + Digit7: { + value: '7', + valueIsDeadKey: false, + withShift: '&', + withShiftIsDeadKey: false, + withAltGr: '¶', + withAltGrIsDeadKey: false, + withShiftAltGr: '‡', + withShiftAltGrIsDeadKey: false + }, + Digit8: { + value: '8', + valueIsDeadKey: false, + withShift: '*', + withShiftIsDeadKey: false, + withAltGr: '•', + withAltGrIsDeadKey: false, + withShiftAltGr: '°', + withShiftAltGrIsDeadKey: false + }, + Digit9: { + value: '9', + valueIsDeadKey: false, + withShift: '(', + withShiftIsDeadKey: false, + withAltGr: 'ª', + withAltGrIsDeadKey: false, + withShiftAltGr: '·', + withShiftAltGrIsDeadKey: false + }, + Digit0: { + value: '0', + valueIsDeadKey: false, + withShift: ')', + withShiftIsDeadKey: false, + withAltGr: 'º', + withAltGrIsDeadKey: false, + withShiftAltGr: '‚', + withShiftAltGrIsDeadKey: false + }, + Enter: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Escape: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Backspace: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Tab: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Space: { + value: ' ', + valueIsDeadKey: false, + withShift: ' ', + withShiftIsDeadKey: false, + withAltGr: ' ', + withAltGrIsDeadKey: false, + withShiftAltGr: ' ', + withShiftAltGrIsDeadKey: false + }, + Minus: { + value: '-', + valueIsDeadKey: false, + withShift: '_', + withShiftIsDeadKey: false, + withAltGr: '–', + withAltGrIsDeadKey: false, + withShiftAltGr: '—', + withShiftAltGrIsDeadKey: false + }, + Equal: { + value: '=', + valueIsDeadKey: false, + withShift: '+', + withShiftIsDeadKey: false, + withAltGr: '≠', + withAltGrIsDeadKey: false, + withShiftAltGr: '±', + withShiftAltGrIsDeadKey: false + }, + BracketLeft: { + value: '[', + valueIsDeadKey: false, + withShift: '{', + withShiftIsDeadKey: false, + withAltGr: '“', + withAltGrIsDeadKey: false, + withShiftAltGr: '”', + withShiftAltGrIsDeadKey: false + }, + BracketRight: { + value: ']', + valueIsDeadKey: false, + withShift: '}', + withShiftIsDeadKey: false, + withAltGr: '‘', + withAltGrIsDeadKey: false, + withShiftAltGr: '’', + withShiftAltGrIsDeadKey: false + }, + Backslash: { + value: '\\', + valueIsDeadKey: false, + withShift: '|', + withShiftIsDeadKey: false, + withAltGr: '«', + withAltGrIsDeadKey: false, + withShiftAltGr: '»', + withShiftAltGrIsDeadKey: false + }, + Semicolon: { + value: ';', + valueIsDeadKey: false, + withShift: ':', + withShiftIsDeadKey: false, + withAltGr: '…', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ú', + withShiftAltGrIsDeadKey: false + }, + Quote: { + value: '\'', + valueIsDeadKey: false, + withShift: '"', + withShiftIsDeadKey: false, + withAltGr: 'æ', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Æ', + withShiftAltGrIsDeadKey: false + }, + Backquote: { + value: '`', + valueIsDeadKey: false, + withShift: '~', + withShiftIsDeadKey: false, + withAltGr: '`', + withAltGrIsDeadKey: true, + withShiftAltGr: '`', + withShiftAltGrIsDeadKey: false + }, + Comma: { + value: ',', + valueIsDeadKey: false, + withShift: '<', + withShiftIsDeadKey: false, + withAltGr: '≤', + withAltGrIsDeadKey: false, + withShiftAltGr: '¯', + withShiftAltGrIsDeadKey: false + }, + Period: { + value: '.', + valueIsDeadKey: false, + withShift: '>', + withShiftIsDeadKey: false, + withAltGr: '≥', + withAltGrIsDeadKey: false, + withShiftAltGr: '˘', + withShiftAltGrIsDeadKey: false + }, + Slash: { + value: '/', + valueIsDeadKey: false, + withShift: '?', + withShiftIsDeadKey: false, + withAltGr: '÷', + withAltGrIsDeadKey: false, + withShiftAltGr: '¿', + withShiftAltGrIsDeadKey: false + }, + CapsLock: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F1: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F2: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F3: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F4: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F5: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F6: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F7: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F8: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F9: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F10: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F11: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F12: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Insert: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Home: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + PageUp: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Delete: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + End: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + PageDown: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowDown: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowUp: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumLock: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumpadDivide: { + value: '/', + valueIsDeadKey: false, + withShift: '/', + withShiftIsDeadKey: false, + withAltGr: '/', + withAltGrIsDeadKey: false, + withShiftAltGr: '/', + withShiftAltGrIsDeadKey: false + }, + NumpadMultiply: { + value: '*', + valueIsDeadKey: false, + withShift: '*', + withShiftIsDeadKey: false, + withAltGr: '*', + withAltGrIsDeadKey: false, + withShiftAltGr: '*', + withShiftAltGrIsDeadKey: false + }, + NumpadSubtract: { + value: '-', + valueIsDeadKey: false, + withShift: '-', + withShiftIsDeadKey: false, + withAltGr: '-', + withAltGrIsDeadKey: false, + withShiftAltGr: '-', + withShiftAltGrIsDeadKey: false + }, + NumpadAdd: { + value: '+', + valueIsDeadKey: false, + withShift: '+', + withShiftIsDeadKey: false, + withAltGr: '+', + withAltGrIsDeadKey: false, + withShiftAltGr: '+', + withShiftAltGrIsDeadKey: false + }, + NumpadEnter: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Numpad1: { + value: '1', + valueIsDeadKey: false, + withShift: '1', + withShiftIsDeadKey: false, + withAltGr: '1', + withAltGrIsDeadKey: false, + withShiftAltGr: '1', + withShiftAltGrIsDeadKey: false + }, + Numpad2: { + value: '2', + valueIsDeadKey: false, + withShift: '2', + withShiftIsDeadKey: false, + withAltGr: '2', + withAltGrIsDeadKey: false, + withShiftAltGr: '2', + withShiftAltGrIsDeadKey: false + }, + Numpad3: { + value: '3', + valueIsDeadKey: false, + withShift: '3', + withShiftIsDeadKey: false, + withAltGr: '3', + withAltGrIsDeadKey: false, + withShiftAltGr: '3', + withShiftAltGrIsDeadKey: false + }, + Numpad4: { + value: '4', + valueIsDeadKey: false, + withShift: '4', + withShiftIsDeadKey: false, + withAltGr: '4', + withAltGrIsDeadKey: false, + withShiftAltGr: '4', + withShiftAltGrIsDeadKey: false + }, + Numpad5: { + value: '5', + valueIsDeadKey: false, + withShift: '5', + withShiftIsDeadKey: false, + withAltGr: '5', + withAltGrIsDeadKey: false, + withShiftAltGr: '5', + withShiftAltGrIsDeadKey: false + }, + Numpad6: { + value: '6', + valueIsDeadKey: false, + withShift: '6', + withShiftIsDeadKey: false, + withAltGr: '6', + withAltGrIsDeadKey: false, + withShiftAltGr: '6', + withShiftAltGrIsDeadKey: false + }, + Numpad7: { + value: '7', + valueIsDeadKey: false, + withShift: '7', + withShiftIsDeadKey: false, + withAltGr: '7', + withAltGrIsDeadKey: false, + withShiftAltGr: '7', + withShiftAltGrIsDeadKey: false + }, + Numpad8: { + value: '8', + valueIsDeadKey: false, + withShift: '8', + withShiftIsDeadKey: false, + withAltGr: '8', + withAltGrIsDeadKey: false, + withShiftAltGr: '8', + withShiftAltGrIsDeadKey: false + }, + Numpad9: { + value: '9', + valueIsDeadKey: false, + withShift: '9', + withShiftIsDeadKey: false, + withAltGr: '9', + withAltGrIsDeadKey: false, + withShiftAltGr: '9', + withShiftAltGrIsDeadKey: false + }, + Numpad0: { + value: '0', + valueIsDeadKey: false, + withShift: '0', + withShiftIsDeadKey: false, + withAltGr: '0', + withAltGrIsDeadKey: false, + withShiftAltGr: '0', + withShiftAltGrIsDeadKey: false + }, + NumpadDecimal: { + value: '.', + valueIsDeadKey: false, + withShift: '.', + withShiftIsDeadKey: false, + withAltGr: '.', + withAltGrIsDeadKey: false, + withShiftAltGr: '.', + withShiftAltGrIsDeadKey: false + }, + IntlBackslash: { + value: '§', + valueIsDeadKey: false, + withShift: '±', + withShiftIsDeadKey: false, + withAltGr: '§', + withAltGrIsDeadKey: false, + withShiftAltGr: '±', + withShiftAltGrIsDeadKey: false + }, + ContextMenu: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumpadEqual: { + value: '=', + valueIsDeadKey: false, + withShift: '=', + withShiftIsDeadKey: false, + withAltGr: '=', + withAltGrIsDeadKey: false, + withShiftAltGr: '=', + withShiftAltGrIsDeadKey: false + }, + F13: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F14: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F15: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F16: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F17: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F18: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F19: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F20: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AudioVolumeMute: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AudioVolumeUp: { + value: '', + valueIsDeadKey: false, + withShift: '=', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '=', + withShiftAltGrIsDeadKey: false + }, + AudioVolumeDown: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumpadComma: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + IntlRo: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + KanaMode: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + IntlYen: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ControlLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ShiftLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AltLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + MetaLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ControlRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ShiftRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AltRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + MetaRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + } +}); diff --git a/src/vs/workbench/services/keybinding/test/node/mac_en_us.txt b/src/vs/workbench/services/keybinding/test/node/mac_en_us.txt new file mode 100644 index 00000000000..833fdf61c32 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/mac_en_us.txt @@ -0,0 +1,507 @@ +isUSStandard: true +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyA | a | A | | A | a | A | [KeyA] | | +| Ctrl+KeyA | a | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | +| Shift+KeyA | A | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | +| Ctrl+Shift+KeyA | A | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | +| Alt+KeyA | a | Alt+A | | Option+A | alt+a | Alt+A | alt+[KeyA] | | +| Ctrl+Alt+KeyA | å | Ctrl+Alt+A | | Ctrl+Option+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | +| Shift+Alt+KeyA | A | Shift+Alt+A | | Shift+Option+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | +| Ctrl+Shift+Alt+KeyA | Å | Ctrl+Shift+Alt+A | | Ctrl+Shift+Option+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyB | b | B | | B | b | B | [KeyB] | | +| Ctrl+KeyB | b | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | +| Shift+KeyB | B | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | +| Ctrl+Shift+KeyB | B | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | +| Alt+KeyB | b | Alt+B | | Option+B | alt+b | Alt+B | alt+[KeyB] | | +| Ctrl+Alt+KeyB | ∫ | Ctrl+Alt+B | | Ctrl+Option+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | +| Shift+Alt+KeyB | B | Shift+Alt+B | | Shift+Option+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | +| Ctrl+Shift+Alt+KeyB | ı | Ctrl+Shift+Alt+B | | Ctrl+Shift+Option+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyC | c | C | | C | c | C | [KeyC] | | +| Ctrl+KeyC | c | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | +| Shift+KeyC | C | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | +| Ctrl+Shift+KeyC | C | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | +| Alt+KeyC | c | Alt+C | | Option+C | alt+c | Alt+C | alt+[KeyC] | | +| Ctrl+Alt+KeyC | ç | Ctrl+Alt+C | | Ctrl+Option+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | +| Shift+Alt+KeyC | C | Shift+Alt+C | | Shift+Option+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | +| Ctrl+Shift+Alt+KeyC | Ç | Ctrl+Shift+Alt+C | | Ctrl+Shift+Option+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyD | d | D | | D | d | D | [KeyD] | | +| Ctrl+KeyD | d | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | +| Shift+KeyD | D | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | +| Ctrl+Shift+KeyD | D | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | +| Alt+KeyD | d | Alt+D | | Option+D | alt+d | Alt+D | alt+[KeyD] | | +| Ctrl+Alt+KeyD | ∂ | Ctrl+Alt+D | | Ctrl+Option+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | +| Shift+Alt+KeyD | D | Shift+Alt+D | | Shift+Option+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | +| Ctrl+Shift+Alt+KeyD | Î | Ctrl+Shift+Alt+D | | Ctrl+Shift+Option+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyE | e | E | | E | e | E | [KeyE] | | +| Ctrl+KeyE | e | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | +| Shift+KeyE | E | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | +| Ctrl+Shift+KeyE | E | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | +| Alt+KeyE | e | Alt+E | | Option+E | alt+e | Alt+E | alt+[KeyE] | | +| Ctrl+Alt+KeyE | ´ | Ctrl+Alt+E | | Ctrl+Option+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | +| Shift+Alt+KeyE | E | Shift+Alt+E | | Shift+Option+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | +| Ctrl+Shift+Alt+KeyE | ´ | Ctrl+Shift+Alt+E | | Ctrl+Shift+Option+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyF | f | F | | F | f | F | [KeyF] | | +| Ctrl+KeyF | f | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | +| Shift+KeyF | F | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | +| Ctrl+Shift+KeyF | F | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | +| Alt+KeyF | f | Alt+F | | Option+F | alt+f | Alt+F | alt+[KeyF] | | +| Ctrl+Alt+KeyF | ƒ | Ctrl+Alt+F | | Ctrl+Option+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | +| Shift+Alt+KeyF | F | Shift+Alt+F | | Shift+Option+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | +| Ctrl+Shift+Alt+KeyF | Ï | Ctrl+Shift+Alt+F | | Ctrl+Shift+Option+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyG | g | G | | G | g | G | [KeyG] | | +| Ctrl+KeyG | g | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | +| Shift+KeyG | G | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | +| Ctrl+Shift+KeyG | G | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | +| Alt+KeyG | g | Alt+G | | Option+G | alt+g | Alt+G | alt+[KeyG] | | +| Ctrl+Alt+KeyG | © | Ctrl+Alt+G | | Ctrl+Option+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | +| Shift+Alt+KeyG | G | Shift+Alt+G | | Shift+Option+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | +| Ctrl+Shift+Alt+KeyG | ˝ | Ctrl+Shift+Alt+G | | Ctrl+Shift+Option+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyH | h | H | | H | h | H | [KeyH] | | +| Ctrl+KeyH | h | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | +| Shift+KeyH | H | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | +| Ctrl+Shift+KeyH | H | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | +| Alt+KeyH | h | Alt+H | | Option+H | alt+h | Alt+H | alt+[KeyH] | | +| Ctrl+Alt+KeyH | ˙ | Ctrl+Alt+H | | Ctrl+Option+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | +| Shift+Alt+KeyH | H | Shift+Alt+H | | Shift+Option+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | +| Ctrl+Shift+Alt+KeyH | Ó | Ctrl+Shift+Alt+H | | Ctrl+Shift+Option+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyI | i | I | | I | i | I | [KeyI] | | +| Ctrl+KeyI | i | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | +| Shift+KeyI | I | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | +| Ctrl+Shift+KeyI | I | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | +| Alt+KeyI | i | Alt+I | | Option+I | alt+i | Alt+I | alt+[KeyI] | | +| Ctrl+Alt+KeyI | ˆ | Ctrl+Alt+I | | Ctrl+Option+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | +| Shift+Alt+KeyI | I | Shift+Alt+I | | Shift+Option+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | +| Ctrl+Shift+Alt+KeyI | ˆ | Ctrl+Shift+Alt+I | | Ctrl+Shift+Option+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyJ | j | J | | J | j | J | [KeyJ] | | +| Ctrl+KeyJ | j | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | +| Shift+KeyJ | J | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | +| Ctrl+Shift+KeyJ | J | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | +| Alt+KeyJ | j | Alt+J | | Option+J | alt+j | Alt+J | alt+[KeyJ] | | +| Ctrl+Alt+KeyJ | ∆ | Ctrl+Alt+J | | Ctrl+Option+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | +| Shift+Alt+KeyJ | J | Shift+Alt+J | | Shift+Option+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | +| Ctrl+Shift+Alt+KeyJ | Ô | Ctrl+Shift+Alt+J | | Ctrl+Shift+Option+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyK | k | K | | K | k | K | [KeyK] | | +| Ctrl+KeyK | k | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | +| Shift+KeyK | K | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | +| Ctrl+Shift+KeyK | K | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | +| Alt+KeyK | k | Alt+K | | Option+K | alt+k | Alt+K | alt+[KeyK] | | +| Ctrl+Alt+KeyK | ˚ | Ctrl+Alt+K | | Ctrl+Option+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | +| Shift+Alt+KeyK | K | Shift+Alt+K | | Shift+Option+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | +| Ctrl+Shift+Alt+KeyK |  | Ctrl+Shift+Alt+K | | Ctrl+Shift+Option+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyL | l | L | | L | l | L | [KeyL] | | +| Ctrl+KeyL | l | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | +| Shift+KeyL | L | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | +| Ctrl+Shift+KeyL | L | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | +| Alt+KeyL | l | Alt+L | | Option+L | alt+l | Alt+L | alt+[KeyL] | | +| Ctrl+Alt+KeyL | ¬ | Ctrl+Alt+L | | Ctrl+Option+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | +| Shift+Alt+KeyL | L | Shift+Alt+L | | Shift+Option+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | +| Ctrl+Shift+Alt+KeyL | Ò | Ctrl+Shift+Alt+L | | Ctrl+Shift+Option+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyM | m | M | | M | m | M | [KeyM] | | +| Ctrl+KeyM | m | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | +| Shift+KeyM | M | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | +| Ctrl+Shift+KeyM | M | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | +| Alt+KeyM | m | Alt+M | | Option+M | alt+m | Alt+M | alt+[KeyM] | | +| Ctrl+Alt+KeyM | µ | Ctrl+Alt+M | | Ctrl+Option+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | +| Shift+Alt+KeyM | M | Shift+Alt+M | | Shift+Option+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | +| Ctrl+Shift+Alt+KeyM |  | Ctrl+Shift+Alt+M | | Ctrl+Shift+Option+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyN | n | N | | N | n | N | [KeyN] | | +| Ctrl+KeyN | n | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | +| Shift+KeyN | N | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | +| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | +| Alt+KeyN | n | Alt+N | | Option+N | alt+n | Alt+N | alt+[KeyN] | | +| Ctrl+Alt+KeyN | ˜ | Ctrl+Alt+N | | Ctrl+Option+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | +| Shift+Alt+KeyN | N | Shift+Alt+N | | Shift+Option+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | +| Ctrl+Shift+Alt+KeyN | ˜ | Ctrl+Shift+Alt+N | | Ctrl+Shift+Option+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyO | o | O | | O | o | O | [KeyO] | | +| Ctrl+KeyO | o | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | +| Shift+KeyO | O | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | +| Ctrl+Shift+KeyO | O | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | +| Alt+KeyO | o | Alt+O | | Option+O | alt+o | Alt+O | alt+[KeyO] | | +| Ctrl+Alt+KeyO | ø | Ctrl+Alt+O | | Ctrl+Option+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | +| Shift+Alt+KeyO | O | Shift+Alt+O | | Shift+Option+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | +| Ctrl+Shift+Alt+KeyO | Ø | Ctrl+Shift+Alt+O | | Ctrl+Shift+Option+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyP | p | P | | P | p | P | [KeyP] | | +| Ctrl+KeyP | p | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | +| Shift+KeyP | P | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | +| Ctrl+Shift+KeyP | P | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | +| Alt+KeyP | p | Alt+P | | Option+P | alt+p | Alt+P | alt+[KeyP] | | +| Ctrl+Alt+KeyP | π | Ctrl+Alt+P | | Ctrl+Option+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | +| Shift+Alt+KeyP | P | Shift+Alt+P | | Shift+Option+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | +| Ctrl+Shift+Alt+KeyP | ∏ | Ctrl+Shift+Alt+P | | Ctrl+Shift+Option+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyQ | q | Q | | Q | q | Q | [KeyQ] | | +| Ctrl+KeyQ | q | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | +| Shift+KeyQ | Q | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | +| Ctrl+Shift+KeyQ | Q | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | +| Alt+KeyQ | q | Alt+Q | | Option+Q | alt+q | Alt+Q | alt+[KeyQ] | | +| Ctrl+Alt+KeyQ | œ | Ctrl+Alt+Q | | Ctrl+Option+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | +| Shift+Alt+KeyQ | Q | Shift+Alt+Q | | Shift+Option+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | +| Ctrl+Shift+Alt+KeyQ | Œ | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Option+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyR | r | R | | R | r | R | [KeyR] | | +| Ctrl+KeyR | r | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | +| Shift+KeyR | R | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | +| Ctrl+Shift+KeyR | R | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | +| Alt+KeyR | r | Alt+R | | Option+R | alt+r | Alt+R | alt+[KeyR] | | +| Ctrl+Alt+KeyR | ® | Ctrl+Alt+R | | Ctrl+Option+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | +| Shift+Alt+KeyR | R | Shift+Alt+R | | Shift+Option+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | +| Ctrl+Shift+Alt+KeyR | ‰ | Ctrl+Shift+Alt+R | | Ctrl+Shift+Option+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyS | s | S | | S | s | S | [KeyS] | | +| Ctrl+KeyS | s | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | +| Shift+KeyS | S | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | +| Ctrl+Shift+KeyS | S | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | +| Alt+KeyS | s | Alt+S | | Option+S | alt+s | Alt+S | alt+[KeyS] | | +| Ctrl+Alt+KeyS | ß | Ctrl+Alt+S | | Ctrl+Option+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | +| Shift+Alt+KeyS | S | Shift+Alt+S | | Shift+Option+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | +| Ctrl+Shift+Alt+KeyS | Í | Ctrl+Shift+Alt+S | | Ctrl+Shift+Option+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyT | t | T | | T | t | T | [KeyT] | | +| Ctrl+KeyT | t | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | +| Shift+KeyT | T | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | +| Ctrl+Shift+KeyT | T | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | +| Alt+KeyT | t | Alt+T | | Option+T | alt+t | Alt+T | alt+[KeyT] | | +| Ctrl+Alt+KeyT | † | Ctrl+Alt+T | | Ctrl+Option+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | +| Shift+Alt+KeyT | T | Shift+Alt+T | | Shift+Option+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | +| Ctrl+Shift+Alt+KeyT | ˇ | Ctrl+Shift+Alt+T | | Ctrl+Shift+Option+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyU | u | U | | U | u | U | [KeyU] | | +| Ctrl+KeyU | u | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | +| Shift+KeyU | U | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | +| Ctrl+Shift+KeyU | U | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | +| Alt+KeyU | u | Alt+U | | Option+U | alt+u | Alt+U | alt+[KeyU] | | +| Ctrl+Alt+KeyU | ¨ | Ctrl+Alt+U | | Ctrl+Option+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | +| Shift+Alt+KeyU | U | Shift+Alt+U | | Shift+Option+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | +| Ctrl+Shift+Alt+KeyU | ¨ | Ctrl+Shift+Alt+U | | Ctrl+Shift+Option+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyV | v | V | | V | v | V | [KeyV] | | +| Ctrl+KeyV | v | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | +| Shift+KeyV | V | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | +| Ctrl+Shift+KeyV | V | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | +| Alt+KeyV | v | Alt+V | | Option+V | alt+v | Alt+V | alt+[KeyV] | | +| Ctrl+Alt+KeyV | √ | Ctrl+Alt+V | | Ctrl+Option+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | +| Shift+Alt+KeyV | V | Shift+Alt+V | | Shift+Option+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | +| Ctrl+Shift+Alt+KeyV | ◊ | Ctrl+Shift+Alt+V | | Ctrl+Shift+Option+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyW | w | W | | W | w | W | [KeyW] | | +| Ctrl+KeyW | w | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | +| Shift+KeyW | W | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | +| Ctrl+Shift+KeyW | W | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | +| Alt+KeyW | w | Alt+W | | Option+W | alt+w | Alt+W | alt+[KeyW] | | +| Ctrl+Alt+KeyW | ∑ | Ctrl+Alt+W | | Ctrl+Option+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | +| Shift+Alt+KeyW | W | Shift+Alt+W | | Shift+Option+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | +| Ctrl+Shift+Alt+KeyW | „ | Ctrl+Shift+Alt+W | | Ctrl+Shift+Option+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyX | x | X | | X | x | X | [KeyX] | | +| Ctrl+KeyX | x | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | +| Shift+KeyX | X | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | +| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | +| Alt+KeyX | x | Alt+X | | Option+X | alt+x | Alt+X | alt+[KeyX] | | +| Ctrl+Alt+KeyX | ≈ | Ctrl+Alt+X | | Ctrl+Option+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | +| Shift+Alt+KeyX | X | Shift+Alt+X | | Shift+Option+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | +| Ctrl+Shift+Alt+KeyX | ˛ | Ctrl+Shift+Alt+X | | Ctrl+Shift+Option+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyY | y | Y | | Y | y | Y | [KeyY] | | +| Ctrl+KeyY | y | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyY] | | +| Shift+KeyY | Y | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyY] | | +| Ctrl+Shift+KeyY | Y | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyY] | | +| Alt+KeyY | y | Alt+Y | | Option+Y | alt+y | Alt+Y | alt+[KeyY] | | +| Ctrl+Alt+KeyY | ¥ | Ctrl+Alt+Y | | Ctrl+Option+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyY] | | +| Shift+Alt+KeyY | Y | Shift+Alt+Y | | Shift+Option+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyY] | | +| Ctrl+Shift+Alt+KeyY | Á | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Option+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyY] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyZ | z | Z | | Z | z | Z | [KeyZ] | | +| Ctrl+KeyZ | z | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyZ] | | +| Shift+KeyZ | Z | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyZ] | | +| Ctrl+Shift+KeyZ | Z | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyZ] | | +| Alt+KeyZ | z | Alt+Z | | Option+Z | alt+z | Alt+Z | alt+[KeyZ] | | +| Ctrl+Alt+KeyZ | Ω | Ctrl+Alt+Z | | Ctrl+Option+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyZ] | | +| Shift+Alt+KeyZ | Z | Shift+Alt+Z | | Shift+Option+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyZ] | | +| Ctrl+Shift+Alt+KeyZ | ¸ | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Option+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyZ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit1 | 1 | 1 | | 1 | 1 | 1 | [Digit1] | | +| Ctrl+Digit1 | 1 | Ctrl+1 | | Ctrl+1 | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | | +| Shift+Digit1 | ! | Shift+1 | | Shift+1 | shift+1 | Shift+1 | shift+[Digit1] | | +| Ctrl+Shift+Digit1 | ! | Ctrl+Shift+1 | | Ctrl+Shift+1 | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | | +| Alt+Digit1 | 1 | Alt+1 | | Option+1 | alt+1 | Alt+1 | alt+[Digit1] | | +| Ctrl+Alt+Digit1 | ¡ | Ctrl+Alt+1 | | Ctrl+Option+1 | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | | +| Shift+Alt+Digit1 | ! | Shift+Alt+1 | | Shift+Option+1 | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | | +| Ctrl+Shift+Alt+Digit1 | ⁄ | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Option+1 | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit2 | 2 | 2 | | 2 | 2 | 2 | [Digit2] | | +| Ctrl+Digit2 | 2 | Ctrl+2 | | Ctrl+2 | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | | +| Shift+Digit2 | @ | Shift+2 | | Shift+2 | shift+2 | Shift+2 | shift+[Digit2] | | +| Ctrl+Shift+Digit2 | @ | Ctrl+Shift+2 | | Ctrl+Shift+2 | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | | +| Alt+Digit2 | 2 | Alt+2 | | Option+2 | alt+2 | Alt+2 | alt+[Digit2] | | +| Ctrl+Alt+Digit2 | ™ | Ctrl+Alt+2 | | Ctrl+Option+2 | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | | +| Shift+Alt+Digit2 | @ | Shift+Alt+2 | | Shift+Option+2 | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | | +| Ctrl+Shift+Alt+Digit2 | € | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Option+2 | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit3 | 3 | 3 | | 3 | 3 | 3 | [Digit3] | | +| Ctrl+Digit3 | 3 | Ctrl+3 | | Ctrl+3 | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | | +| Shift+Digit3 | # | Shift+3 | | Shift+3 | shift+3 | Shift+3 | shift+[Digit3] | | +| Ctrl+Shift+Digit3 | # | Ctrl+Shift+3 | | Ctrl+Shift+3 | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | | +| Alt+Digit3 | 3 | Alt+3 | | Option+3 | alt+3 | Alt+3 | alt+[Digit3] | | +| Ctrl+Alt+Digit3 | £ | Ctrl+Alt+3 | | Ctrl+Option+3 | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | | +| Shift+Alt+Digit3 | # | Shift+Alt+3 | | Shift+Option+3 | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | | +| Ctrl+Shift+Alt+Digit3 | ‹ | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Option+3 | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit4 | 4 | 4 | | 4 | 4 | 4 | [Digit4] | | +| Ctrl+Digit4 | 4 | Ctrl+4 | | Ctrl+4 | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | | +| Shift+Digit4 | $ | Shift+4 | | Shift+4 | shift+4 | Shift+4 | shift+[Digit4] | | +| Ctrl+Shift+Digit4 | $ | Ctrl+Shift+4 | | Ctrl+Shift+4 | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | | +| Alt+Digit4 | 4 | Alt+4 | | Option+4 | alt+4 | Alt+4 | alt+[Digit4] | | +| Ctrl+Alt+Digit4 | ¢ | Ctrl+Alt+4 | | Ctrl+Option+4 | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | | +| Shift+Alt+Digit4 | $ | Shift+Alt+4 | | Shift+Option+4 | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | | +| Ctrl+Shift+Alt+Digit4 | › | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Option+4 | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit5 | 5 | 5 | | 5 | 5 | 5 | [Digit5] | | +| Ctrl+Digit5 | 5 | Ctrl+5 | | Ctrl+5 | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | | +| Shift+Digit5 | % | Shift+5 | | Shift+5 | shift+5 | Shift+5 | shift+[Digit5] | | +| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+5 | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | | +| Alt+Digit5 | 5 | Alt+5 | | Option+5 | alt+5 | Alt+5 | alt+[Digit5] | | +| Ctrl+Alt+Digit5 | ∞ | Ctrl+Alt+5 | | Ctrl+Option+5 | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | | +| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Option+5 | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | | +| Ctrl+Shift+Alt+Digit5 | fi | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Option+5 | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit6 | 6 | 6 | | 6 | 6 | 6 | [Digit6] | | +| Ctrl+Digit6 | 6 | Ctrl+6 | | Ctrl+6 | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | | +| Shift+Digit6 | ^ | Shift+6 | | Shift+6 | shift+6 | Shift+6 | shift+[Digit6] | | +| Ctrl+Shift+Digit6 | ^ | Ctrl+Shift+6 | | Ctrl+Shift+6 | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | | +| Alt+Digit6 | 6 | Alt+6 | | Option+6 | alt+6 | Alt+6 | alt+[Digit6] | | +| Ctrl+Alt+Digit6 | § | Ctrl+Alt+6 | | Ctrl+Option+6 | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | | +| Shift+Alt+Digit6 | ^ | Shift+Alt+6 | | Shift+Option+6 | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | | +| Ctrl+Shift+Alt+Digit6 | fl | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Option+6 | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit7 | 7 | 7 | | 7 | 7 | 7 | [Digit7] | | +| Ctrl+Digit7 | 7 | Ctrl+7 | | Ctrl+7 | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | | +| Shift+Digit7 | & | Shift+7 | | Shift+7 | shift+7 | Shift+7 | shift+[Digit7] | | +| Ctrl+Shift+Digit7 | & | Ctrl+Shift+7 | | Ctrl+Shift+7 | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | | +| Alt+Digit7 | 7 | Alt+7 | | Option+7 | alt+7 | Alt+7 | alt+[Digit7] | | +| Ctrl+Alt+Digit7 | ¶ | Ctrl+Alt+7 | | Ctrl+Option+7 | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | | +| Shift+Alt+Digit7 | & | Shift+Alt+7 | | Shift+Option+7 | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | | +| Ctrl+Shift+Alt+Digit7 | ‡ | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Option+7 | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit8 | 8 | 8 | | 8 | 8 | 8 | [Digit8] | | +| Ctrl+Digit8 | 8 | Ctrl+8 | | Ctrl+8 | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | | +| Shift+Digit8 | * | Shift+8 | | Shift+8 | shift+8 | Shift+8 | shift+[Digit8] | | +| Ctrl+Shift+Digit8 | * | Ctrl+Shift+8 | | Ctrl+Shift+8 | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | | +| Alt+Digit8 | 8 | Alt+8 | | Option+8 | alt+8 | Alt+8 | alt+[Digit8] | | +| Ctrl+Alt+Digit8 | • | Ctrl+Alt+8 | | Ctrl+Option+8 | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | | +| Shift+Alt+Digit8 | * | Shift+Alt+8 | | Shift+Option+8 | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | | +| Ctrl+Shift+Alt+Digit8 | ° | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Option+8 | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit9 | 9 | 9 | | 9 | 9 | 9 | [Digit9] | | +| Ctrl+Digit9 | 9 | Ctrl+9 | | Ctrl+9 | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | | +| Shift+Digit9 | ( | Shift+9 | | Shift+9 | shift+9 | Shift+9 | shift+[Digit9] | | +| Ctrl+Shift+Digit9 | ( | Ctrl+Shift+9 | | Ctrl+Shift+9 | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | | +| Alt+Digit9 | 9 | Alt+9 | | Option+9 | alt+9 | Alt+9 | alt+[Digit9] | | +| Ctrl+Alt+Digit9 | ª | Ctrl+Alt+9 | | Ctrl+Option+9 | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | | +| Shift+Alt+Digit9 | ( | Shift+Alt+9 | | Shift+Option+9 | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | | +| Ctrl+Shift+Alt+Digit9 | · | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Option+9 | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit0 | 0 | 0 | | 0 | 0 | 0 | [Digit0] | | +| Ctrl+Digit0 | 0 | Ctrl+0 | | Ctrl+0 | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | | +| Shift+Digit0 | ) | Shift+0 | | Shift+0 | shift+0 | Shift+0 | shift+[Digit0] | | +| Ctrl+Shift+Digit0 | ) | Ctrl+Shift+0 | | Ctrl+Shift+0 | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | | +| Alt+Digit0 | 0 | Alt+0 | | Option+0 | alt+0 | Alt+0 | alt+[Digit0] | | +| Ctrl+Alt+Digit0 | º | Ctrl+Alt+0 | | Ctrl+Option+0 | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | | +| Shift+Alt+Digit0 | ) | Shift+Alt+0 | | Shift+Option+0 | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | | +| Ctrl+Shift+Alt+Digit0 | ‚ | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Option+0 | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Minus | - | - | | - | - | - | [Minus] | | +| Ctrl+Minus | - | Ctrl+- | | Ctrl+- | ctrl+- | Ctrl+- | ctrl+[Minus] | | +| Shift+Minus | _ | Shift+- | | Shift+- | shift+- | Shift+- | shift+[Minus] | | +| Ctrl+Shift+Minus | _ | Ctrl+Shift+- | | Ctrl+Shift+- | ctrl+shift+- | Ctrl+Shift+- | ctrl+shift+[Minus] | | +| Alt+Minus | - | Alt+- | | Option+- | alt+- | Alt+- | alt+[Minus] | | +| Ctrl+Alt+Minus | – | Ctrl+Alt+- | | Ctrl+Option+- | ctrl+alt+- | Ctrl+Alt+- | ctrl+alt+[Minus] | | +| Shift+Alt+Minus | _ | Shift+Alt+- | | Shift+Option+- | shift+alt+- | Shift+Alt+- | shift+alt+[Minus] | | +| Ctrl+Shift+Alt+Minus | — | Ctrl+Shift+Alt+- | | Ctrl+Shift+Option+- | ctrl+shift+alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+[Minus] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Equal | = | = | | = | = | = | [Equal] | | +| Ctrl+Equal | = | Ctrl+= | | Ctrl+= | ctrl+= | Ctrl+= | ctrl+[Equal] | | +| Shift+Equal | + | Shift+= | | Shift+= | shift+= | Shift+= | shift+[Equal] | | +| Ctrl+Shift+Equal | + | Ctrl+Shift+= | | Ctrl+Shift+= | ctrl+shift+= | Ctrl+Shift+= | ctrl+shift+[Equal] | | +| Alt+Equal | = | Alt+= | | Option+= | alt+= | Alt+= | alt+[Equal] | | +| Ctrl+Alt+Equal | ≠ | Ctrl+Alt+= | | Ctrl+Option+= | ctrl+alt+= | Ctrl+Alt+= | ctrl+alt+[Equal] | | +| Shift+Alt+Equal | + | Shift+Alt+= | | Shift+Option+= | shift+alt+= | Shift+Alt+= | shift+alt+[Equal] | | +| Ctrl+Shift+Alt+Equal | ± | Ctrl+Shift+Alt+= | | Ctrl+Shift+Option+= | ctrl+shift+alt+= | Ctrl+Shift+Alt+= | ctrl+shift+alt+[Equal] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketLeft | [ | [ | | [ | [ | [ | [BracketLeft] | | +| Ctrl+BracketLeft | [ | Ctrl+[ | | Ctrl+[ | ctrl+[ | Ctrl+[ | ctrl+[BracketLeft] | | +| Shift+BracketLeft | { | Shift+[ | | Shift+[ | shift+[ | Shift+[ | shift+[BracketLeft] | | +| Ctrl+Shift+BracketLeft | { | Ctrl+Shift+[ | | Ctrl+Shift+[ | ctrl+shift+[ | Ctrl+Shift+[ | ctrl+shift+[BracketLeft] | | +| Alt+BracketLeft | [ | Alt+[ | | Option+[ | alt+[ | Alt+[ | alt+[BracketLeft] | | +| Ctrl+Alt+BracketLeft | “ | Ctrl+Alt+[ | | Ctrl+Option+[ | ctrl+alt+[ | Ctrl+Alt+[ | ctrl+alt+[BracketLeft] | | +| Shift+Alt+BracketLeft | { | Shift+Alt+[ | | Shift+Option+[ | shift+alt+[ | Shift+Alt+[ | shift+alt+[BracketLeft] | | +| Ctrl+Shift+Alt+BracketLeft | ” | Ctrl+Shift+Alt+[ | | Ctrl+Shift+Option+[ | ctrl+shift+alt+[ | Ctrl+Shift+Alt+[ | ctrl+shift+alt+[BracketLeft] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketRight | ] | ] | | ] | ] | ] | [BracketRight] | | +| Ctrl+BracketRight | ] | Ctrl+] | | Ctrl+] | ctrl+] | Ctrl+] | ctrl+[BracketRight] | | +| Shift+BracketRight | } | Shift+] | | Shift+] | shift+] | Shift+] | shift+[BracketRight] | | +| Ctrl+Shift+BracketRight | } | Ctrl+Shift+] | | Ctrl+Shift+] | ctrl+shift+] | Ctrl+Shift+] | ctrl+shift+[BracketRight] | | +| Alt+BracketRight | ] | Alt+] | | Option+] | alt+] | Alt+] | alt+[BracketRight] | | +| Ctrl+Alt+BracketRight | ‘ | Ctrl+Alt+] | | Ctrl+Option+] | ctrl+alt+] | Ctrl+Alt+] | ctrl+alt+[BracketRight] | | +| Shift+Alt+BracketRight | } | Shift+Alt+] | | Shift+Option+] | shift+alt+] | Shift+Alt+] | shift+alt+[BracketRight] | | +| Ctrl+Shift+Alt+BracketRight | ’ | Ctrl+Shift+Alt+] | | Ctrl+Shift+Option+] | ctrl+shift+alt+] | Ctrl+Shift+Alt+] | ctrl+shift+alt+[BracketRight] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backslash | \ | \ | | \ | \ | \ | [Backslash] | | +| Ctrl+Backslash | \ | Ctrl+\ | | Ctrl+\ | ctrl+\ | Ctrl+\ | ctrl+[Backslash] | | +| Shift+Backslash | | | Shift+\ | | Shift+\ | shift+\ | Shift+\ | shift+[Backslash] | | +| Ctrl+Shift+Backslash | | | Ctrl+Shift+\ | | Ctrl+Shift+\ | ctrl+shift+\ | Ctrl+Shift+\ | ctrl+shift+[Backslash] | | +| Alt+Backslash | \ | Alt+\ | | Option+\ | alt+\ | Alt+\ | alt+[Backslash] | | +| Ctrl+Alt+Backslash | « | Ctrl+Alt+\ | | Ctrl+Option+\ | ctrl+alt+\ | Ctrl+Alt+\ | ctrl+alt+[Backslash] | | +| Shift+Alt+Backslash | | | Shift+Alt+\ | | Shift+Option+\ | shift+alt+\ | Shift+Alt+\ | shift+alt+[Backslash] | | +| Ctrl+Shift+Alt+Backslash | » | Ctrl+Shift+Alt+\ | | Ctrl+Shift+Option+\ | ctrl+shift+alt+\ | Ctrl+Shift+Alt+\ | ctrl+shift+alt+[Backslash] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlHash | --- | | | null | null | null | null | | +| Ctrl+IntlHash | --- | | | null | null | null | null | | +| Shift+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | +| Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | +| Shift+Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Semicolon | ; | ; | | ; | ; | ; | [Semicolon] | | +| Ctrl+Semicolon | ; | Ctrl+; | | Ctrl+; | ctrl+; | Ctrl+; | ctrl+[Semicolon] | | +| Shift+Semicolon | : | Shift+; | | Shift+; | shift+; | Shift+; | shift+[Semicolon] | | +| Ctrl+Shift+Semicolon | : | Ctrl+Shift+; | | Ctrl+Shift+; | ctrl+shift+; | Ctrl+Shift+; | ctrl+shift+[Semicolon] | | +| Alt+Semicolon | ; | Alt+; | | Option+; | alt+; | Alt+; | alt+[Semicolon] | | +| Ctrl+Alt+Semicolon | … | Ctrl+Alt+; | | Ctrl+Option+; | ctrl+alt+; | Ctrl+Alt+; | ctrl+alt+[Semicolon] | | +| Shift+Alt+Semicolon | : | Shift+Alt+; | | Shift+Option+; | shift+alt+; | Shift+Alt+; | shift+alt+[Semicolon] | | +| Ctrl+Shift+Alt+Semicolon | Ú | Ctrl+Shift+Alt+; | | Ctrl+Shift+Option+; | ctrl+shift+alt+; | Ctrl+Shift+Alt+; | ctrl+shift+alt+[Semicolon] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Quote | ' | ' | | ' | ' | ' | [Quote] | | +| Ctrl+Quote | ' | Ctrl+' | | Ctrl+' | ctrl+' | Ctrl+' | ctrl+[Quote] | | +| Shift+Quote | " | Shift+' | | Shift+' | shift+' | Shift+' | shift+[Quote] | | +| Ctrl+Shift+Quote | " | Ctrl+Shift+' | | Ctrl+Shift+' | ctrl+shift+' | Ctrl+Shift+' | ctrl+shift+[Quote] | | +| Alt+Quote | ' | Alt+' | | Option+' | alt+' | Alt+' | alt+[Quote] | | +| Ctrl+Alt+Quote | æ | Ctrl+Alt+' | | Ctrl+Option+' | ctrl+alt+' | Ctrl+Alt+' | ctrl+alt+[Quote] | | +| Shift+Alt+Quote | " | Shift+Alt+' | | Shift+Option+' | shift+alt+' | Shift+Alt+' | shift+alt+[Quote] | | +| Ctrl+Shift+Alt+Quote | Æ | Ctrl+Shift+Alt+' | | Ctrl+Shift+Option+' | ctrl+shift+alt+' | Ctrl+Shift+Alt+' | ctrl+shift+alt+[Quote] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backquote | ` | ` | | ` | ` | ` | [Backquote] | | +| Ctrl+Backquote | ` | Ctrl+` | | Ctrl+` | ctrl+` | Ctrl+` | ctrl+[Backquote] | | +| Shift+Backquote | ~ | Shift+` | | Shift+` | shift+` | Shift+` | shift+[Backquote] | | +| Ctrl+Shift+Backquote | ~ | Ctrl+Shift+` | | Ctrl+Shift+` | ctrl+shift+` | Ctrl+Shift+` | ctrl+shift+[Backquote] | | +| Alt+Backquote | ` | Alt+` | | Option+` | alt+` | Alt+` | alt+[Backquote] | | +| Ctrl+Alt+Backquote | ` | Ctrl+Alt+` | | Ctrl+Option+` | ctrl+alt+` | Ctrl+Alt+` | ctrl+alt+[Backquote] | | +| Shift+Alt+Backquote | ~ | Shift+Alt+` | | Shift+Option+` | shift+alt+` | Shift+Alt+` | shift+alt+[Backquote] | | +| Ctrl+Shift+Alt+Backquote | ` | Ctrl+Shift+Alt+` | | Ctrl+Shift+Option+` | ctrl+shift+alt+` | Ctrl+Shift+Alt+` | ctrl+shift+alt+[Backquote] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Comma | , | , | | , | , | , | [Comma] | | +| Ctrl+Comma | , | Ctrl+, | | Ctrl+, | ctrl+, | Ctrl+, | ctrl+[Comma] | | +| Shift+Comma | < | Shift+, | | Shift+, | shift+, | Shift+, | shift+[Comma] | | +| Ctrl+Shift+Comma | < | Ctrl+Shift+, | | Ctrl+Shift+, | ctrl+shift+, | Ctrl+Shift+, | ctrl+shift+[Comma] | | +| Alt+Comma | , | Alt+, | | Option+, | alt+, | Alt+, | alt+[Comma] | | +| Ctrl+Alt+Comma | ≤ | Ctrl+Alt+, | | Ctrl+Option+, | ctrl+alt+, | Ctrl+Alt+, | ctrl+alt+[Comma] | | +| Shift+Alt+Comma | < | Shift+Alt+, | | Shift+Option+, | shift+alt+, | Shift+Alt+, | shift+alt+[Comma] | | +| Ctrl+Shift+Alt+Comma | ¯ | Ctrl+Shift+Alt+, | | Ctrl+Shift+Option+, | ctrl+shift+alt+, | Ctrl+Shift+Alt+, | ctrl+shift+alt+[Comma] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Period | . | . | | . | . | . | [Period] | | +| Ctrl+Period | . | Ctrl+. | | Ctrl+. | ctrl+. | Ctrl+. | ctrl+[Period] | | +| Shift+Period | > | Shift+. | | Shift+. | shift+. | Shift+. | shift+[Period] | | +| Ctrl+Shift+Period | > | Ctrl+Shift+. | | Ctrl+Shift+. | ctrl+shift+. | Ctrl+Shift+. | ctrl+shift+[Period] | | +| Alt+Period | . | Alt+. | | Option+. | alt+. | Alt+. | alt+[Period] | | +| Ctrl+Alt+Period | ≥ | Ctrl+Alt+. | | Ctrl+Option+. | ctrl+alt+. | Ctrl+Alt+. | ctrl+alt+[Period] | | +| Shift+Alt+Period | > | Shift+Alt+. | | Shift+Option+. | shift+alt+. | Shift+Alt+. | shift+alt+[Period] | | +| Ctrl+Shift+Alt+Period | ˘ | Ctrl+Shift+Alt+. | | Ctrl+Shift+Option+. | ctrl+shift+alt+. | Ctrl+Shift+Alt+. | ctrl+shift+alt+[Period] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Slash | / | / | | / | / | / | [Slash] | | +| Ctrl+Slash | / | Ctrl+/ | | Ctrl+/ | ctrl+/ | Ctrl+/ | ctrl+[Slash] | | +| Shift+Slash | ? | Shift+/ | | Shift+/ | shift+/ | Shift+/ | shift+[Slash] | | +| Ctrl+Shift+Slash | ? | Ctrl+Shift+/ | | Ctrl+Shift+/ | ctrl+shift+/ | Ctrl+Shift+/ | ctrl+shift+[Slash] | | +| Alt+Slash | / | Alt+/ | | Option+/ | alt+/ | Alt+/ | alt+[Slash] | | +| Ctrl+Alt+Slash | ÷ | Ctrl+Alt+/ | | Ctrl+Option+/ | ctrl+alt+/ | Ctrl+Alt+/ | ctrl+alt+[Slash] | | +| Shift+Alt+Slash | ? | Shift+Alt+/ | | Shift+Option+/ | shift+alt+/ | Shift+Alt+/ | shift+alt+[Slash] | | +| Ctrl+Shift+Alt+Slash | ¿ | Ctrl+Shift+Alt+/ | | Ctrl+Shift+Option+/ | ctrl+shift+alt+/ | Ctrl+Shift+Alt+/ | ctrl+shift+alt+[Slash] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | +| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | +| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | +| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | +| Alt+ArrowUp | --- | Alt+UpArrow | | Option+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | +| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Option+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | +| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Option+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | +| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Option+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | +| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | +| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | +| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | +| Alt+Numpad0 | --- | Alt+NumPad0 | | Option+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | +| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Option+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | +| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Option+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | +| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Option+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlBackslash | § | | | § | [IntlBackslash] | null | [IntlBackslash] | NO | +| Ctrl+IntlBackslash | § | | | Ctrl+§ | ctrl+[IntlBackslash] | null | ctrl+[IntlBackslash] | NO | +| Shift+IntlBackslash | ± | | | Shift+§ | shift+[IntlBackslash] | null | shift+[IntlBackslash] | NO | +| Ctrl+Shift+IntlBackslash | ± | | | Ctrl+Shift+§ | ctrl+shift+[IntlBackslash] | null | ctrl+shift+[IntlBackslash] | NO | +| Alt+IntlBackslash | § | | | Option+§ | alt+[IntlBackslash] | null | alt+[IntlBackslash] | NO | +| Ctrl+Alt+IntlBackslash | § | | | Ctrl+Option+§ | ctrl+alt+[IntlBackslash] | null | ctrl+alt+[IntlBackslash] | NO | +| Shift+Alt+IntlBackslash | ± | | | Shift+Option+§ | shift+alt+[IntlBackslash] | null | shift+alt+[IntlBackslash] | NO | +| Ctrl+Shift+Alt+IntlBackslash | ± | | | Ctrl+Shift+Option+§ | ctrl+shift+alt+[IntlBackslash] | null | ctrl+shift+alt+[IntlBackslash] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | +| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | +| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | +| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | +| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | +| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | +| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | +| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | +| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | +| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | +| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | +| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | +| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | +| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | +| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/node/mac_zh_hant.js b/src/vs/workbench/services/keybinding/test/node/mac_zh_hant.js new file mode 100644 index 00000000000..7a3fd205cc5 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/mac_zh_hant.js @@ -0,0 +1,1188 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +define({ + KeyA: { + value: 'ㄇ', + valueIsDeadKey: false, + withShift: 'A', + withShiftIsDeadKey: false, + withAltGr: 'a', + withAltGrIsDeadKey: false, + withShiftAltGr: 'A', + withShiftAltGrIsDeadKey: false + }, + KeyB: { + value: 'ㄖ', + valueIsDeadKey: false, + withShift: 'B', + withShiftIsDeadKey: false, + withAltGr: 'b', + withAltGrIsDeadKey: false, + withShiftAltGr: 'B', + withShiftAltGrIsDeadKey: false + }, + KeyC: { + value: 'ㄏ', + valueIsDeadKey: false, + withShift: 'C', + withShiftIsDeadKey: false, + withAltGr: 'c', + withAltGrIsDeadKey: false, + withShiftAltGr: 'C', + withShiftAltGrIsDeadKey: false + }, + KeyD: { + value: 'ㄎ', + valueIsDeadKey: false, + withShift: 'D', + withShiftIsDeadKey: false, + withAltGr: 'd', + withAltGrIsDeadKey: false, + withShiftAltGr: 'D', + withShiftAltGrIsDeadKey: false + }, + KeyE: { + value: 'ㄍ', + valueIsDeadKey: false, + withShift: 'E', + withShiftIsDeadKey: false, + withAltGr: 'e', + withAltGrIsDeadKey: false, + withShiftAltGr: 'E', + withShiftAltGrIsDeadKey: false + }, + KeyF: { + value: 'ㄑ', + valueIsDeadKey: false, + withShift: 'F', + withShiftIsDeadKey: false, + withAltGr: 'f', + withAltGrIsDeadKey: false, + withShiftAltGr: 'F', + withShiftAltGrIsDeadKey: false + }, + KeyG: { + value: 'ㄕ', + valueIsDeadKey: false, + withShift: 'G', + withShiftIsDeadKey: false, + withAltGr: 'g', + withAltGrIsDeadKey: false, + withShiftAltGr: 'G', + withShiftAltGrIsDeadKey: false + }, + KeyH: { + value: 'ㄘ', + valueIsDeadKey: false, + withShift: 'H', + withShiftIsDeadKey: false, + withAltGr: 'h', + withAltGrIsDeadKey: false, + withShiftAltGr: 'H', + withShiftAltGrIsDeadKey: false + }, + KeyI: { + value: 'ㄛ', + valueIsDeadKey: false, + withShift: 'I', + withShiftIsDeadKey: false, + withAltGr: 'i', + withAltGrIsDeadKey: false, + withShiftAltGr: 'I', + withShiftAltGrIsDeadKey: false + }, + KeyJ: { + value: 'ㄨ', + valueIsDeadKey: false, + withShift: 'J', + withShiftIsDeadKey: false, + withAltGr: 'j', + withAltGrIsDeadKey: false, + withShiftAltGr: 'J', + withShiftAltGrIsDeadKey: false + }, + KeyK: { + value: 'ㄜ', + valueIsDeadKey: false, + withShift: 'K', + withShiftIsDeadKey: false, + withAltGr: 'k', + withAltGrIsDeadKey: false, + withShiftAltGr: 'K', + withShiftAltGrIsDeadKey: false + }, + KeyL: { + value: 'ㄠ', + valueIsDeadKey: false, + withShift: 'L', + withShiftIsDeadKey: false, + withAltGr: 'l', + withAltGrIsDeadKey: false, + withShiftAltGr: 'L', + withShiftAltGrIsDeadKey: false + }, + KeyM: { + value: 'ㄩ', + valueIsDeadKey: false, + withShift: 'M', + withShiftIsDeadKey: false, + withAltGr: 'm', + withAltGrIsDeadKey: false, + withShiftAltGr: 'M', + withShiftAltGrIsDeadKey: false + }, + KeyN: { + value: 'ㄙ', + valueIsDeadKey: false, + withShift: 'N', + withShiftIsDeadKey: false, + withAltGr: 'n', + withAltGrIsDeadKey: false, + withShiftAltGr: 'N', + withShiftAltGrIsDeadKey: false + }, + KeyO: { + value: 'ㄟ', + valueIsDeadKey: false, + withShift: 'O', + withShiftIsDeadKey: false, + withAltGr: 'o', + withAltGrIsDeadKey: false, + withShiftAltGr: 'O', + withShiftAltGrIsDeadKey: false + }, + KeyP: { + value: 'ㄣ', + valueIsDeadKey: false, + withShift: 'P', + withShiftIsDeadKey: false, + withAltGr: 'p', + withAltGrIsDeadKey: false, + withShiftAltGr: 'P', + withShiftAltGrIsDeadKey: false + }, + KeyQ: { + value: 'ㄆ', + valueIsDeadKey: false, + withShift: 'Q', + withShiftIsDeadKey: false, + withAltGr: 'q', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Q', + withShiftAltGrIsDeadKey: false + }, + KeyR: { + value: 'ㄐ', + valueIsDeadKey: false, + withShift: 'R', + withShiftIsDeadKey: false, + withAltGr: 'r', + withAltGrIsDeadKey: false, + withShiftAltGr: 'R', + withShiftAltGrIsDeadKey: false + }, + KeyS: { + value: 'ㄋ', + valueIsDeadKey: false, + withShift: 'S', + withShiftIsDeadKey: false, + withAltGr: 's', + withAltGrIsDeadKey: false, + withShiftAltGr: 'S', + withShiftAltGrIsDeadKey: false + }, + KeyT: { + value: 'ㄔ', + valueIsDeadKey: false, + withShift: 'T', + withShiftIsDeadKey: false, + withAltGr: 't', + withAltGrIsDeadKey: false, + withShiftAltGr: 'T', + withShiftAltGrIsDeadKey: false + }, + KeyU: { + value: 'ㄧ', + valueIsDeadKey: false, + withShift: 'U', + withShiftIsDeadKey: false, + withAltGr: 'u', + withAltGrIsDeadKey: false, + withShiftAltGr: 'U', + withShiftAltGrIsDeadKey: false + }, + KeyV: { + value: 'ㄒ', + valueIsDeadKey: false, + withShift: 'V', + withShiftIsDeadKey: false, + withAltGr: 'v', + withAltGrIsDeadKey: false, + withShiftAltGr: 'V', + withShiftAltGrIsDeadKey: false + }, + KeyW: { + value: 'ㄊ', + valueIsDeadKey: false, + withShift: 'W', + withShiftIsDeadKey: false, + withAltGr: 'w', + withAltGrIsDeadKey: false, + withShiftAltGr: 'W', + withShiftAltGrIsDeadKey: false + }, + KeyX: { + value: 'ㄌ', + valueIsDeadKey: false, + withShift: 'X', + withShiftIsDeadKey: false, + withAltGr: 'x', + withAltGrIsDeadKey: false, + withShiftAltGr: 'X', + withShiftAltGrIsDeadKey: false + }, + KeyY: { + value: 'ㄗ', + valueIsDeadKey: false, + withShift: 'Y', + withShiftIsDeadKey: false, + withAltGr: 'y', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Y', + withShiftAltGrIsDeadKey: false + }, + KeyZ: { + value: 'ㄈ', + valueIsDeadKey: false, + withShift: 'Z', + withShiftIsDeadKey: false, + withAltGr: 'z', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Z', + withShiftAltGrIsDeadKey: false + }, + Digit1: { + value: 'ㄅ', + valueIsDeadKey: false, + withShift: '!', + withShiftIsDeadKey: false, + withAltGr: '1', + withAltGrIsDeadKey: false, + withShiftAltGr: '!', + withShiftAltGrIsDeadKey: false + }, + Digit2: { + value: 'ㄉ', + valueIsDeadKey: false, + withShift: '@', + withShiftIsDeadKey: false, + withAltGr: '2', + withAltGrIsDeadKey: false, + withShiftAltGr: '@', + withShiftAltGrIsDeadKey: false + }, + Digit3: { + value: 'ˇ', + valueIsDeadKey: false, + withShift: '#', + withShiftIsDeadKey: false, + withAltGr: '3', + withAltGrIsDeadKey: false, + withShiftAltGr: '#', + withShiftAltGrIsDeadKey: false + }, + Digit4: { + value: 'ˋ', + valueIsDeadKey: false, + withShift: '$', + withShiftIsDeadKey: false, + withAltGr: '4', + withAltGrIsDeadKey: false, + withShiftAltGr: '$', + withShiftAltGrIsDeadKey: false + }, + Digit5: { + value: 'ㄓ', + valueIsDeadKey: false, + withShift: '%', + withShiftIsDeadKey: false, + withAltGr: '5', + withAltGrIsDeadKey: false, + withShiftAltGr: '%', + withShiftAltGrIsDeadKey: false + }, + Digit6: { + value: 'ˊ', + valueIsDeadKey: false, + withShift: '^', + withShiftIsDeadKey: false, + withAltGr: '6', + withAltGrIsDeadKey: false, + withShiftAltGr: '^', + withShiftAltGrIsDeadKey: false + }, + Digit7: { + value: '˙', + valueIsDeadKey: false, + withShift: '&', + withShiftIsDeadKey: false, + withAltGr: '7', + withAltGrIsDeadKey: false, + withShiftAltGr: '&', + withShiftAltGrIsDeadKey: false + }, + Digit8: { + value: 'ㄚ', + valueIsDeadKey: false, + withShift: '*', + withShiftIsDeadKey: false, + withAltGr: '8', + withAltGrIsDeadKey: false, + withShiftAltGr: '*', + withShiftAltGrIsDeadKey: false + }, + Digit9: { + value: 'ㄞ', + valueIsDeadKey: false, + withShift: '(', + withShiftIsDeadKey: false, + withAltGr: '9', + withAltGrIsDeadKey: false, + withShiftAltGr: '(', + withShiftAltGrIsDeadKey: false + }, + Digit0: { + value: 'ㄢ', + valueIsDeadKey: false, + withShift: ')', + withShiftIsDeadKey: false, + withAltGr: '0', + withAltGrIsDeadKey: false, + withShiftAltGr: ')', + withShiftAltGrIsDeadKey: false + }, + Enter: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Escape: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '‍', + withAltGrIsDeadKey: false, + withShiftAltGr: '‌', + withShiftAltGrIsDeadKey: false + }, + Backspace: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Tab: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Space: { + value: ' ', + valueIsDeadKey: false, + withShift: ' ', + withShiftIsDeadKey: false, + withAltGr: ' ', + withAltGrIsDeadKey: false, + withShiftAltGr: ' ', + withShiftAltGrIsDeadKey: false + }, + Minus: { + value: 'ㄦ', + valueIsDeadKey: false, + withShift: '_', + withShiftIsDeadKey: false, + withAltGr: '—', + withAltGrIsDeadKey: false, + withShiftAltGr: '_', + withShiftAltGrIsDeadKey: false + }, + Equal: { + value: '=', + valueIsDeadKey: false, + withShift: '+', + withShiftIsDeadKey: false, + withAltGr: '=', + withAltGrIsDeadKey: false, + withShiftAltGr: '+', + withShiftAltGrIsDeadKey: false + }, + BracketLeft: { + value: '「', + valueIsDeadKey: false, + withShift: '『', + withShiftIsDeadKey: false, + withAltGr: '[', + withAltGrIsDeadKey: false, + withShiftAltGr: '{', + withShiftAltGrIsDeadKey: false + }, + BracketRight: { + value: '」', + valueIsDeadKey: false, + withShift: '』', + withShiftIsDeadKey: false, + withAltGr: ']', + withAltGrIsDeadKey: false, + withShiftAltGr: '}', + withShiftAltGrIsDeadKey: false + }, + Backslash: { + value: '、', + valueIsDeadKey: false, + withShift: '|', + withShiftIsDeadKey: false, + withAltGr: '\\', + withAltGrIsDeadKey: false, + withShiftAltGr: '|', + withShiftAltGrIsDeadKey: false + }, + Semicolon: { + value: 'ㄤ', + valueIsDeadKey: false, + withShift: ':', + withShiftIsDeadKey: false, + withAltGr: ';', + withAltGrIsDeadKey: false, + withShiftAltGr: ':', + withShiftAltGrIsDeadKey: false + }, + Quote: { + value: '\'', + valueIsDeadKey: false, + withShift: '"', + withShiftIsDeadKey: false, + withAltGr: '\'', + withAltGrIsDeadKey: false, + withShiftAltGr: '"', + withShiftAltGrIsDeadKey: false + }, + Backquote: { + value: '·', + valueIsDeadKey: false, + withShift: '~', + withShiftIsDeadKey: false, + withAltGr: '`', + withAltGrIsDeadKey: false, + withShiftAltGr: '~', + withShiftAltGrIsDeadKey: false + }, + Comma: { + value: 'ㄝ', + valueIsDeadKey: false, + withShift: ',', + withShiftIsDeadKey: false, + withAltGr: ',', + withAltGrIsDeadKey: false, + withShiftAltGr: '<', + withShiftAltGrIsDeadKey: false + }, + Period: { + value: 'ㄡ', + valueIsDeadKey: false, + withShift: '。', + withShiftIsDeadKey: false, + withAltGr: '.', + withAltGrIsDeadKey: false, + withShiftAltGr: '>', + withShiftAltGrIsDeadKey: false + }, + Slash: { + value: 'ㄥ', + valueIsDeadKey: false, + withShift: '?', + withShiftIsDeadKey: false, + withAltGr: '/', + withAltGrIsDeadKey: false, + withShiftAltGr: '?', + withShiftAltGrIsDeadKey: false + }, + CapsLock: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F1: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F2: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F3: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F4: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F5: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F6: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F7: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F8: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F9: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F10: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F11: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F12: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Insert: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Home: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + PageUp: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Delete: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + End: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + PageDown: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowDown: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowUp: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumLock: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumpadDivide: { + value: '/', + valueIsDeadKey: false, + withShift: '/', + withShiftIsDeadKey: false, + withAltGr: '/', + withAltGrIsDeadKey: false, + withShiftAltGr: '/', + withShiftAltGrIsDeadKey: false + }, + NumpadMultiply: { + value: '*', + valueIsDeadKey: false, + withShift: '*', + withShiftIsDeadKey: false, + withAltGr: '*', + withAltGrIsDeadKey: false, + withShiftAltGr: '*', + withShiftAltGrIsDeadKey: false + }, + NumpadSubtract: { + value: '-', + valueIsDeadKey: false, + withShift: '-', + withShiftIsDeadKey: false, + withAltGr: '-', + withAltGrIsDeadKey: false, + withShiftAltGr: '-', + withShiftAltGrIsDeadKey: false + }, + NumpadAdd: { + value: '+', + valueIsDeadKey: false, + withShift: '+', + withShiftIsDeadKey: false, + withAltGr: '+', + withAltGrIsDeadKey: false, + withShiftAltGr: '+', + withShiftAltGrIsDeadKey: false + }, + NumpadEnter: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Numpad1: { + value: '1', + valueIsDeadKey: false, + withShift: '1', + withShiftIsDeadKey: false, + withAltGr: '1', + withAltGrIsDeadKey: false, + withShiftAltGr: '1', + withShiftAltGrIsDeadKey: false + }, + Numpad2: { + value: '2', + valueIsDeadKey: false, + withShift: '2', + withShiftIsDeadKey: false, + withAltGr: '2', + withAltGrIsDeadKey: false, + withShiftAltGr: '2', + withShiftAltGrIsDeadKey: false + }, + Numpad3: { + value: '3', + valueIsDeadKey: false, + withShift: '3', + withShiftIsDeadKey: false, + withAltGr: '3', + withAltGrIsDeadKey: false, + withShiftAltGr: '3', + withShiftAltGrIsDeadKey: false + }, + Numpad4: { + value: '4', + valueIsDeadKey: false, + withShift: '4', + withShiftIsDeadKey: false, + withAltGr: '4', + withAltGrIsDeadKey: false, + withShiftAltGr: '4', + withShiftAltGrIsDeadKey: false + }, + Numpad5: { + value: '5', + valueIsDeadKey: false, + withShift: '5', + withShiftIsDeadKey: false, + withAltGr: '5', + withAltGrIsDeadKey: false, + withShiftAltGr: '5', + withShiftAltGrIsDeadKey: false + }, + Numpad6: { + value: '6', + valueIsDeadKey: false, + withShift: '6', + withShiftIsDeadKey: false, + withAltGr: '6', + withAltGrIsDeadKey: false, + withShiftAltGr: '6', + withShiftAltGrIsDeadKey: false + }, + Numpad7: { + value: '7', + valueIsDeadKey: false, + withShift: '7', + withShiftIsDeadKey: false, + withAltGr: '7', + withAltGrIsDeadKey: false, + withShiftAltGr: '7', + withShiftAltGrIsDeadKey: false + }, + Numpad8: { + value: '8', + valueIsDeadKey: false, + withShift: '8', + withShiftIsDeadKey: false, + withAltGr: '8', + withAltGrIsDeadKey: false, + withShiftAltGr: '8', + withShiftAltGrIsDeadKey: false + }, + Numpad9: { + value: '9', + valueIsDeadKey: false, + withShift: '9', + withShiftIsDeadKey: false, + withAltGr: '9', + withAltGrIsDeadKey: false, + withShiftAltGr: '9', + withShiftAltGrIsDeadKey: false + }, + Numpad0: { + value: '0', + valueIsDeadKey: false, + withShift: '0', + withShiftIsDeadKey: false, + withAltGr: '0', + withAltGrIsDeadKey: false, + withShiftAltGr: '0', + withShiftAltGrIsDeadKey: false + }, + NumpadDecimal: { + value: '.', + valueIsDeadKey: false, + withShift: '.', + withShiftIsDeadKey: false, + withAltGr: '.', + withAltGrIsDeadKey: false, + withShiftAltGr: '.', + withShiftAltGrIsDeadKey: false + }, + IntlBackslash: { + value: '§', + valueIsDeadKey: false, + withShift: '±', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ContextMenu: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumpadEqual: { + value: '=', + valueIsDeadKey: false, + withShift: '=', + withShiftIsDeadKey: false, + withAltGr: '=', + withAltGrIsDeadKey: false, + withShiftAltGr: '=', + withShiftAltGrIsDeadKey: false + }, + F13: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F14: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F15: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F16: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F17: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F18: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F19: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F20: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AudioVolumeMute: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AudioVolumeUp: { + value: '', + valueIsDeadKey: false, + withShift: '=', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '=', + withShiftAltGrIsDeadKey: false + }, + AudioVolumeDown: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumpadComma: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + IntlRo: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + KanaMode: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + IntlYen: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ControlLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ShiftLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AltLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + MetaLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ControlRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ShiftRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AltRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + MetaRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + } +}); diff --git a/src/vs/workbench/services/keybinding/test/node/mac_zh_hant.txt b/src/vs/workbench/services/keybinding/test/node/mac_zh_hant.txt new file mode 100644 index 00000000000..0d7b9b6bbd6 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/mac_zh_hant.txt @@ -0,0 +1,507 @@ +isUSStandard: false +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyA | ㄇ | A | | A | a | A | [KeyA] | | +| Ctrl+KeyA | ㄇ | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | +| Shift+KeyA | A | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | +| Ctrl+Shift+KeyA | A | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | +| Alt+KeyA | ㄇ | Alt+A | | Option+A | alt+a | Alt+A | alt+[KeyA] | | +| Ctrl+Alt+KeyA | a | Ctrl+Alt+A | | Ctrl+Option+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | +| Shift+Alt+KeyA | A | Shift+Alt+A | | Shift+Option+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | +| Ctrl+Shift+Alt+KeyA | A | Ctrl+Shift+Alt+A | | Ctrl+Shift+Option+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyB | ㄖ | B | | B | b | B | [KeyB] | | +| Ctrl+KeyB | ㄖ | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | +| Shift+KeyB | B | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | +| Ctrl+Shift+KeyB | B | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | +| Alt+KeyB | ㄖ | Alt+B | | Option+B | alt+b | Alt+B | alt+[KeyB] | | +| Ctrl+Alt+KeyB | b | Ctrl+Alt+B | | Ctrl+Option+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | +| Shift+Alt+KeyB | B | Shift+Alt+B | | Shift+Option+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | +| Ctrl+Shift+Alt+KeyB | B | Ctrl+Shift+Alt+B | | Ctrl+Shift+Option+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyC | ㄏ | C | | C | c | C | [KeyC] | | +| Ctrl+KeyC | ㄏ | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | +| Shift+KeyC | C | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | +| Ctrl+Shift+KeyC | C | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | +| Alt+KeyC | ㄏ | Alt+C | | Option+C | alt+c | Alt+C | alt+[KeyC] | | +| Ctrl+Alt+KeyC | c | Ctrl+Alt+C | | Ctrl+Option+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | +| Shift+Alt+KeyC | C | Shift+Alt+C | | Shift+Option+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | +| Ctrl+Shift+Alt+KeyC | C | Ctrl+Shift+Alt+C | | Ctrl+Shift+Option+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyD | ㄎ | D | | D | d | D | [KeyD] | | +| Ctrl+KeyD | ㄎ | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | +| Shift+KeyD | D | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | +| Ctrl+Shift+KeyD | D | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | +| Alt+KeyD | ㄎ | Alt+D | | Option+D | alt+d | Alt+D | alt+[KeyD] | | +| Ctrl+Alt+KeyD | d | Ctrl+Alt+D | | Ctrl+Option+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | +| Shift+Alt+KeyD | D | Shift+Alt+D | | Shift+Option+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | +| Ctrl+Shift+Alt+KeyD | D | Ctrl+Shift+Alt+D | | Ctrl+Shift+Option+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyE | ㄍ | E | | E | e | E | [KeyE] | | +| Ctrl+KeyE | ㄍ | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | +| Shift+KeyE | E | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | +| Ctrl+Shift+KeyE | E | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | +| Alt+KeyE | ㄍ | Alt+E | | Option+E | alt+e | Alt+E | alt+[KeyE] | | +| Ctrl+Alt+KeyE | e | Ctrl+Alt+E | | Ctrl+Option+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | +| Shift+Alt+KeyE | E | Shift+Alt+E | | Shift+Option+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | +| Ctrl+Shift+Alt+KeyE | E | Ctrl+Shift+Alt+E | | Ctrl+Shift+Option+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyF | ㄑ | F | | F | f | F | [KeyF] | | +| Ctrl+KeyF | ㄑ | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | +| Shift+KeyF | F | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | +| Ctrl+Shift+KeyF | F | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | +| Alt+KeyF | ㄑ | Alt+F | | Option+F | alt+f | Alt+F | alt+[KeyF] | | +| Ctrl+Alt+KeyF | f | Ctrl+Alt+F | | Ctrl+Option+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | +| Shift+Alt+KeyF | F | Shift+Alt+F | | Shift+Option+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | +| Ctrl+Shift+Alt+KeyF | F | Ctrl+Shift+Alt+F | | Ctrl+Shift+Option+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyG | ㄕ | G | | G | g | G | [KeyG] | | +| Ctrl+KeyG | ㄕ | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | +| Shift+KeyG | G | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | +| Ctrl+Shift+KeyG | G | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | +| Alt+KeyG | ㄕ | Alt+G | | Option+G | alt+g | Alt+G | alt+[KeyG] | | +| Ctrl+Alt+KeyG | g | Ctrl+Alt+G | | Ctrl+Option+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | +| Shift+Alt+KeyG | G | Shift+Alt+G | | Shift+Option+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | +| Ctrl+Shift+Alt+KeyG | G | Ctrl+Shift+Alt+G | | Ctrl+Shift+Option+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyH | ㄘ | H | | H | h | H | [KeyH] | | +| Ctrl+KeyH | ㄘ | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | +| Shift+KeyH | H | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | +| Ctrl+Shift+KeyH | H | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | +| Alt+KeyH | ㄘ | Alt+H | | Option+H | alt+h | Alt+H | alt+[KeyH] | | +| Ctrl+Alt+KeyH | h | Ctrl+Alt+H | | Ctrl+Option+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | +| Shift+Alt+KeyH | H | Shift+Alt+H | | Shift+Option+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | +| Ctrl+Shift+Alt+KeyH | H | Ctrl+Shift+Alt+H | | Ctrl+Shift+Option+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyI | ㄛ | I | | I | i | I | [KeyI] | | +| Ctrl+KeyI | ㄛ | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | +| Shift+KeyI | I | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | +| Ctrl+Shift+KeyI | I | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | +| Alt+KeyI | ㄛ | Alt+I | | Option+I | alt+i | Alt+I | alt+[KeyI] | | +| Ctrl+Alt+KeyI | i | Ctrl+Alt+I | | Ctrl+Option+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | +| Shift+Alt+KeyI | I | Shift+Alt+I | | Shift+Option+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | +| Ctrl+Shift+Alt+KeyI | I | Ctrl+Shift+Alt+I | | Ctrl+Shift+Option+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyJ | ㄨ | J | | J | j | J | [KeyJ] | | +| Ctrl+KeyJ | ㄨ | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | +| Shift+KeyJ | J | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | +| Ctrl+Shift+KeyJ | J | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | +| Alt+KeyJ | ㄨ | Alt+J | | Option+J | alt+j | Alt+J | alt+[KeyJ] | | +| Ctrl+Alt+KeyJ | j | Ctrl+Alt+J | | Ctrl+Option+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | +| Shift+Alt+KeyJ | J | Shift+Alt+J | | Shift+Option+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | +| Ctrl+Shift+Alt+KeyJ | J | Ctrl+Shift+Alt+J | | Ctrl+Shift+Option+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyK | ㄜ | K | | K | k | K | [KeyK] | | +| Ctrl+KeyK | ㄜ | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | +| Shift+KeyK | K | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | +| Ctrl+Shift+KeyK | K | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | +| Alt+KeyK | ㄜ | Alt+K | | Option+K | alt+k | Alt+K | alt+[KeyK] | | +| Ctrl+Alt+KeyK | k | Ctrl+Alt+K | | Ctrl+Option+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | +| Shift+Alt+KeyK | K | Shift+Alt+K | | Shift+Option+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | +| Ctrl+Shift+Alt+KeyK | K | Ctrl+Shift+Alt+K | | Ctrl+Shift+Option+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyL | ㄠ | L | | L | l | L | [KeyL] | | +| Ctrl+KeyL | ㄠ | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | +| Shift+KeyL | L | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | +| Ctrl+Shift+KeyL | L | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | +| Alt+KeyL | ㄠ | Alt+L | | Option+L | alt+l | Alt+L | alt+[KeyL] | | +| Ctrl+Alt+KeyL | l | Ctrl+Alt+L | | Ctrl+Option+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | +| Shift+Alt+KeyL | L | Shift+Alt+L | | Shift+Option+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | +| Ctrl+Shift+Alt+KeyL | L | Ctrl+Shift+Alt+L | | Ctrl+Shift+Option+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyM | ㄩ | M | | M | m | M | [KeyM] | | +| Ctrl+KeyM | ㄩ | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | +| Shift+KeyM | M | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | +| Ctrl+Shift+KeyM | M | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | +| Alt+KeyM | ㄩ | Alt+M | | Option+M | alt+m | Alt+M | alt+[KeyM] | | +| Ctrl+Alt+KeyM | m | Ctrl+Alt+M | | Ctrl+Option+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | +| Shift+Alt+KeyM | M | Shift+Alt+M | | Shift+Option+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | +| Ctrl+Shift+Alt+KeyM | M | Ctrl+Shift+Alt+M | | Ctrl+Shift+Option+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyN | ㄙ | N | | N | n | N | [KeyN] | | +| Ctrl+KeyN | ㄙ | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | +| Shift+KeyN | N | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | +| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | +| Alt+KeyN | ㄙ | Alt+N | | Option+N | alt+n | Alt+N | alt+[KeyN] | | +| Ctrl+Alt+KeyN | n | Ctrl+Alt+N | | Ctrl+Option+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | +| Shift+Alt+KeyN | N | Shift+Alt+N | | Shift+Option+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | +| Ctrl+Shift+Alt+KeyN | N | Ctrl+Shift+Alt+N | | Ctrl+Shift+Option+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyO | ㄟ | O | | O | o | O | [KeyO] | | +| Ctrl+KeyO | ㄟ | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | +| Shift+KeyO | O | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | +| Ctrl+Shift+KeyO | O | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | +| Alt+KeyO | ㄟ | Alt+O | | Option+O | alt+o | Alt+O | alt+[KeyO] | | +| Ctrl+Alt+KeyO | o | Ctrl+Alt+O | | Ctrl+Option+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | +| Shift+Alt+KeyO | O | Shift+Alt+O | | Shift+Option+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | +| Ctrl+Shift+Alt+KeyO | O | Ctrl+Shift+Alt+O | | Ctrl+Shift+Option+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyP | ㄣ | P | | P | p | P | [KeyP] | | +| Ctrl+KeyP | ㄣ | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | +| Shift+KeyP | P | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | +| Ctrl+Shift+KeyP | P | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | +| Alt+KeyP | ㄣ | Alt+P | | Option+P | alt+p | Alt+P | alt+[KeyP] | | +| Ctrl+Alt+KeyP | p | Ctrl+Alt+P | | Ctrl+Option+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | +| Shift+Alt+KeyP | P | Shift+Alt+P | | Shift+Option+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | +| Ctrl+Shift+Alt+KeyP | P | Ctrl+Shift+Alt+P | | Ctrl+Shift+Option+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyQ | ㄆ | Q | | Q | q | Q | [KeyQ] | | +| Ctrl+KeyQ | ㄆ | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | +| Shift+KeyQ | Q | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | +| Ctrl+Shift+KeyQ | Q | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | +| Alt+KeyQ | ㄆ | Alt+Q | | Option+Q | alt+q | Alt+Q | alt+[KeyQ] | | +| Ctrl+Alt+KeyQ | q | Ctrl+Alt+Q | | Ctrl+Option+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | +| Shift+Alt+KeyQ | Q | Shift+Alt+Q | | Shift+Option+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | +| Ctrl+Shift+Alt+KeyQ | Q | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Option+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyR | ㄐ | R | | R | r | R | [KeyR] | | +| Ctrl+KeyR | ㄐ | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | +| Shift+KeyR | R | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | +| Ctrl+Shift+KeyR | R | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | +| Alt+KeyR | ㄐ | Alt+R | | Option+R | alt+r | Alt+R | alt+[KeyR] | | +| Ctrl+Alt+KeyR | r | Ctrl+Alt+R | | Ctrl+Option+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | +| Shift+Alt+KeyR | R | Shift+Alt+R | | Shift+Option+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | +| Ctrl+Shift+Alt+KeyR | R | Ctrl+Shift+Alt+R | | Ctrl+Shift+Option+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyS | ㄋ | S | | S | s | S | [KeyS] | | +| Ctrl+KeyS | ㄋ | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | +| Shift+KeyS | S | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | +| Ctrl+Shift+KeyS | S | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | +| Alt+KeyS | ㄋ | Alt+S | | Option+S | alt+s | Alt+S | alt+[KeyS] | | +| Ctrl+Alt+KeyS | s | Ctrl+Alt+S | | Ctrl+Option+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | +| Shift+Alt+KeyS | S | Shift+Alt+S | | Shift+Option+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | +| Ctrl+Shift+Alt+KeyS | S | Ctrl+Shift+Alt+S | | Ctrl+Shift+Option+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyT | ㄔ | T | | T | t | T | [KeyT] | | +| Ctrl+KeyT | ㄔ | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | +| Shift+KeyT | T | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | +| Ctrl+Shift+KeyT | T | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | +| Alt+KeyT | ㄔ | Alt+T | | Option+T | alt+t | Alt+T | alt+[KeyT] | | +| Ctrl+Alt+KeyT | t | Ctrl+Alt+T | | Ctrl+Option+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | +| Shift+Alt+KeyT | T | Shift+Alt+T | | Shift+Option+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | +| Ctrl+Shift+Alt+KeyT | T | Ctrl+Shift+Alt+T | | Ctrl+Shift+Option+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyU | ㄧ | U | | U | u | U | [KeyU] | | +| Ctrl+KeyU | ㄧ | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | +| Shift+KeyU | U | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | +| Ctrl+Shift+KeyU | U | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | +| Alt+KeyU | ㄧ | Alt+U | | Option+U | alt+u | Alt+U | alt+[KeyU] | | +| Ctrl+Alt+KeyU | u | Ctrl+Alt+U | | Ctrl+Option+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | +| Shift+Alt+KeyU | U | Shift+Alt+U | | Shift+Option+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | +| Ctrl+Shift+Alt+KeyU | U | Ctrl+Shift+Alt+U | | Ctrl+Shift+Option+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyV | ㄒ | V | | V | v | V | [KeyV] | | +| Ctrl+KeyV | ㄒ | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | +| Shift+KeyV | V | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | +| Ctrl+Shift+KeyV | V | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | +| Alt+KeyV | ㄒ | Alt+V | | Option+V | alt+v | Alt+V | alt+[KeyV] | | +| Ctrl+Alt+KeyV | v | Ctrl+Alt+V | | Ctrl+Option+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | +| Shift+Alt+KeyV | V | Shift+Alt+V | | Shift+Option+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | +| Ctrl+Shift+Alt+KeyV | V | Ctrl+Shift+Alt+V | | Ctrl+Shift+Option+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyW | ㄊ | W | | W | w | W | [KeyW] | | +| Ctrl+KeyW | ㄊ | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | +| Shift+KeyW | W | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | +| Ctrl+Shift+KeyW | W | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | +| Alt+KeyW | ㄊ | Alt+W | | Option+W | alt+w | Alt+W | alt+[KeyW] | | +| Ctrl+Alt+KeyW | w | Ctrl+Alt+W | | Ctrl+Option+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | +| Shift+Alt+KeyW | W | Shift+Alt+W | | Shift+Option+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | +| Ctrl+Shift+Alt+KeyW | W | Ctrl+Shift+Alt+W | | Ctrl+Shift+Option+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyX | ㄌ | X | | X | x | X | [KeyX] | | +| Ctrl+KeyX | ㄌ | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | +| Shift+KeyX | X | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | +| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | +| Alt+KeyX | ㄌ | Alt+X | | Option+X | alt+x | Alt+X | alt+[KeyX] | | +| Ctrl+Alt+KeyX | x | Ctrl+Alt+X | | Ctrl+Option+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | +| Shift+Alt+KeyX | X | Shift+Alt+X | | Shift+Option+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | +| Ctrl+Shift+Alt+KeyX | X | Ctrl+Shift+Alt+X | | Ctrl+Shift+Option+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyY | ㄗ | Y | | Y | y | Y | [KeyY] | | +| Ctrl+KeyY | ㄗ | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyY] | | +| Shift+KeyY | Y | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyY] | | +| Ctrl+Shift+KeyY | Y | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyY] | | +| Alt+KeyY | ㄗ | Alt+Y | | Option+Y | alt+y | Alt+Y | alt+[KeyY] | | +| Ctrl+Alt+KeyY | y | Ctrl+Alt+Y | | Ctrl+Option+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyY] | | +| Shift+Alt+KeyY | Y | Shift+Alt+Y | | Shift+Option+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyY] | | +| Ctrl+Shift+Alt+KeyY | Y | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Option+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyY] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyZ | ㄈ | Z | | Z | z | Z | [KeyZ] | | +| Ctrl+KeyZ | ㄈ | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyZ] | | +| Shift+KeyZ | Z | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyZ] | | +| Ctrl+Shift+KeyZ | Z | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyZ] | | +| Alt+KeyZ | ㄈ | Alt+Z | | Option+Z | alt+z | Alt+Z | alt+[KeyZ] | | +| Ctrl+Alt+KeyZ | z | Ctrl+Alt+Z | | Ctrl+Option+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyZ] | | +| Shift+Alt+KeyZ | Z | Shift+Alt+Z | | Shift+Option+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyZ] | | +| Ctrl+Shift+Alt+KeyZ | Z | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Option+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyZ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit1 | ㄅ | 1 | | ㄅ | 1 | 1 | [Digit1] | NO | +| Ctrl+Digit1 | ㄅ | Ctrl+1 | | Ctrl+ㄅ | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | NO | +| Shift+Digit1 | ! | Shift+1 | | Shift+ㄅ | shift+1 | Shift+1 | shift+[Digit1] | NO | +| Ctrl+Shift+Digit1 | ! | Ctrl+Shift+1 | | Ctrl+Shift+ㄅ | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | NO | +| Alt+Digit1 | ㄅ | Alt+1 | | Option+ㄅ | alt+1 | Alt+1 | alt+[Digit1] | NO | +| Ctrl+Alt+Digit1 | 1 | Ctrl+Alt+1 | | Ctrl+Option+ㄅ | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | NO | +| Shift+Alt+Digit1 | ! | Shift+Alt+1 | | Shift+Option+ㄅ | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | NO | +| Ctrl+Shift+Alt+Digit1 | ! | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Option+ㄅ | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit2 | ㄉ | 2 | | ㄉ | 2 | 2 | [Digit2] | NO | +| Ctrl+Digit2 | ㄉ | Ctrl+2 | | Ctrl+ㄉ | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | NO | +| Shift+Digit2 | @ | Shift+2 | | Shift+ㄉ | shift+2 | Shift+2 | shift+[Digit2] | NO | +| Ctrl+Shift+Digit2 | @ | Ctrl+Shift+2 | | Ctrl+Shift+ㄉ | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | NO | +| Alt+Digit2 | ㄉ | Alt+2 | | Option+ㄉ | alt+2 | Alt+2 | alt+[Digit2] | NO | +| Ctrl+Alt+Digit2 | 2 | Ctrl+Alt+2 | | Ctrl+Option+ㄉ | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | NO | +| Shift+Alt+Digit2 | @ | Shift+Alt+2 | | Shift+Option+ㄉ | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | NO | +| Ctrl+Shift+Alt+Digit2 | @ | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Option+ㄉ | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit3 | ˇ | 3 | | ˇ | 3 | 3 | [Digit3] | NO | +| Ctrl+Digit3 | ˇ | Ctrl+3 | | Ctrl+ˇ | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | NO | +| Shift+Digit3 | # | Shift+3 | | Shift+ˇ | shift+3 | Shift+3 | shift+[Digit3] | NO | +| Ctrl+Shift+Digit3 | # | Ctrl+Shift+3 | | Ctrl+Shift+ˇ | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | NO | +| Alt+Digit3 | ˇ | Alt+3 | | Option+ˇ | alt+3 | Alt+3 | alt+[Digit3] | NO | +| Ctrl+Alt+Digit3 | 3 | Ctrl+Alt+3 | | Ctrl+Option+ˇ | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | NO | +| Shift+Alt+Digit3 | # | Shift+Alt+3 | | Shift+Option+ˇ | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | NO | +| Ctrl+Shift+Alt+Digit3 | # | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Option+ˇ | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit4 | ˋ | 4 | | ˋ | 4 | 4 | [Digit4] | NO | +| Ctrl+Digit4 | ˋ | Ctrl+4 | | Ctrl+ˋ | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | NO | +| Shift+Digit4 | $ | Shift+4 | | Shift+ˋ | shift+4 | Shift+4 | shift+[Digit4] | NO | +| Ctrl+Shift+Digit4 | $ | Ctrl+Shift+4 | | Ctrl+Shift+ˋ | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | NO | +| Alt+Digit4 | ˋ | Alt+4 | | Option+ˋ | alt+4 | Alt+4 | alt+[Digit4] | NO | +| Ctrl+Alt+Digit4 | 4 | Ctrl+Alt+4 | | Ctrl+Option+ˋ | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | NO | +| Shift+Alt+Digit4 | $ | Shift+Alt+4 | | Shift+Option+ˋ | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | NO | +| Ctrl+Shift+Alt+Digit4 | $ | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Option+ˋ | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit5 | ㄓ | 5 | | ㄓ | 5 | 5 | [Digit5] | NO | +| Ctrl+Digit5 | ㄓ | Ctrl+5 | | Ctrl+ㄓ | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | NO | +| Shift+Digit5 | % | Shift+5 | | Shift+ㄓ | shift+5 | Shift+5 | shift+[Digit5] | NO | +| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+ㄓ | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | NO | +| Alt+Digit5 | ㄓ | Alt+5 | | Option+ㄓ | alt+5 | Alt+5 | alt+[Digit5] | NO | +| Ctrl+Alt+Digit5 | 5 | Ctrl+Alt+5 | | Ctrl+Option+ㄓ | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | NO | +| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Option+ㄓ | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | NO | +| Ctrl+Shift+Alt+Digit5 | % | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Option+ㄓ | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit6 | ˊ | 6 | | ˊ | 6 | 6 | [Digit6] | NO | +| Ctrl+Digit6 | ˊ | Ctrl+6 | | Ctrl+ˊ | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | NO | +| Shift+Digit6 | ^ | Shift+6 | | Shift+ˊ | shift+6 | Shift+6 | shift+[Digit6] | NO | +| Ctrl+Shift+Digit6 | ^ | Ctrl+Shift+6 | | Ctrl+Shift+ˊ | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | NO | +| Alt+Digit6 | ˊ | Alt+6 | | Option+ˊ | alt+6 | Alt+6 | alt+[Digit6] | NO | +| Ctrl+Alt+Digit6 | 6 | Ctrl+Alt+6 | | Ctrl+Option+ˊ | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | NO | +| Shift+Alt+Digit6 | ^ | Shift+Alt+6 | | Shift+Option+ˊ | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | NO | +| Ctrl+Shift+Alt+Digit6 | ^ | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Option+ˊ | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit7 | ˙ | 7 | | ˙ | 7 | 7 | [Digit7] | NO | +| Ctrl+Digit7 | ˙ | Ctrl+7 | | Ctrl+˙ | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | NO | +| Shift+Digit7 | & | Shift+7 | | Shift+˙ | shift+7 | Shift+7 | shift+[Digit7] | NO | +| Ctrl+Shift+Digit7 | & | Ctrl+Shift+7 | | Ctrl+Shift+˙ | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | NO | +| Alt+Digit7 | ˙ | Alt+7 | | Option+˙ | alt+7 | Alt+7 | alt+[Digit7] | NO | +| Ctrl+Alt+Digit7 | 7 | Ctrl+Alt+7 | | Ctrl+Option+˙ | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | NO | +| Shift+Alt+Digit7 | & | Shift+Alt+7 | | Shift+Option+˙ | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | NO | +| Ctrl+Shift+Alt+Digit7 | & | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Option+˙ | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit8 | ㄚ | 8 | | ㄚ | 8 | 8 | [Digit8] | NO | +| Ctrl+Digit8 | ㄚ | Ctrl+8 | | Ctrl+ㄚ | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | NO | +| Shift+Digit8 | * | Shift+8 | | Shift+ㄚ | shift+8 | Shift+8 | shift+[Digit8] | NO | +| Ctrl+Shift+Digit8 | * | Ctrl+Shift+8 | | Ctrl+Shift+ㄚ | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | NO | +| Alt+Digit8 | ㄚ | Alt+8 | | Option+ㄚ | alt+8 | Alt+8 | alt+[Digit8] | NO | +| Ctrl+Alt+Digit8 | 8 | Ctrl+Alt+8 | | Ctrl+Option+ㄚ | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | NO | +| Shift+Alt+Digit8 | * | Shift+Alt+8 | | Shift+Option+ㄚ | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | NO | +| Ctrl+Shift+Alt+Digit8 | * | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Option+ㄚ | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit9 | ㄞ | 9 | | ㄞ | 9 | 9 | [Digit9] | NO | +| Ctrl+Digit9 | ㄞ | Ctrl+9 | | Ctrl+ㄞ | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | NO | +| Shift+Digit9 | ( | Shift+9 | | Shift+ㄞ | shift+9 | Shift+9 | shift+[Digit9] | NO | +| Ctrl+Shift+Digit9 | ( | Ctrl+Shift+9 | | Ctrl+Shift+ㄞ | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | NO | +| Alt+Digit9 | ㄞ | Alt+9 | | Option+ㄞ | alt+9 | Alt+9 | alt+[Digit9] | NO | +| Ctrl+Alt+Digit9 | 9 | Ctrl+Alt+9 | | Ctrl+Option+ㄞ | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | NO | +| Shift+Alt+Digit9 | ( | Shift+Alt+9 | | Shift+Option+ㄞ | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | NO | +| Ctrl+Shift+Alt+Digit9 | ( | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Option+ㄞ | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit0 | ㄢ | 0 | | ㄢ | 0 | 0 | [Digit0] | NO | +| Ctrl+Digit0 | ㄢ | Ctrl+0 | | Ctrl+ㄢ | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | NO | +| Shift+Digit0 | ) | Shift+0 | | Shift+ㄢ | shift+0 | Shift+0 | shift+[Digit0] | NO | +| Ctrl+Shift+Digit0 | ) | Ctrl+Shift+0 | | Ctrl+Shift+ㄢ | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | NO | +| Alt+Digit0 | ㄢ | Alt+0 | | Option+ㄢ | alt+0 | Alt+0 | alt+[Digit0] | NO | +| Ctrl+Alt+Digit0 | 0 | Ctrl+Alt+0 | | Ctrl+Option+ㄢ | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | NO | +| Shift+Alt+Digit0 | ) | Shift+Alt+0 | | Shift+Option+ㄢ | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | NO | +| Ctrl+Shift+Alt+Digit0 | ) | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Option+ㄢ | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Minus | ㄦ | | | ㄦ | [Minus] | null | [Minus] | NO | +| Ctrl+Minus | ㄦ | | | Ctrl+ㄦ | ctrl+[Minus] | null | ctrl+[Minus] | NO | +| Shift+Minus | _ | Shift+- | | Shift+ㄦ | shift+[Minus] | null | shift+[Minus] | NO | +| Ctrl+Shift+Minus | _ | Ctrl+Shift+- | | Ctrl+Shift+ㄦ | ctrl+shift+[Minus] | null | ctrl+shift+[Minus] | NO | +| Alt+Minus | ㄦ | | | Option+ㄦ | alt+[Minus] | null | alt+[Minus] | NO | +| Ctrl+Alt+Minus | — | | | Ctrl+Option+ㄦ | ctrl+alt+[Minus] | null | ctrl+alt+[Minus] | NO | +| Shift+Alt+Minus | _ | Shift+Alt+- | | Shift+Option+ㄦ | shift+alt+[Minus] | null | shift+alt+[Minus] | NO | +| Ctrl+Shift+Alt+Minus | _ | Ctrl+Shift+Alt+- | | Ctrl+Shift+Option+ㄦ | ctrl+shift+alt+[Minus] | null | ctrl+shift+alt+[Minus] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Equal | = | = | | = | = | = | [Equal] | | +| Ctrl+Equal | = | Ctrl+= | | Ctrl+= | ctrl+= | Ctrl+= | ctrl+[Equal] | | +| Shift+Equal | + | Shift+= | | Shift+= | shift+= | Shift+= | shift+[Equal] | | +| Ctrl+Shift+Equal | + | Ctrl+Shift+= | | Ctrl+Shift+= | ctrl+shift+= | Ctrl+Shift+= | ctrl+shift+[Equal] | | +| Alt+Equal | = | Alt+= | | Option+= | alt+= | Alt+= | alt+[Equal] | | +| Ctrl+Alt+Equal | = | Ctrl+Alt+= | | Ctrl+Option+= | ctrl+alt+= | Ctrl+Alt+= | ctrl+alt+[Equal] | | +| Shift+Alt+Equal | + | Shift+Alt+= | | Shift+Option+= | shift+alt+= | Shift+Alt+= | shift+alt+[Equal] | | +| Ctrl+Shift+Alt+Equal | + | Ctrl+Shift+Alt+= | | Ctrl+Shift+Option+= | ctrl+shift+alt+= | Ctrl+Shift+Alt+= | ctrl+shift+alt+[Equal] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketLeft | 「 | [ | 1 | 「 | [ | [ | [BracketLeft] | NO | +| Ctrl+BracketLeft | 「 | Ctrl+[ | | Ctrl+「 | ctrl+[ | Ctrl+[ | ctrl+[BracketLeft] | NO | +| Shift+BracketLeft | 『 | Shift+[ | 1 | Shift+「 | shift+[ | Shift+[ | shift+[BracketLeft] | NO | +| Ctrl+Shift+BracketLeft | 『 | Ctrl+Shift+[ | | Ctrl+Shift+「 | ctrl+shift+[ | Ctrl+Shift+[ | ctrl+shift+[BracketLeft] | NO | +| Alt+BracketLeft | 「 | Alt+[ | | Option+「 | alt+[ | Alt+[ | alt+[BracketLeft] | NO | +| Ctrl+Alt+BracketLeft | [ | [ | 2 | Ctrl+Option+「 | ctrl+alt+[BracketLeft] | Ctrl+Alt+[ | ctrl+alt+[BracketLeft] | NO | +| Shift+Alt+BracketLeft | 『 | Shift+Alt+[ | | Shift+Option+「 | shift+alt+[ | Shift+Alt+[ | shift+alt+[BracketLeft] | NO | +| Ctrl+Shift+Alt+BracketLeft | { | Shift+[ | 2 | Ctrl+Shift+Option+「 | ctrl+shift+alt+[BracketLeft] | Ctrl+Shift+Alt+[ | ctrl+shift+alt+[BracketLeft] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketRight | 」 | ] | 1 | 」 | ] | ] | [BracketRight] | NO | +| Ctrl+BracketRight | 」 | Ctrl+] | | Ctrl+」 | ctrl+] | Ctrl+] | ctrl+[BracketRight] | NO | +| Shift+BracketRight | 』 | Shift+] | 1 | Shift+」 | shift+] | Shift+] | shift+[BracketRight] | NO | +| Ctrl+Shift+BracketRight | 』 | Ctrl+Shift+] | | Ctrl+Shift+」 | ctrl+shift+] | Ctrl+Shift+] | ctrl+shift+[BracketRight] | NO | +| Alt+BracketRight | 」 | Alt+] | | Option+」 | alt+] | Alt+] | alt+[BracketRight] | NO | +| Ctrl+Alt+BracketRight | ] | ] | 2 | Ctrl+Option+」 | ctrl+alt+[BracketRight] | Ctrl+Alt+] | ctrl+alt+[BracketRight] | NO | +| Shift+Alt+BracketRight | 』 | Shift+Alt+] | | Shift+Option+」 | shift+alt+] | Shift+Alt+] | shift+alt+[BracketRight] | NO | +| Ctrl+Shift+Alt+BracketRight | } | Shift+] | 2 | Ctrl+Shift+Option+」 | ctrl+shift+alt+[BracketRight] | Ctrl+Shift+Alt+] | ctrl+shift+alt+[BracketRight] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backslash | 、 | | | 、 | [Backslash] | null | [Backslash] | NO | +| Ctrl+Backslash | 、 | | | Ctrl+、 | ctrl+[Backslash] | null | ctrl+[Backslash] | NO | +| Shift+Backslash | | | Shift+\ | | Shift+、 | shift+[Backslash] | null | shift+[Backslash] | NO | +| Ctrl+Shift+Backslash | | | Ctrl+Shift+\ | | Ctrl+Shift+、 | ctrl+shift+[Backslash] | null | ctrl+shift+[Backslash] | NO | +| Alt+Backslash | 、 | | | Option+、 | alt+[Backslash] | null | alt+[Backslash] | NO | +| Ctrl+Alt+Backslash | \ | \ | | Ctrl+Option+、 | ctrl+alt+[Backslash] | null | ctrl+alt+[Backslash] | NO | +| Shift+Alt+Backslash | | | Shift+Alt+\ | | Shift+Option+、 | shift+alt+[Backslash] | null | shift+alt+[Backslash] | NO | +| Ctrl+Shift+Alt+Backslash | | | Ctrl+Shift+Alt+\ | | Ctrl+Shift+Option+、 | ctrl+shift+alt+[Backslash] | null | ctrl+shift+alt+[Backslash] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlHash | --- | | | null | null | null | null | | +| Ctrl+IntlHash | --- | | | null | null | null | null | | +| Shift+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | +| Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | +| Shift+Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Semicolon | ㄤ | | | ㄤ | [Semicolon] | null | [Semicolon] | NO | +| Ctrl+Semicolon | ㄤ | | | Ctrl+ㄤ | ctrl+[Semicolon] | null | ctrl+[Semicolon] | NO | +| Shift+Semicolon | : | Shift+; | | Shift+ㄤ | shift+[Semicolon] | null | shift+[Semicolon] | NO | +| Ctrl+Shift+Semicolon | : | Ctrl+Shift+; | | Ctrl+Shift+ㄤ | ctrl+shift+[Semicolon] | null | ctrl+shift+[Semicolon] | NO | +| Alt+Semicolon | ㄤ | | | Option+ㄤ | alt+[Semicolon] | null | alt+[Semicolon] | NO | +| Ctrl+Alt+Semicolon | ; | ; | | Ctrl+Option+ㄤ | ctrl+alt+[Semicolon] | null | ctrl+alt+[Semicolon] | NO | +| Shift+Alt+Semicolon | : | Shift+Alt+; | | Shift+Option+ㄤ | shift+alt+[Semicolon] | null | shift+alt+[Semicolon] | NO | +| Ctrl+Shift+Alt+Semicolon | : | Ctrl+Shift+Alt+; | | Ctrl+Shift+Option+ㄤ | ctrl+shift+alt+[Semicolon] | null | ctrl+shift+alt+[Semicolon] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Quote | ' | ' | | ' | ' | ' | [Quote] | | +| Ctrl+Quote | ' | Ctrl+' | | Ctrl+' | ctrl+' | Ctrl+' | ctrl+[Quote] | | +| Shift+Quote | " | Shift+' | | Shift+' | shift+' | Shift+' | shift+[Quote] | | +| Ctrl+Shift+Quote | " | Ctrl+Shift+' | | Ctrl+Shift+' | ctrl+shift+' | Ctrl+Shift+' | ctrl+shift+[Quote] | | +| Alt+Quote | ' | Alt+' | | Option+' | alt+' | Alt+' | alt+[Quote] | | +| Ctrl+Alt+Quote | ' | Ctrl+Alt+' | | Ctrl+Option+' | ctrl+alt+' | Ctrl+Alt+' | ctrl+alt+[Quote] | | +| Shift+Alt+Quote | " | Shift+Alt+' | | Shift+Option+' | shift+alt+' | Shift+Alt+' | shift+alt+[Quote] | | +| Ctrl+Shift+Alt+Quote | " | Ctrl+Shift+Alt+' | | Ctrl+Shift+Option+' | ctrl+shift+alt+' | Ctrl+Shift+Alt+' | ctrl+shift+alt+[Quote] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backquote | · | | | · | [Backquote] | null | [Backquote] | NO | +| Ctrl+Backquote | · | | | Ctrl+· | ctrl+[Backquote] | null | ctrl+[Backquote] | NO | +| Shift+Backquote | ~ | Shift+` | | Shift+· | shift+[Backquote] | null | shift+[Backquote] | NO | +| Ctrl+Shift+Backquote | ~ | Ctrl+Shift+` | | Ctrl+Shift+· | ctrl+shift+[Backquote] | null | ctrl+shift+[Backquote] | NO | +| Alt+Backquote | · | | | Option+· | alt+[Backquote] | null | alt+[Backquote] | NO | +| Ctrl+Alt+Backquote | ` | ` | | Ctrl+Option+· | ctrl+alt+[Backquote] | null | ctrl+alt+[Backquote] | NO | +| Shift+Alt+Backquote | ~ | Shift+Alt+` | | Shift+Option+· | shift+alt+[Backquote] | null | shift+alt+[Backquote] | NO | +| Ctrl+Shift+Alt+Backquote | ~ | Ctrl+Shift+Alt+` | | Ctrl+Shift+Option+· | ctrl+shift+alt+[Backquote] | null | ctrl+shift+alt+[Backquote] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Comma | ㄝ | | | ㄝ | [Comma] | null | [Comma] | NO | +| Ctrl+Comma | ㄝ | | | Ctrl+ㄝ | ctrl+[Comma] | null | ctrl+[Comma] | NO | +| Shift+Comma | , | , | 1 | Shift+ㄝ | shift+[Comma] | null | shift+[Comma] | NO | +| Ctrl+Shift+Comma | , | Ctrl+, | | Ctrl+Shift+ㄝ | ctrl+shift+[Comma] | null | ctrl+shift+[Comma] | NO | +| Alt+Comma | ㄝ | | | Option+ㄝ | alt+[Comma] | null | alt+[Comma] | NO | +| Ctrl+Alt+Comma | , | , | 2 | Ctrl+Option+ㄝ | ctrl+alt+[Comma] | null | ctrl+alt+[Comma] | NO | +| Shift+Alt+Comma | , | Alt+, | | Shift+Option+ㄝ | shift+alt+[Comma] | null | shift+alt+[Comma] | NO | +| Ctrl+Shift+Alt+Comma | < | Shift+, | | Ctrl+Shift+Option+ㄝ | ctrl+shift+alt+[Comma] | null | ctrl+shift+alt+[Comma] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Period | ㄡ | | | ㄡ | [Period] | null | [Period] | NO | +| Ctrl+Period | ㄡ | | | Ctrl+ㄡ | ctrl+[Period] | null | ctrl+[Period] | NO | +| Shift+Period | 。 | . | 1 | Shift+ㄡ | shift+[Period] | null | shift+[Period] | NO | +| Ctrl+Shift+Period | 。 | Ctrl+. | | Ctrl+Shift+ㄡ | ctrl+shift+[Period] | null | ctrl+shift+[Period] | NO | +| Alt+Period | ㄡ | | | Option+ㄡ | alt+[Period] | null | alt+[Period] | NO | +| Ctrl+Alt+Period | . | . | 2 | Ctrl+Option+ㄡ | ctrl+alt+[Period] | null | ctrl+alt+[Period] | NO | +| Shift+Alt+Period | 。 | Alt+. | | Shift+Option+ㄡ | shift+alt+[Period] | null | shift+alt+[Period] | NO | +| Ctrl+Shift+Alt+Period | > | Shift+. | | Ctrl+Shift+Option+ㄡ | ctrl+shift+alt+[Period] | null | ctrl+shift+alt+[Period] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Slash | ㄥ | | | ㄥ | [Slash] | null | [Slash] | NO | +| Ctrl+Slash | ㄥ | | | Ctrl+ㄥ | ctrl+[Slash] | null | ctrl+[Slash] | NO | +| Shift+Slash | ? | Shift+/ | | Shift+ㄥ | shift+[Slash] | null | shift+[Slash] | NO | +| Ctrl+Shift+Slash | ? | Ctrl+Shift+/ | | Ctrl+Shift+ㄥ | ctrl+shift+[Slash] | null | ctrl+shift+[Slash] | NO | +| Alt+Slash | ㄥ | | | Option+ㄥ | alt+[Slash] | null | alt+[Slash] | NO | +| Ctrl+Alt+Slash | / | / | | Ctrl+Option+ㄥ | ctrl+alt+[Slash] | null | ctrl+alt+[Slash] | NO | +| Shift+Alt+Slash | ? | Shift+Alt+/ | | Shift+Option+ㄥ | shift+alt+[Slash] | null | shift+alt+[Slash] | NO | +| Ctrl+Shift+Alt+Slash | ? | Ctrl+Shift+Alt+/ | | Ctrl+Shift+Option+ㄥ | ctrl+shift+alt+[Slash] | null | ctrl+shift+alt+[Slash] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | +| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | +| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | +| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | +| Alt+ArrowUp | --- | Alt+UpArrow | | Option+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | +| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Option+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | +| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Option+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | +| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Option+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | +| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | +| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | +| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | +| Alt+Numpad0 | --- | Alt+NumPad0 | | Option+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | +| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Option+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | +| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Option+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | +| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Option+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlBackslash | § | | | § | [IntlBackslash] | null | [IntlBackslash] | NO | +| Ctrl+IntlBackslash | § | | | Ctrl+§ | ctrl+[IntlBackslash] | null | ctrl+[IntlBackslash] | NO | +| Shift+IntlBackslash | ± | | | Shift+§ | shift+[IntlBackslash] | null | shift+[IntlBackslash] | NO | +| Ctrl+Shift+IntlBackslash | ± | | | Ctrl+Shift+§ | ctrl+shift+[IntlBackslash] | null | ctrl+shift+[IntlBackslash] | NO | +| Alt+IntlBackslash | § | | | Option+§ | alt+[IntlBackslash] | null | alt+[IntlBackslash] | NO | +| Ctrl+Alt+IntlBackslash | --- | | | Ctrl+Option+§ | ctrl+alt+[IntlBackslash] | null | ctrl+alt+[IntlBackslash] | NO | +| Shift+Alt+IntlBackslash | ± | | | Shift+Option+§ | shift+alt+[IntlBackslash] | null | shift+alt+[IntlBackslash] | NO | +| Ctrl+Shift+Alt+IntlBackslash | --- | | | Ctrl+Shift+Option+§ | ctrl+shift+alt+[IntlBackslash] | null | ctrl+shift+alt+[IntlBackslash] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | +| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | +| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | +| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | +| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | +| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | +| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | +| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | +| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | +| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | +| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | +| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | +| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | +| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | +| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/node/mac_zh_hant2.js b/src/vs/workbench/services/keybinding/test/node/mac_zh_hant2.js new file mode 100644 index 00000000000..5ad77d35f34 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/mac_zh_hant2.js @@ -0,0 +1,1188 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +define({ + KeyA: { + value: 'a', + valueIsDeadKey: false, + withShift: 'A', + withShiftIsDeadKey: false, + withAltGr: 'å', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Å', + withShiftAltGrIsDeadKey: false + }, + KeyB: { + value: 'b', + valueIsDeadKey: false, + withShift: 'B', + withShiftIsDeadKey: false, + withAltGr: '∫', + withAltGrIsDeadKey: false, + withShiftAltGr: '符', + withShiftAltGrIsDeadKey: false + }, + KeyC: { + value: 'c', + valueIsDeadKey: false, + withShift: 'C', + withShiftIsDeadKey: false, + withAltGr: 'ç', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ç', + withShiftAltGrIsDeadKey: false + }, + KeyD: { + value: 'd', + valueIsDeadKey: false, + withShift: 'D', + withShiftIsDeadKey: false, + withAltGr: '∂', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Î', + withShiftAltGrIsDeadKey: false + }, + KeyE: { + value: 'e', + valueIsDeadKey: false, + withShift: 'E', + withShiftIsDeadKey: false, + withAltGr: '´', + withAltGrIsDeadKey: true, + withShiftAltGr: '助', + withShiftAltGrIsDeadKey: false + }, + KeyF: { + value: 'f', + valueIsDeadKey: false, + withShift: 'F', + withShiftIsDeadKey: false, + withAltGr: 'ƒ', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ï', + withShiftAltGrIsDeadKey: false + }, + KeyG: { + value: 'g', + valueIsDeadKey: false, + withShift: 'G', + withShiftIsDeadKey: false, + withAltGr: '©', + withAltGrIsDeadKey: false, + withShiftAltGr: '˝', + withShiftAltGrIsDeadKey: false + }, + KeyH: { + value: 'h', + valueIsDeadKey: false, + withShift: 'H', + withShiftIsDeadKey: false, + withAltGr: '˙', + withAltGrIsDeadKey: false, + withShiftAltGr: '半', + withShiftAltGrIsDeadKey: false + }, + KeyI: { + value: 'i', + valueIsDeadKey: false, + withShift: 'I', + withShiftIsDeadKey: false, + withAltGr: 'ˆ', + withAltGrIsDeadKey: true, + withShiftAltGr: 'ˆ', + withShiftAltGrIsDeadKey: false + }, + KeyJ: { + value: 'j', + valueIsDeadKey: false, + withShift: 'J', + withShiftIsDeadKey: false, + withAltGr: '∆', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ô', + withShiftAltGrIsDeadKey: false + }, + KeyK: { + value: 'k', + valueIsDeadKey: false, + withShift: 'K', + withShiftIsDeadKey: false, + withAltGr: '˚', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + KeyL: { + value: 'l', + valueIsDeadKey: false, + withShift: 'L', + withShiftIsDeadKey: false, + withAltGr: '¬', + withAltGrIsDeadKey: false, + withShiftAltGr: '查', + withShiftAltGrIsDeadKey: false + }, + KeyM: { + value: 'm', + valueIsDeadKey: false, + withShift: 'M', + withShiftIsDeadKey: false, + withAltGr: 'µ', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Â', + withShiftAltGrIsDeadKey: false + }, + KeyN: { + value: 'n', + valueIsDeadKey: false, + withShift: 'N', + withShiftIsDeadKey: false, + withAltGr: '˜', + withAltGrIsDeadKey: true, + withShiftAltGr: '˜', + withShiftAltGrIsDeadKey: false + }, + KeyO: { + value: 'o', + valueIsDeadKey: false, + withShift: 'O', + withShiftIsDeadKey: false, + withAltGr: 'ø', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ø', + withShiftAltGrIsDeadKey: false + }, + KeyP: { + value: 'p', + valueIsDeadKey: false, + withShift: 'P', + withShiftIsDeadKey: false, + withAltGr: 'π', + withAltGrIsDeadKey: false, + withShiftAltGr: '∏', + withShiftAltGrIsDeadKey: false + }, + KeyQ: { + value: 'q', + valueIsDeadKey: false, + withShift: 'Q', + withShiftIsDeadKey: false, + withAltGr: 'œ', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Œ', + withShiftAltGrIsDeadKey: false + }, + KeyR: { + value: 'r', + valueIsDeadKey: false, + withShift: 'R', + withShiftIsDeadKey: false, + withAltGr: '®', + withAltGrIsDeadKey: false, + withShiftAltGr: '‰', + withShiftAltGrIsDeadKey: false + }, + KeyS: { + value: 's', + valueIsDeadKey: false, + withShift: 'S', + withShiftIsDeadKey: false, + withAltGr: 'ß', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Í', + withShiftAltGrIsDeadKey: false + }, + KeyT: { + value: 't', + valueIsDeadKey: false, + withShift: 'T', + withShiftIsDeadKey: false, + withAltGr: '†', + withAltGrIsDeadKey: false, + withShiftAltGr: 'ˇ', + withShiftAltGrIsDeadKey: false + }, + KeyU: { + value: 'u', + valueIsDeadKey: false, + withShift: 'U', + withShiftIsDeadKey: false, + withAltGr: '¨', + withAltGrIsDeadKey: true, + withShiftAltGr: '¨', + withShiftAltGrIsDeadKey: false + }, + KeyV: { + value: 'v', + valueIsDeadKey: false, + withShift: 'V', + withShiftIsDeadKey: false, + withAltGr: '√', + withAltGrIsDeadKey: false, + withShiftAltGr: '◊', + withShiftAltGrIsDeadKey: false + }, + KeyW: { + value: 'w', + valueIsDeadKey: false, + withShift: 'W', + withShiftIsDeadKey: false, + withAltGr: '∑', + withAltGrIsDeadKey: false, + withShiftAltGr: '„', + withShiftAltGrIsDeadKey: false + }, + KeyX: { + value: 'x', + valueIsDeadKey: false, + withShift: 'X', + withShiftIsDeadKey: false, + withAltGr: '≈', + withAltGrIsDeadKey: false, + withShiftAltGr: '˛', + withShiftAltGrIsDeadKey: false + }, + KeyY: { + value: 'y', + valueIsDeadKey: false, + withShift: 'Y', + withShiftIsDeadKey: false, + withAltGr: '¥', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Á', + withShiftAltGrIsDeadKey: false + }, + KeyZ: { + value: 'z', + valueIsDeadKey: false, + withShift: 'Z', + withShiftIsDeadKey: false, + withAltGr: 'Ω', + withAltGrIsDeadKey: false, + withShiftAltGr: '¸', + withShiftAltGrIsDeadKey: false + }, + Digit1: { + value: '1', + valueIsDeadKey: false, + withShift: '!', + withShiftIsDeadKey: false, + withAltGr: '1', + withAltGrIsDeadKey: false, + withShiftAltGr: '⁄', + withShiftAltGrIsDeadKey: false + }, + Digit2: { + value: '2', + valueIsDeadKey: false, + withShift: '@', + withShiftIsDeadKey: false, + withAltGr: '2', + withAltGrIsDeadKey: false, + withShiftAltGr: '€', + withShiftAltGrIsDeadKey: false + }, + Digit3: { + value: '3', + valueIsDeadKey: false, + withShift: '#', + withShiftIsDeadKey: false, + withAltGr: '3', + withAltGrIsDeadKey: false, + withShiftAltGr: '‹', + withShiftAltGrIsDeadKey: false + }, + Digit4: { + value: '4', + valueIsDeadKey: false, + withShift: '$', + withShiftIsDeadKey: false, + withAltGr: '4', + withAltGrIsDeadKey: false, + withShiftAltGr: '›', + withShiftAltGrIsDeadKey: false + }, + Digit5: { + value: '5', + valueIsDeadKey: false, + withShift: '%', + withShiftIsDeadKey: false, + withAltGr: '5', + withAltGrIsDeadKey: false, + withShiftAltGr: 'fi', + withShiftAltGrIsDeadKey: false + }, + Digit6: { + value: '6', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '6', + withAltGrIsDeadKey: false, + withShiftAltGr: 'fl', + withShiftAltGrIsDeadKey: false + }, + Digit7: { + value: '7', + valueIsDeadKey: false, + withShift: '&', + withShiftIsDeadKey: false, + withAltGr: '7', + withAltGrIsDeadKey: false, + withShiftAltGr: '‡', + withShiftAltGrIsDeadKey: false + }, + Digit8: { + value: '8', + valueIsDeadKey: false, + withShift: '*', + withShiftIsDeadKey: false, + withAltGr: '8', + withAltGrIsDeadKey: false, + withShiftAltGr: '°', + withShiftAltGrIsDeadKey: false + }, + Digit9: { + value: '9', + valueIsDeadKey: false, + withShift: '(', + withShiftIsDeadKey: false, + withAltGr: '9', + withAltGrIsDeadKey: false, + withShiftAltGr: '·', + withShiftAltGrIsDeadKey: false + }, + Digit0: { + value: '0', + valueIsDeadKey: false, + withShift: ')', + withShiftIsDeadKey: false, + withAltGr: '0', + withAltGrIsDeadKey: false, + withShiftAltGr: '‚', + withShiftAltGrIsDeadKey: false + }, + Enter: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Escape: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Backspace: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Tab: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Space: { + value: ' ', + valueIsDeadKey: false, + withShift: ' ', + withShiftIsDeadKey: false, + withAltGr: ' ', + withAltGrIsDeadKey: false, + withShiftAltGr: ' ', + withShiftAltGrIsDeadKey: false + }, + Minus: { + value: '-', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '–', + withAltGrIsDeadKey: false, + withShiftAltGr: '—', + withShiftAltGrIsDeadKey: false + }, + Equal: { + value: '=', + valueIsDeadKey: false, + withShift: '+', + withShiftIsDeadKey: false, + withAltGr: '≠', + withAltGrIsDeadKey: false, + withShiftAltGr: '±', + withShiftAltGrIsDeadKey: false + }, + BracketLeft: { + value: '【', + valueIsDeadKey: false, + withShift: '「', + withShiftIsDeadKey: false, + withAltGr: '“', + withAltGrIsDeadKey: false, + withShiftAltGr: '”', + withShiftAltGrIsDeadKey: false + }, + BracketRight: { + value: '】', + valueIsDeadKey: false, + withShift: '」', + withShiftIsDeadKey: false, + withAltGr: '‘', + withAltGrIsDeadKey: false, + withShiftAltGr: '’', + withShiftAltGrIsDeadKey: false + }, + Backslash: { + value: '、', + valueIsDeadKey: false, + withShift: '|', + withShiftIsDeadKey: false, + withAltGr: '«', + withAltGrIsDeadKey: false, + withShiftAltGr: '»', + withShiftAltGrIsDeadKey: false + }, + Semicolon: { + value: ';', + valueIsDeadKey: false, + withShift: ':', + withShiftIsDeadKey: false, + withAltGr: '…', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ú', + withShiftAltGrIsDeadKey: false + }, + Quote: { + value: '\'', + valueIsDeadKey: false, + withShift: '"', + withShiftIsDeadKey: false, + withAltGr: 'æ', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Æ', + withShiftAltGrIsDeadKey: false + }, + Backquote: { + value: '·', + valueIsDeadKey: false, + withShift: '~', + withShiftIsDeadKey: false, + withAltGr: '·', + withAltGrIsDeadKey: false, + withShiftAltGr: '·', + withShiftAltGrIsDeadKey: false + }, + Comma: { + value: ',', + valueIsDeadKey: false, + withShift: '《', + withShiftIsDeadKey: false, + withAltGr: '≤', + withAltGrIsDeadKey: false, + withShiftAltGr: '¯', + withShiftAltGrIsDeadKey: false + }, + Period: { + value: '。', + valueIsDeadKey: false, + withShift: '》', + withShiftIsDeadKey: false, + withAltGr: '≥', + withAltGrIsDeadKey: false, + withShiftAltGr: '˘', + withShiftAltGrIsDeadKey: false + }, + Slash: { + value: '/', + valueIsDeadKey: false, + withShift: '?', + withShiftIsDeadKey: false, + withAltGr: '÷', + withAltGrIsDeadKey: false, + withShiftAltGr: '¿', + withShiftAltGrIsDeadKey: false + }, + CapsLock: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F1: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F2: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F3: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F4: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F5: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F6: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F7: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F8: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F9: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F10: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F11: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F12: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Insert: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Home: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + PageUp: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Delete: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + End: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + PageDown: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowDown: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ArrowUp: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumLock: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumpadDivide: { + value: '/', + valueIsDeadKey: false, + withShift: '/', + withShiftIsDeadKey: false, + withAltGr: '/', + withAltGrIsDeadKey: false, + withShiftAltGr: '/', + withShiftAltGrIsDeadKey: false + }, + NumpadMultiply: { + value: '*', + valueIsDeadKey: false, + withShift: '*', + withShiftIsDeadKey: false, + withAltGr: '*', + withAltGrIsDeadKey: false, + withShiftAltGr: '*', + withShiftAltGrIsDeadKey: false + }, + NumpadSubtract: { + value: '-', + valueIsDeadKey: false, + withShift: '-', + withShiftIsDeadKey: false, + withAltGr: '-', + withAltGrIsDeadKey: false, + withShiftAltGr: '-', + withShiftAltGrIsDeadKey: false + }, + NumpadAdd: { + value: '+', + valueIsDeadKey: false, + withShift: '+', + withShiftIsDeadKey: false, + withAltGr: '+', + withAltGrIsDeadKey: false, + withShiftAltGr: '+', + withShiftAltGrIsDeadKey: false + }, + NumpadEnter: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + Numpad1: { + value: '1', + valueIsDeadKey: false, + withShift: '1', + withShiftIsDeadKey: false, + withAltGr: '1', + withAltGrIsDeadKey: false, + withShiftAltGr: '1', + withShiftAltGrIsDeadKey: false + }, + Numpad2: { + value: '2', + valueIsDeadKey: false, + withShift: '2', + withShiftIsDeadKey: false, + withAltGr: '2', + withAltGrIsDeadKey: false, + withShiftAltGr: '2', + withShiftAltGrIsDeadKey: false + }, + Numpad3: { + value: '3', + valueIsDeadKey: false, + withShift: '3', + withShiftIsDeadKey: false, + withAltGr: '3', + withAltGrIsDeadKey: false, + withShiftAltGr: '3', + withShiftAltGrIsDeadKey: false + }, + Numpad4: { + value: '4', + valueIsDeadKey: false, + withShift: '4', + withShiftIsDeadKey: false, + withAltGr: '4', + withAltGrIsDeadKey: false, + withShiftAltGr: '4', + withShiftAltGrIsDeadKey: false + }, + Numpad5: { + value: '5', + valueIsDeadKey: false, + withShift: '5', + withShiftIsDeadKey: false, + withAltGr: '5', + withAltGrIsDeadKey: false, + withShiftAltGr: '5', + withShiftAltGrIsDeadKey: false + }, + Numpad6: { + value: '6', + valueIsDeadKey: false, + withShift: '6', + withShiftIsDeadKey: false, + withAltGr: '6', + withAltGrIsDeadKey: false, + withShiftAltGr: '6', + withShiftAltGrIsDeadKey: false + }, + Numpad7: { + value: '7', + valueIsDeadKey: false, + withShift: '7', + withShiftIsDeadKey: false, + withAltGr: '7', + withAltGrIsDeadKey: false, + withShiftAltGr: '7', + withShiftAltGrIsDeadKey: false + }, + Numpad8: { + value: '8', + valueIsDeadKey: false, + withShift: '8', + withShiftIsDeadKey: false, + withAltGr: '8', + withAltGrIsDeadKey: false, + withShiftAltGr: '8', + withShiftAltGrIsDeadKey: false + }, + Numpad9: { + value: '9', + valueIsDeadKey: false, + withShift: '9', + withShiftIsDeadKey: false, + withAltGr: '9', + withAltGrIsDeadKey: false, + withShiftAltGr: '9', + withShiftAltGrIsDeadKey: false + }, + Numpad0: { + value: '0', + valueIsDeadKey: false, + withShift: '0', + withShiftIsDeadKey: false, + withAltGr: '0', + withAltGrIsDeadKey: false, + withShiftAltGr: '0', + withShiftAltGrIsDeadKey: false + }, + NumpadDecimal: { + value: '.', + valueIsDeadKey: false, + withShift: '.', + withShiftIsDeadKey: false, + withAltGr: '.', + withAltGrIsDeadKey: false, + withShiftAltGr: '.', + withShiftAltGrIsDeadKey: false + }, + IntlBackslash: { + value: '§', + valueIsDeadKey: false, + withShift: '±', + withShiftIsDeadKey: false, + withAltGr: '§', + withAltGrIsDeadKey: false, + withShiftAltGr: '±', + withShiftAltGrIsDeadKey: false + }, + ContextMenu: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumpadEqual: { + value: '=', + valueIsDeadKey: false, + withShift: '=', + withShiftIsDeadKey: false, + withAltGr: '=', + withAltGrIsDeadKey: false, + withShiftAltGr: '=', + withShiftAltGrIsDeadKey: false + }, + F13: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F14: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F15: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F16: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F17: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F18: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F19: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + F20: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AudioVolumeMute: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AudioVolumeUp: { + value: '', + valueIsDeadKey: false, + withShift: '=', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '=', + withShiftAltGrIsDeadKey: false + }, + AudioVolumeDown: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + NumpadComma: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + IntlRo: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + KanaMode: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + IntlYen: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ControlLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ShiftLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AltLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + MetaLeft: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ControlRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + ShiftRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + AltRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + }, + MetaRight: { + value: '', + valueIsDeadKey: false, + withShift: '', + withShiftIsDeadKey: false, + withAltGr: '', + withAltGrIsDeadKey: false, + withShiftAltGr: '', + withShiftAltGrIsDeadKey: false + } +}); diff --git a/src/vs/workbench/services/keybinding/test/node/mac_zh_hant2.txt b/src/vs/workbench/services/keybinding/test/node/mac_zh_hant2.txt new file mode 100644 index 00000000000..17b24363b35 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/mac_zh_hant2.txt @@ -0,0 +1,507 @@ +isUSStandard: false +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyA | a | A | | A | a | A | [KeyA] | | +| Ctrl+KeyA | a | Ctrl+A | | Ctrl+A | ctrl+a | Ctrl+A | ctrl+[KeyA] | | +| Shift+KeyA | A | Shift+A | | Shift+A | shift+a | Shift+A | shift+[KeyA] | | +| Ctrl+Shift+KeyA | A | Ctrl+Shift+A | | Ctrl+Shift+A | ctrl+shift+a | Ctrl+Shift+A | ctrl+shift+[KeyA] | | +| Alt+KeyA | a | Alt+A | | Option+A | alt+a | Alt+A | alt+[KeyA] | | +| Ctrl+Alt+KeyA | å | Ctrl+Alt+A | | Ctrl+Option+A | ctrl+alt+a | Ctrl+Alt+A | ctrl+alt+[KeyA] | | +| Shift+Alt+KeyA | A | Shift+Alt+A | | Shift+Option+A | shift+alt+a | Shift+Alt+A | shift+alt+[KeyA] | | +| Ctrl+Shift+Alt+KeyA | Å | Ctrl+Shift+Alt+A | | Ctrl+Shift+Option+A | ctrl+shift+alt+a | Ctrl+Shift+Alt+A | ctrl+shift+alt+[KeyA] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyB | b | B | | B | b | B | [KeyB] | | +| Ctrl+KeyB | b | Ctrl+B | | Ctrl+B | ctrl+b | Ctrl+B | ctrl+[KeyB] | | +| Shift+KeyB | B | Shift+B | | Shift+B | shift+b | Shift+B | shift+[KeyB] | | +| Ctrl+Shift+KeyB | B | Ctrl+Shift+B | | Ctrl+Shift+B | ctrl+shift+b | Ctrl+Shift+B | ctrl+shift+[KeyB] | | +| Alt+KeyB | b | Alt+B | | Option+B | alt+b | Alt+B | alt+[KeyB] | | +| Ctrl+Alt+KeyB | ∫ | Ctrl+Alt+B | | Ctrl+Option+B | ctrl+alt+b | Ctrl+Alt+B | ctrl+alt+[KeyB] | | +| Shift+Alt+KeyB | B | Shift+Alt+B | | Shift+Option+B | shift+alt+b | Shift+Alt+B | shift+alt+[KeyB] | | +| Ctrl+Shift+Alt+KeyB | 符 | Ctrl+Shift+Alt+B | | Ctrl+Shift+Option+B | ctrl+shift+alt+b | Ctrl+Shift+Alt+B | ctrl+shift+alt+[KeyB] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyC | c | C | | C | c | C | [KeyC] | | +| Ctrl+KeyC | c | Ctrl+C | | Ctrl+C | ctrl+c | Ctrl+C | ctrl+[KeyC] | | +| Shift+KeyC | C | Shift+C | | Shift+C | shift+c | Shift+C | shift+[KeyC] | | +| Ctrl+Shift+KeyC | C | Ctrl+Shift+C | | Ctrl+Shift+C | ctrl+shift+c | Ctrl+Shift+C | ctrl+shift+[KeyC] | | +| Alt+KeyC | c | Alt+C | | Option+C | alt+c | Alt+C | alt+[KeyC] | | +| Ctrl+Alt+KeyC | ç | Ctrl+Alt+C | | Ctrl+Option+C | ctrl+alt+c | Ctrl+Alt+C | ctrl+alt+[KeyC] | | +| Shift+Alt+KeyC | C | Shift+Alt+C | | Shift+Option+C | shift+alt+c | Shift+Alt+C | shift+alt+[KeyC] | | +| Ctrl+Shift+Alt+KeyC | Ç | Ctrl+Shift+Alt+C | | Ctrl+Shift+Option+C | ctrl+shift+alt+c | Ctrl+Shift+Alt+C | ctrl+shift+alt+[KeyC] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyD | d | D | | D | d | D | [KeyD] | | +| Ctrl+KeyD | d | Ctrl+D | | Ctrl+D | ctrl+d | Ctrl+D | ctrl+[KeyD] | | +| Shift+KeyD | D | Shift+D | | Shift+D | shift+d | Shift+D | shift+[KeyD] | | +| Ctrl+Shift+KeyD | D | Ctrl+Shift+D | | Ctrl+Shift+D | ctrl+shift+d | Ctrl+Shift+D | ctrl+shift+[KeyD] | | +| Alt+KeyD | d | Alt+D | | Option+D | alt+d | Alt+D | alt+[KeyD] | | +| Ctrl+Alt+KeyD | ∂ | Ctrl+Alt+D | | Ctrl+Option+D | ctrl+alt+d | Ctrl+Alt+D | ctrl+alt+[KeyD] | | +| Shift+Alt+KeyD | D | Shift+Alt+D | | Shift+Option+D | shift+alt+d | Shift+Alt+D | shift+alt+[KeyD] | | +| Ctrl+Shift+Alt+KeyD | Î | Ctrl+Shift+Alt+D | | Ctrl+Shift+Option+D | ctrl+shift+alt+d | Ctrl+Shift+Alt+D | ctrl+shift+alt+[KeyD] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyE | e | E | | E | e | E | [KeyE] | | +| Ctrl+KeyE | e | Ctrl+E | | Ctrl+E | ctrl+e | Ctrl+E | ctrl+[KeyE] | | +| Shift+KeyE | E | Shift+E | | Shift+E | shift+e | Shift+E | shift+[KeyE] | | +| Ctrl+Shift+KeyE | E | Ctrl+Shift+E | | Ctrl+Shift+E | ctrl+shift+e | Ctrl+Shift+E | ctrl+shift+[KeyE] | | +| Alt+KeyE | e | Alt+E | | Option+E | alt+e | Alt+E | alt+[KeyE] | | +| Ctrl+Alt+KeyE | ´ | Ctrl+Alt+E | | Ctrl+Option+E | ctrl+alt+e | Ctrl+Alt+E | ctrl+alt+[KeyE] | | +| Shift+Alt+KeyE | E | Shift+Alt+E | | Shift+Option+E | shift+alt+e | Shift+Alt+E | shift+alt+[KeyE] | | +| Ctrl+Shift+Alt+KeyE | 助 | Ctrl+Shift+Alt+E | | Ctrl+Shift+Option+E | ctrl+shift+alt+e | Ctrl+Shift+Alt+E | ctrl+shift+alt+[KeyE] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyF | f | F | | F | f | F | [KeyF] | | +| Ctrl+KeyF | f | Ctrl+F | | Ctrl+F | ctrl+f | Ctrl+F | ctrl+[KeyF] | | +| Shift+KeyF | F | Shift+F | | Shift+F | shift+f | Shift+F | shift+[KeyF] | | +| Ctrl+Shift+KeyF | F | Ctrl+Shift+F | | Ctrl+Shift+F | ctrl+shift+f | Ctrl+Shift+F | ctrl+shift+[KeyF] | | +| Alt+KeyF | f | Alt+F | | Option+F | alt+f | Alt+F | alt+[KeyF] | | +| Ctrl+Alt+KeyF | ƒ | Ctrl+Alt+F | | Ctrl+Option+F | ctrl+alt+f | Ctrl+Alt+F | ctrl+alt+[KeyF] | | +| Shift+Alt+KeyF | F | Shift+Alt+F | | Shift+Option+F | shift+alt+f | Shift+Alt+F | shift+alt+[KeyF] | | +| Ctrl+Shift+Alt+KeyF | Ï | Ctrl+Shift+Alt+F | | Ctrl+Shift+Option+F | ctrl+shift+alt+f | Ctrl+Shift+Alt+F | ctrl+shift+alt+[KeyF] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyG | g | G | | G | g | G | [KeyG] | | +| Ctrl+KeyG | g | Ctrl+G | | Ctrl+G | ctrl+g | Ctrl+G | ctrl+[KeyG] | | +| Shift+KeyG | G | Shift+G | | Shift+G | shift+g | Shift+G | shift+[KeyG] | | +| Ctrl+Shift+KeyG | G | Ctrl+Shift+G | | Ctrl+Shift+G | ctrl+shift+g | Ctrl+Shift+G | ctrl+shift+[KeyG] | | +| Alt+KeyG | g | Alt+G | | Option+G | alt+g | Alt+G | alt+[KeyG] | | +| Ctrl+Alt+KeyG | © | Ctrl+Alt+G | | Ctrl+Option+G | ctrl+alt+g | Ctrl+Alt+G | ctrl+alt+[KeyG] | | +| Shift+Alt+KeyG | G | Shift+Alt+G | | Shift+Option+G | shift+alt+g | Shift+Alt+G | shift+alt+[KeyG] | | +| Ctrl+Shift+Alt+KeyG | ˝ | Ctrl+Shift+Alt+G | | Ctrl+Shift+Option+G | ctrl+shift+alt+g | Ctrl+Shift+Alt+G | ctrl+shift+alt+[KeyG] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyH | h | H | | H | h | H | [KeyH] | | +| Ctrl+KeyH | h | Ctrl+H | | Ctrl+H | ctrl+h | Ctrl+H | ctrl+[KeyH] | | +| Shift+KeyH | H | Shift+H | | Shift+H | shift+h | Shift+H | shift+[KeyH] | | +| Ctrl+Shift+KeyH | H | Ctrl+Shift+H | | Ctrl+Shift+H | ctrl+shift+h | Ctrl+Shift+H | ctrl+shift+[KeyH] | | +| Alt+KeyH | h | Alt+H | | Option+H | alt+h | Alt+H | alt+[KeyH] | | +| Ctrl+Alt+KeyH | ˙ | Ctrl+Alt+H | | Ctrl+Option+H | ctrl+alt+h | Ctrl+Alt+H | ctrl+alt+[KeyH] | | +| Shift+Alt+KeyH | H | Shift+Alt+H | | Shift+Option+H | shift+alt+h | Shift+Alt+H | shift+alt+[KeyH] | | +| Ctrl+Shift+Alt+KeyH | 半 | Ctrl+Shift+Alt+H | | Ctrl+Shift+Option+H | ctrl+shift+alt+h | Ctrl+Shift+Alt+H | ctrl+shift+alt+[KeyH] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyI | i | I | | I | i | I | [KeyI] | | +| Ctrl+KeyI | i | Ctrl+I | | Ctrl+I | ctrl+i | Ctrl+I | ctrl+[KeyI] | | +| Shift+KeyI | I | Shift+I | | Shift+I | shift+i | Shift+I | shift+[KeyI] | | +| Ctrl+Shift+KeyI | I | Ctrl+Shift+I | | Ctrl+Shift+I | ctrl+shift+i | Ctrl+Shift+I | ctrl+shift+[KeyI] | | +| Alt+KeyI | i | Alt+I | | Option+I | alt+i | Alt+I | alt+[KeyI] | | +| Ctrl+Alt+KeyI | ˆ | Ctrl+Alt+I | | Ctrl+Option+I | ctrl+alt+i | Ctrl+Alt+I | ctrl+alt+[KeyI] | | +| Shift+Alt+KeyI | I | Shift+Alt+I | | Shift+Option+I | shift+alt+i | Shift+Alt+I | shift+alt+[KeyI] | | +| Ctrl+Shift+Alt+KeyI | ˆ | Ctrl+Shift+Alt+I | | Ctrl+Shift+Option+I | ctrl+shift+alt+i | Ctrl+Shift+Alt+I | ctrl+shift+alt+[KeyI] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyJ | j | J | | J | j | J | [KeyJ] | | +| Ctrl+KeyJ | j | Ctrl+J | | Ctrl+J | ctrl+j | Ctrl+J | ctrl+[KeyJ] | | +| Shift+KeyJ | J | Shift+J | | Shift+J | shift+j | Shift+J | shift+[KeyJ] | | +| Ctrl+Shift+KeyJ | J | Ctrl+Shift+J | | Ctrl+Shift+J | ctrl+shift+j | Ctrl+Shift+J | ctrl+shift+[KeyJ] | | +| Alt+KeyJ | j | Alt+J | | Option+J | alt+j | Alt+J | alt+[KeyJ] | | +| Ctrl+Alt+KeyJ | ∆ | Ctrl+Alt+J | | Ctrl+Option+J | ctrl+alt+j | Ctrl+Alt+J | ctrl+alt+[KeyJ] | | +| Shift+Alt+KeyJ | J | Shift+Alt+J | | Shift+Option+J | shift+alt+j | Shift+Alt+J | shift+alt+[KeyJ] | | +| Ctrl+Shift+Alt+KeyJ | Ô | Ctrl+Shift+Alt+J | | Ctrl+Shift+Option+J | ctrl+shift+alt+j | Ctrl+Shift+Alt+J | ctrl+shift+alt+[KeyJ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyK | k | K | | K | k | K | [KeyK] | | +| Ctrl+KeyK | k | Ctrl+K | | Ctrl+K | ctrl+k | Ctrl+K | ctrl+[KeyK] | | +| Shift+KeyK | K | Shift+K | | Shift+K | shift+k | Shift+K | shift+[KeyK] | | +| Ctrl+Shift+KeyK | K | Ctrl+Shift+K | | Ctrl+Shift+K | ctrl+shift+k | Ctrl+Shift+K | ctrl+shift+[KeyK] | | +| Alt+KeyK | k | Alt+K | | Option+K | alt+k | Alt+K | alt+[KeyK] | | +| Ctrl+Alt+KeyK | ˚ | Ctrl+Alt+K | | Ctrl+Option+K | ctrl+alt+k | Ctrl+Alt+K | ctrl+alt+[KeyK] | | +| Shift+Alt+KeyK | K | Shift+Alt+K | | Shift+Option+K | shift+alt+k | Shift+Alt+K | shift+alt+[KeyK] | | +| Ctrl+Shift+Alt+KeyK |  | Ctrl+Shift+Alt+K | | Ctrl+Shift+Option+K | ctrl+shift+alt+k | Ctrl+Shift+Alt+K | ctrl+shift+alt+[KeyK] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyL | l | L | | L | l | L | [KeyL] | | +| Ctrl+KeyL | l | Ctrl+L | | Ctrl+L | ctrl+l | Ctrl+L | ctrl+[KeyL] | | +| Shift+KeyL | L | Shift+L | | Shift+L | shift+l | Shift+L | shift+[KeyL] | | +| Ctrl+Shift+KeyL | L | Ctrl+Shift+L | | Ctrl+Shift+L | ctrl+shift+l | Ctrl+Shift+L | ctrl+shift+[KeyL] | | +| Alt+KeyL | l | Alt+L | | Option+L | alt+l | Alt+L | alt+[KeyL] | | +| Ctrl+Alt+KeyL | ¬ | Ctrl+Alt+L | | Ctrl+Option+L | ctrl+alt+l | Ctrl+Alt+L | ctrl+alt+[KeyL] | | +| Shift+Alt+KeyL | L | Shift+Alt+L | | Shift+Option+L | shift+alt+l | Shift+Alt+L | shift+alt+[KeyL] | | +| Ctrl+Shift+Alt+KeyL | 查 | Ctrl+Shift+Alt+L | | Ctrl+Shift+Option+L | ctrl+shift+alt+l | Ctrl+Shift+Alt+L | ctrl+shift+alt+[KeyL] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyM | m | M | | M | m | M | [KeyM] | | +| Ctrl+KeyM | m | Ctrl+M | | Ctrl+M | ctrl+m | Ctrl+M | ctrl+[KeyM] | | +| Shift+KeyM | M | Shift+M | | Shift+M | shift+m | Shift+M | shift+[KeyM] | | +| Ctrl+Shift+KeyM | M | Ctrl+Shift+M | | Ctrl+Shift+M | ctrl+shift+m | Ctrl+Shift+M | ctrl+shift+[KeyM] | | +| Alt+KeyM | m | Alt+M | | Option+M | alt+m | Alt+M | alt+[KeyM] | | +| Ctrl+Alt+KeyM | µ | Ctrl+Alt+M | | Ctrl+Option+M | ctrl+alt+m | Ctrl+Alt+M | ctrl+alt+[KeyM] | | +| Shift+Alt+KeyM | M | Shift+Alt+M | | Shift+Option+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | +| Ctrl+Shift+Alt+KeyM |  | Ctrl+Shift+Alt+M | | Ctrl+Shift+Option+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyN | n | N | | N | n | N | [KeyN] | | +| Ctrl+KeyN | n | Ctrl+N | | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | | +| Shift+KeyN | N | Shift+N | | Shift+N | shift+n | Shift+N | shift+[KeyN] | | +| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | | +| Alt+KeyN | n | Alt+N | | Option+N | alt+n | Alt+N | alt+[KeyN] | | +| Ctrl+Alt+KeyN | ˜ | Ctrl+Alt+N | | Ctrl+Option+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | +| Shift+Alt+KeyN | N | Shift+Alt+N | | Shift+Option+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | | +| Ctrl+Shift+Alt+KeyN | ˜ | Ctrl+Shift+Alt+N | | Ctrl+Shift+Option+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyO | o | O | | O | o | O | [KeyO] | | +| Ctrl+KeyO | o | Ctrl+O | | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | | +| Shift+KeyO | O | Shift+O | | Shift+O | shift+o | Shift+O | shift+[KeyO] | | +| Ctrl+Shift+KeyO | O | Ctrl+Shift+O | | Ctrl+Shift+O | ctrl+shift+o | Ctrl+Shift+O | ctrl+shift+[KeyO] | | +| Alt+KeyO | o | Alt+O | | Option+O | alt+o | Alt+O | alt+[KeyO] | | +| Ctrl+Alt+KeyO | ø | Ctrl+Alt+O | | Ctrl+Option+O | ctrl+alt+o | Ctrl+Alt+O | ctrl+alt+[KeyO] | | +| Shift+Alt+KeyO | O | Shift+Alt+O | | Shift+Option+O | shift+alt+o | Shift+Alt+O | shift+alt+[KeyO] | | +| Ctrl+Shift+Alt+KeyO | Ø | Ctrl+Shift+Alt+O | | Ctrl+Shift+Option+O | ctrl+shift+alt+o | Ctrl+Shift+Alt+O | ctrl+shift+alt+[KeyO] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyP | p | P | | P | p | P | [KeyP] | | +| Ctrl+KeyP | p | Ctrl+P | | Ctrl+P | ctrl+p | Ctrl+P | ctrl+[KeyP] | | +| Shift+KeyP | P | Shift+P | | Shift+P | shift+p | Shift+P | shift+[KeyP] | | +| Ctrl+Shift+KeyP | P | Ctrl+Shift+P | | Ctrl+Shift+P | ctrl+shift+p | Ctrl+Shift+P | ctrl+shift+[KeyP] | | +| Alt+KeyP | p | Alt+P | | Option+P | alt+p | Alt+P | alt+[KeyP] | | +| Ctrl+Alt+KeyP | π | Ctrl+Alt+P | | Ctrl+Option+P | ctrl+alt+p | Ctrl+Alt+P | ctrl+alt+[KeyP] | | +| Shift+Alt+KeyP | P | Shift+Alt+P | | Shift+Option+P | shift+alt+p | Shift+Alt+P | shift+alt+[KeyP] | | +| Ctrl+Shift+Alt+KeyP | ∏ | Ctrl+Shift+Alt+P | | Ctrl+Shift+Option+P | ctrl+shift+alt+p | Ctrl+Shift+Alt+P | ctrl+shift+alt+[KeyP] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyQ | q | Q | | Q | q | Q | [KeyQ] | | +| Ctrl+KeyQ | q | Ctrl+Q | | Ctrl+Q | ctrl+q | Ctrl+Q | ctrl+[KeyQ] | | +| Shift+KeyQ | Q | Shift+Q | | Shift+Q | shift+q | Shift+Q | shift+[KeyQ] | | +| Ctrl+Shift+KeyQ | Q | Ctrl+Shift+Q | | Ctrl+Shift+Q | ctrl+shift+q | Ctrl+Shift+Q | ctrl+shift+[KeyQ] | | +| Alt+KeyQ | q | Alt+Q | | Option+Q | alt+q | Alt+Q | alt+[KeyQ] | | +| Ctrl+Alt+KeyQ | œ | Ctrl+Alt+Q | | Ctrl+Option+Q | ctrl+alt+q | Ctrl+Alt+Q | ctrl+alt+[KeyQ] | | +| Shift+Alt+KeyQ | Q | Shift+Alt+Q | | Shift+Option+Q | shift+alt+q | Shift+Alt+Q | shift+alt+[KeyQ] | | +| Ctrl+Shift+Alt+KeyQ | Œ | Ctrl+Shift+Alt+Q | | Ctrl+Shift+Option+Q | ctrl+shift+alt+q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+[KeyQ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyR | r | R | | R | r | R | [KeyR] | | +| Ctrl+KeyR | r | Ctrl+R | | Ctrl+R | ctrl+r | Ctrl+R | ctrl+[KeyR] | | +| Shift+KeyR | R | Shift+R | | Shift+R | shift+r | Shift+R | shift+[KeyR] | | +| Ctrl+Shift+KeyR | R | Ctrl+Shift+R | | Ctrl+Shift+R | ctrl+shift+r | Ctrl+Shift+R | ctrl+shift+[KeyR] | | +| Alt+KeyR | r | Alt+R | | Option+R | alt+r | Alt+R | alt+[KeyR] | | +| Ctrl+Alt+KeyR | ® | Ctrl+Alt+R | | Ctrl+Option+R | ctrl+alt+r | Ctrl+Alt+R | ctrl+alt+[KeyR] | | +| Shift+Alt+KeyR | R | Shift+Alt+R | | Shift+Option+R | shift+alt+r | Shift+Alt+R | shift+alt+[KeyR] | | +| Ctrl+Shift+Alt+KeyR | ‰ | Ctrl+Shift+Alt+R | | Ctrl+Shift+Option+R | ctrl+shift+alt+r | Ctrl+Shift+Alt+R | ctrl+shift+alt+[KeyR] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyS | s | S | | S | s | S | [KeyS] | | +| Ctrl+KeyS | s | Ctrl+S | | Ctrl+S | ctrl+s | Ctrl+S | ctrl+[KeyS] | | +| Shift+KeyS | S | Shift+S | | Shift+S | shift+s | Shift+S | shift+[KeyS] | | +| Ctrl+Shift+KeyS | S | Ctrl+Shift+S | | Ctrl+Shift+S | ctrl+shift+s | Ctrl+Shift+S | ctrl+shift+[KeyS] | | +| Alt+KeyS | s | Alt+S | | Option+S | alt+s | Alt+S | alt+[KeyS] | | +| Ctrl+Alt+KeyS | ß | Ctrl+Alt+S | | Ctrl+Option+S | ctrl+alt+s | Ctrl+Alt+S | ctrl+alt+[KeyS] | | +| Shift+Alt+KeyS | S | Shift+Alt+S | | Shift+Option+S | shift+alt+s | Shift+Alt+S | shift+alt+[KeyS] | | +| Ctrl+Shift+Alt+KeyS | Í | Ctrl+Shift+Alt+S | | Ctrl+Shift+Option+S | ctrl+shift+alt+s | Ctrl+Shift+Alt+S | ctrl+shift+alt+[KeyS] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyT | t | T | | T | t | T | [KeyT] | | +| Ctrl+KeyT | t | Ctrl+T | | Ctrl+T | ctrl+t | Ctrl+T | ctrl+[KeyT] | | +| Shift+KeyT | T | Shift+T | | Shift+T | shift+t | Shift+T | shift+[KeyT] | | +| Ctrl+Shift+KeyT | T | Ctrl+Shift+T | | Ctrl+Shift+T | ctrl+shift+t | Ctrl+Shift+T | ctrl+shift+[KeyT] | | +| Alt+KeyT | t | Alt+T | | Option+T | alt+t | Alt+T | alt+[KeyT] | | +| Ctrl+Alt+KeyT | † | Ctrl+Alt+T | | Ctrl+Option+T | ctrl+alt+t | Ctrl+Alt+T | ctrl+alt+[KeyT] | | +| Shift+Alt+KeyT | T | Shift+Alt+T | | Shift+Option+T | shift+alt+t | Shift+Alt+T | shift+alt+[KeyT] | | +| Ctrl+Shift+Alt+KeyT | ˇ | Ctrl+Shift+Alt+T | | Ctrl+Shift+Option+T | ctrl+shift+alt+t | Ctrl+Shift+Alt+T | ctrl+shift+alt+[KeyT] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyU | u | U | | U | u | U | [KeyU] | | +| Ctrl+KeyU | u | Ctrl+U | | Ctrl+U | ctrl+u | Ctrl+U | ctrl+[KeyU] | | +| Shift+KeyU | U | Shift+U | | Shift+U | shift+u | Shift+U | shift+[KeyU] | | +| Ctrl+Shift+KeyU | U | Ctrl+Shift+U | | Ctrl+Shift+U | ctrl+shift+u | Ctrl+Shift+U | ctrl+shift+[KeyU] | | +| Alt+KeyU | u | Alt+U | | Option+U | alt+u | Alt+U | alt+[KeyU] | | +| Ctrl+Alt+KeyU | ¨ | Ctrl+Alt+U | | Ctrl+Option+U | ctrl+alt+u | Ctrl+Alt+U | ctrl+alt+[KeyU] | | +| Shift+Alt+KeyU | U | Shift+Alt+U | | Shift+Option+U | shift+alt+u | Shift+Alt+U | shift+alt+[KeyU] | | +| Ctrl+Shift+Alt+KeyU | ¨ | Ctrl+Shift+Alt+U | | Ctrl+Shift+Option+U | ctrl+shift+alt+u | Ctrl+Shift+Alt+U | ctrl+shift+alt+[KeyU] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyV | v | V | | V | v | V | [KeyV] | | +| Ctrl+KeyV | v | Ctrl+V | | Ctrl+V | ctrl+v | Ctrl+V | ctrl+[KeyV] | | +| Shift+KeyV | V | Shift+V | | Shift+V | shift+v | Shift+V | shift+[KeyV] | | +| Ctrl+Shift+KeyV | V | Ctrl+Shift+V | | Ctrl+Shift+V | ctrl+shift+v | Ctrl+Shift+V | ctrl+shift+[KeyV] | | +| Alt+KeyV | v | Alt+V | | Option+V | alt+v | Alt+V | alt+[KeyV] | | +| Ctrl+Alt+KeyV | √ | Ctrl+Alt+V | | Ctrl+Option+V | ctrl+alt+v | Ctrl+Alt+V | ctrl+alt+[KeyV] | | +| Shift+Alt+KeyV | V | Shift+Alt+V | | Shift+Option+V | shift+alt+v | Shift+Alt+V | shift+alt+[KeyV] | | +| Ctrl+Shift+Alt+KeyV | ◊ | Ctrl+Shift+Alt+V | | Ctrl+Shift+Option+V | ctrl+shift+alt+v | Ctrl+Shift+Alt+V | ctrl+shift+alt+[KeyV] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyW | w | W | | W | w | W | [KeyW] | | +| Ctrl+KeyW | w | Ctrl+W | | Ctrl+W | ctrl+w | Ctrl+W | ctrl+[KeyW] | | +| Shift+KeyW | W | Shift+W | | Shift+W | shift+w | Shift+W | shift+[KeyW] | | +| Ctrl+Shift+KeyW | W | Ctrl+Shift+W | | Ctrl+Shift+W | ctrl+shift+w | Ctrl+Shift+W | ctrl+shift+[KeyW] | | +| Alt+KeyW | w | Alt+W | | Option+W | alt+w | Alt+W | alt+[KeyW] | | +| Ctrl+Alt+KeyW | ∑ | Ctrl+Alt+W | | Ctrl+Option+W | ctrl+alt+w | Ctrl+Alt+W | ctrl+alt+[KeyW] | | +| Shift+Alt+KeyW | W | Shift+Alt+W | | Shift+Option+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | +| Ctrl+Shift+Alt+KeyW | „ | Ctrl+Shift+Alt+W | | Ctrl+Shift+Option+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyX | x | X | | X | x | X | [KeyX] | | +| Ctrl+KeyX | x | Ctrl+X | | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | | +| Shift+KeyX | X | Shift+X | | Shift+X | shift+x | Shift+X | shift+[KeyX] | | +| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | | +| Alt+KeyX | x | Alt+X | | Option+X | alt+x | Alt+X | alt+[KeyX] | | +| Ctrl+Alt+KeyX | ≈ | Ctrl+Alt+X | | Ctrl+Option+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | | +| Shift+Alt+KeyX | X | Shift+Alt+X | | Shift+Option+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | | +| Ctrl+Shift+Alt+KeyX | ˛ | Ctrl+Shift+Alt+X | | Ctrl+Shift+Option+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyY | y | Y | | Y | y | Y | [KeyY] | | +| Ctrl+KeyY | y | Ctrl+Y | | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyY] | | +| Shift+KeyY | Y | Shift+Y | | Shift+Y | shift+y | Shift+Y | shift+[KeyY] | | +| Ctrl+Shift+KeyY | Y | Ctrl+Shift+Y | | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyY] | | +| Alt+KeyY | y | Alt+Y | | Option+Y | alt+y | Alt+Y | alt+[KeyY] | | +| Ctrl+Alt+KeyY | ¥ | Ctrl+Alt+Y | | Ctrl+Option+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyY] | | +| Shift+Alt+KeyY | Y | Shift+Alt+Y | | Shift+Option+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyY] | | +| Ctrl+Shift+Alt+KeyY | Á | Ctrl+Shift+Alt+Y | | Ctrl+Shift+Option+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyY] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| KeyZ | z | Z | | Z | z | Z | [KeyZ] | | +| Ctrl+KeyZ | z | Ctrl+Z | | Ctrl+Z | ctrl+z | Ctrl+Z | ctrl+[KeyZ] | | +| Shift+KeyZ | Z | Shift+Z | | Shift+Z | shift+z | Shift+Z | shift+[KeyZ] | | +| Ctrl+Shift+KeyZ | Z | Ctrl+Shift+Z | | Ctrl+Shift+Z | ctrl+shift+z | Ctrl+Shift+Z | ctrl+shift+[KeyZ] | | +| Alt+KeyZ | z | Alt+Z | | Option+Z | alt+z | Alt+Z | alt+[KeyZ] | | +| Ctrl+Alt+KeyZ | Ω | Ctrl+Alt+Z | | Ctrl+Option+Z | ctrl+alt+z | Ctrl+Alt+Z | ctrl+alt+[KeyZ] | | +| Shift+Alt+KeyZ | Z | Shift+Alt+Z | | Shift+Option+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyZ] | | +| Ctrl+Shift+Alt+KeyZ | ¸ | Ctrl+Shift+Alt+Z | | Ctrl+Shift+Option+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyZ] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit1 | 1 | 1 | | 1 | 1 | 1 | [Digit1] | | +| Ctrl+Digit1 | 1 | Ctrl+1 | | Ctrl+1 | ctrl+1 | Ctrl+1 | ctrl+[Digit1] | | +| Shift+Digit1 | ! | Shift+1 | | Shift+1 | shift+1 | Shift+1 | shift+[Digit1] | | +| Ctrl+Shift+Digit1 | ! | Ctrl+Shift+1 | | Ctrl+Shift+1 | ctrl+shift+1 | Ctrl+Shift+1 | ctrl+shift+[Digit1] | | +| Alt+Digit1 | 1 | Alt+1 | | Option+1 | alt+1 | Alt+1 | alt+[Digit1] | | +| Ctrl+Alt+Digit1 | 1 | Ctrl+Alt+1 | | Ctrl+Option+1 | ctrl+alt+1 | Ctrl+Alt+1 | ctrl+alt+[Digit1] | | +| Shift+Alt+Digit1 | ! | Shift+Alt+1 | | Shift+Option+1 | shift+alt+1 | Shift+Alt+1 | shift+alt+[Digit1] | | +| Ctrl+Shift+Alt+Digit1 | ⁄ | Ctrl+Shift+Alt+1 | | Ctrl+Shift+Option+1 | ctrl+shift+alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+[Digit1] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit2 | 2 | 2 | | 2 | 2 | 2 | [Digit2] | | +| Ctrl+Digit2 | 2 | Ctrl+2 | | Ctrl+2 | ctrl+2 | Ctrl+2 | ctrl+[Digit2] | | +| Shift+Digit2 | @ | Shift+2 | | Shift+2 | shift+2 | Shift+2 | shift+[Digit2] | | +| Ctrl+Shift+Digit2 | @ | Ctrl+Shift+2 | | Ctrl+Shift+2 | ctrl+shift+2 | Ctrl+Shift+2 | ctrl+shift+[Digit2] | | +| Alt+Digit2 | 2 | Alt+2 | | Option+2 | alt+2 | Alt+2 | alt+[Digit2] | | +| Ctrl+Alt+Digit2 | 2 | Ctrl+Alt+2 | | Ctrl+Option+2 | ctrl+alt+2 | Ctrl+Alt+2 | ctrl+alt+[Digit2] | | +| Shift+Alt+Digit2 | @ | Shift+Alt+2 | | Shift+Option+2 | shift+alt+2 | Shift+Alt+2 | shift+alt+[Digit2] | | +| Ctrl+Shift+Alt+Digit2 | € | Ctrl+Shift+Alt+2 | | Ctrl+Shift+Option+2 | ctrl+shift+alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+[Digit2] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit3 | 3 | 3 | | 3 | 3 | 3 | [Digit3] | | +| Ctrl+Digit3 | 3 | Ctrl+3 | | Ctrl+3 | ctrl+3 | Ctrl+3 | ctrl+[Digit3] | | +| Shift+Digit3 | # | Shift+3 | | Shift+3 | shift+3 | Shift+3 | shift+[Digit3] | | +| Ctrl+Shift+Digit3 | # | Ctrl+Shift+3 | | Ctrl+Shift+3 | ctrl+shift+3 | Ctrl+Shift+3 | ctrl+shift+[Digit3] | | +| Alt+Digit3 | 3 | Alt+3 | | Option+3 | alt+3 | Alt+3 | alt+[Digit3] | | +| Ctrl+Alt+Digit3 | 3 | Ctrl+Alt+3 | | Ctrl+Option+3 | ctrl+alt+3 | Ctrl+Alt+3 | ctrl+alt+[Digit3] | | +| Shift+Alt+Digit3 | # | Shift+Alt+3 | | Shift+Option+3 | shift+alt+3 | Shift+Alt+3 | shift+alt+[Digit3] | | +| Ctrl+Shift+Alt+Digit3 | ‹ | Ctrl+Shift+Alt+3 | | Ctrl+Shift+Option+3 | ctrl+shift+alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+[Digit3] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit4 | 4 | 4 | | 4 | 4 | 4 | [Digit4] | | +| Ctrl+Digit4 | 4 | Ctrl+4 | | Ctrl+4 | ctrl+4 | Ctrl+4 | ctrl+[Digit4] | | +| Shift+Digit4 | $ | Shift+4 | | Shift+4 | shift+4 | Shift+4 | shift+[Digit4] | | +| Ctrl+Shift+Digit4 | $ | Ctrl+Shift+4 | | Ctrl+Shift+4 | ctrl+shift+4 | Ctrl+Shift+4 | ctrl+shift+[Digit4] | | +| Alt+Digit4 | 4 | Alt+4 | | Option+4 | alt+4 | Alt+4 | alt+[Digit4] | | +| Ctrl+Alt+Digit4 | 4 | Ctrl+Alt+4 | | Ctrl+Option+4 | ctrl+alt+4 | Ctrl+Alt+4 | ctrl+alt+[Digit4] | | +| Shift+Alt+Digit4 | $ | Shift+Alt+4 | | Shift+Option+4 | shift+alt+4 | Shift+Alt+4 | shift+alt+[Digit4] | | +| Ctrl+Shift+Alt+Digit4 | › | Ctrl+Shift+Alt+4 | | Ctrl+Shift+Option+4 | ctrl+shift+alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+[Digit4] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit5 | 5 | 5 | | 5 | 5 | 5 | [Digit5] | | +| Ctrl+Digit5 | 5 | Ctrl+5 | | Ctrl+5 | ctrl+5 | Ctrl+5 | ctrl+[Digit5] | | +| Shift+Digit5 | % | Shift+5 | | Shift+5 | shift+5 | Shift+5 | shift+[Digit5] | | +| Ctrl+Shift+Digit5 | % | Ctrl+Shift+5 | | Ctrl+Shift+5 | ctrl+shift+5 | Ctrl+Shift+5 | ctrl+shift+[Digit5] | | +| Alt+Digit5 | 5 | Alt+5 | | Option+5 | alt+5 | Alt+5 | alt+[Digit5] | | +| Ctrl+Alt+Digit5 | 5 | Ctrl+Alt+5 | | Ctrl+Option+5 | ctrl+alt+5 | Ctrl+Alt+5 | ctrl+alt+[Digit5] | | +| Shift+Alt+Digit5 | % | Shift+Alt+5 | | Shift+Option+5 | shift+alt+5 | Shift+Alt+5 | shift+alt+[Digit5] | | +| Ctrl+Shift+Alt+Digit5 | fi | Ctrl+Shift+Alt+5 | | Ctrl+Shift+Option+5 | ctrl+shift+alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+[Digit5] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit6 | 6 | 6 | | 6 | 6 | 6 | [Digit6] | | +| Ctrl+Digit6 | 6 | Ctrl+6 | | Ctrl+6 | ctrl+6 | Ctrl+6 | ctrl+[Digit6] | | +| Shift+Digit6 | --- | Shift+6 | | Shift+6 | shift+6 | Shift+6 | shift+[Digit6] | | +| Ctrl+Shift+Digit6 | --- | Ctrl+Shift+6 | | Ctrl+Shift+6 | ctrl+shift+6 | Ctrl+Shift+6 | ctrl+shift+[Digit6] | | +| Alt+Digit6 | 6 | Alt+6 | | Option+6 | alt+6 | Alt+6 | alt+[Digit6] | | +| Ctrl+Alt+Digit6 | 6 | Ctrl+Alt+6 | | Ctrl+Option+6 | ctrl+alt+6 | Ctrl+Alt+6 | ctrl+alt+[Digit6] | | +| Shift+Alt+Digit6 | --- | Shift+Alt+6 | | Shift+Option+6 | shift+alt+6 | Shift+Alt+6 | shift+alt+[Digit6] | | +| Ctrl+Shift+Alt+Digit6 | fl | Ctrl+Shift+Alt+6 | | Ctrl+Shift+Option+6 | ctrl+shift+alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+[Digit6] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit7 | 7 | 7 | | 7 | 7 | 7 | [Digit7] | | +| Ctrl+Digit7 | 7 | Ctrl+7 | | Ctrl+7 | ctrl+7 | Ctrl+7 | ctrl+[Digit7] | | +| Shift+Digit7 | & | Shift+7 | | Shift+7 | shift+7 | Shift+7 | shift+[Digit7] | | +| Ctrl+Shift+Digit7 | & | Ctrl+Shift+7 | | Ctrl+Shift+7 | ctrl+shift+7 | Ctrl+Shift+7 | ctrl+shift+[Digit7] | | +| Alt+Digit7 | 7 | Alt+7 | | Option+7 | alt+7 | Alt+7 | alt+[Digit7] | | +| Ctrl+Alt+Digit7 | 7 | Ctrl+Alt+7 | | Ctrl+Option+7 | ctrl+alt+7 | Ctrl+Alt+7 | ctrl+alt+[Digit7] | | +| Shift+Alt+Digit7 | & | Shift+Alt+7 | | Shift+Option+7 | shift+alt+7 | Shift+Alt+7 | shift+alt+[Digit7] | | +| Ctrl+Shift+Alt+Digit7 | ‡ | Ctrl+Shift+Alt+7 | | Ctrl+Shift+Option+7 | ctrl+shift+alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+[Digit7] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit8 | 8 | 8 | | 8 | 8 | 8 | [Digit8] | | +| Ctrl+Digit8 | 8 | Ctrl+8 | | Ctrl+8 | ctrl+8 | Ctrl+8 | ctrl+[Digit8] | | +| Shift+Digit8 | * | Shift+8 | | Shift+8 | shift+8 | Shift+8 | shift+[Digit8] | | +| Ctrl+Shift+Digit8 | * | Ctrl+Shift+8 | | Ctrl+Shift+8 | ctrl+shift+8 | Ctrl+Shift+8 | ctrl+shift+[Digit8] | | +| Alt+Digit8 | 8 | Alt+8 | | Option+8 | alt+8 | Alt+8 | alt+[Digit8] | | +| Ctrl+Alt+Digit8 | 8 | Ctrl+Alt+8 | | Ctrl+Option+8 | ctrl+alt+8 | Ctrl+Alt+8 | ctrl+alt+[Digit8] | | +| Shift+Alt+Digit8 | * | Shift+Alt+8 | | Shift+Option+8 | shift+alt+8 | Shift+Alt+8 | shift+alt+[Digit8] | | +| Ctrl+Shift+Alt+Digit8 | ° | Ctrl+Shift+Alt+8 | | Ctrl+Shift+Option+8 | ctrl+shift+alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+[Digit8] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit9 | 9 | 9 | | 9 | 9 | 9 | [Digit9] | | +| Ctrl+Digit9 | 9 | Ctrl+9 | | Ctrl+9 | ctrl+9 | Ctrl+9 | ctrl+[Digit9] | | +| Shift+Digit9 | ( | Shift+9 | | Shift+9 | shift+9 | Shift+9 | shift+[Digit9] | | +| Ctrl+Shift+Digit9 | ( | Ctrl+Shift+9 | | Ctrl+Shift+9 | ctrl+shift+9 | Ctrl+Shift+9 | ctrl+shift+[Digit9] | | +| Alt+Digit9 | 9 | Alt+9 | | Option+9 | alt+9 | Alt+9 | alt+[Digit9] | | +| Ctrl+Alt+Digit9 | 9 | Ctrl+Alt+9 | | Ctrl+Option+9 | ctrl+alt+9 | Ctrl+Alt+9 | ctrl+alt+[Digit9] | | +| Shift+Alt+Digit9 | ( | Shift+Alt+9 | | Shift+Option+9 | shift+alt+9 | Shift+Alt+9 | shift+alt+[Digit9] | | +| Ctrl+Shift+Alt+Digit9 | · | Ctrl+Shift+Alt+9 | | Ctrl+Shift+Option+9 | ctrl+shift+alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+[Digit9] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Digit0 | 0 | 0 | | 0 | 0 | 0 | [Digit0] | | +| Ctrl+Digit0 | 0 | Ctrl+0 | | Ctrl+0 | ctrl+0 | Ctrl+0 | ctrl+[Digit0] | | +| Shift+Digit0 | ) | Shift+0 | | Shift+0 | shift+0 | Shift+0 | shift+[Digit0] | | +| Ctrl+Shift+Digit0 | ) | Ctrl+Shift+0 | | Ctrl+Shift+0 | ctrl+shift+0 | Ctrl+Shift+0 | ctrl+shift+[Digit0] | | +| Alt+Digit0 | 0 | Alt+0 | | Option+0 | alt+0 | Alt+0 | alt+[Digit0] | | +| Ctrl+Alt+Digit0 | 0 | Ctrl+Alt+0 | | Ctrl+Option+0 | ctrl+alt+0 | Ctrl+Alt+0 | ctrl+alt+[Digit0] | | +| Shift+Alt+Digit0 | ) | Shift+Alt+0 | | Shift+Option+0 | shift+alt+0 | Shift+Alt+0 | shift+alt+[Digit0] | | +| Ctrl+Shift+Alt+Digit0 | ‚ | Ctrl+Shift+Alt+0 | | Ctrl+Shift+Option+0 | ctrl+shift+alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+[Digit0] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Minus | - | - | | - | - | - | [Minus] | | +| Ctrl+Minus | - | Ctrl+- | | Ctrl+- | ctrl+- | Ctrl+- | ctrl+[Minus] | | +| Shift+Minus | --- | Shift+- | | Shift+- | shift+- | Shift+- | shift+[Minus] | | +| Ctrl+Shift+Minus | --- | Ctrl+Shift+- | | Ctrl+Shift+- | ctrl+shift+- | Ctrl+Shift+- | ctrl+shift+[Minus] | | +| Alt+Minus | - | Alt+- | | Option+- | alt+- | Alt+- | alt+[Minus] | | +| Ctrl+Alt+Minus | – | Ctrl+Alt+- | | Ctrl+Option+- | ctrl+alt+- | Ctrl+Alt+- | ctrl+alt+[Minus] | | +| Shift+Alt+Minus | --- | Shift+Alt+- | | Shift+Option+- | shift+alt+- | Shift+Alt+- | shift+alt+[Minus] | | +| Ctrl+Shift+Alt+Minus | — | Ctrl+Shift+Alt+- | | Ctrl+Shift+Option+- | ctrl+shift+alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+[Minus] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Equal | = | = | | = | = | = | [Equal] | | +| Ctrl+Equal | = | Ctrl+= | | Ctrl+= | ctrl+= | Ctrl+= | ctrl+[Equal] | | +| Shift+Equal | + | Shift+= | | Shift+= | shift+= | Shift+= | shift+[Equal] | | +| Ctrl+Shift+Equal | + | Ctrl+Shift+= | | Ctrl+Shift+= | ctrl+shift+= | Ctrl+Shift+= | ctrl+shift+[Equal] | | +| Alt+Equal | = | Alt+= | | Option+= | alt+= | Alt+= | alt+[Equal] | | +| Ctrl+Alt+Equal | ≠ | Ctrl+Alt+= | | Ctrl+Option+= | ctrl+alt+= | Ctrl+Alt+= | ctrl+alt+[Equal] | | +| Shift+Alt+Equal | + | Shift+Alt+= | | Shift+Option+= | shift+alt+= | Shift+Alt+= | shift+alt+[Equal] | | +| Ctrl+Shift+Alt+Equal | ± | Ctrl+Shift+Alt+= | | Ctrl+Shift+Option+= | ctrl+shift+alt+= | Ctrl+Shift+Alt+= | ctrl+shift+alt+[Equal] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketLeft | 【 | [ | 1 | 【 | [BracketLeft] | null | [BracketLeft] | NO | +| Ctrl+BracketLeft | 【 | Ctrl+[ | 1 | Ctrl+【 | ctrl+[BracketLeft] | null | ctrl+[BracketLeft] | NO | +| Shift+BracketLeft | 「 | [ | 2 | Shift+【 | shift+[BracketLeft] | null | shift+[BracketLeft] | NO | +| Ctrl+Shift+BracketLeft | 「 | Ctrl+[ | 2 | Ctrl+Shift+【 | ctrl+shift+[BracketLeft] | null | ctrl+shift+[BracketLeft] | NO | +| Alt+BracketLeft | 【 | Alt+[ | 1 | Option+【 | alt+[BracketLeft] | null | alt+[BracketLeft] | NO | +| Ctrl+Alt+BracketLeft | “ | Ctrl+Alt+[ | 1 | Ctrl+Option+【 | ctrl+alt+[BracketLeft] | null | ctrl+alt+[BracketLeft] | NO | +| Shift+Alt+BracketLeft | 「 | Alt+[ | 2 | Shift+Option+【 | shift+alt+[BracketLeft] | null | shift+alt+[BracketLeft] | NO | +| Ctrl+Shift+Alt+BracketLeft | ” | Ctrl+Alt+[ | 2 | Ctrl+Shift+Option+【 | ctrl+shift+alt+[BracketLeft] | null | ctrl+shift+alt+[BracketLeft] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| BracketRight | 】 | ] | 1 | 】 | [BracketRight] | null | [BracketRight] | NO | +| Ctrl+BracketRight | 】 | Ctrl+] | 1 | Ctrl+】 | ctrl+[BracketRight] | null | ctrl+[BracketRight] | NO | +| Shift+BracketRight | 」 | ] | 2 | Shift+】 | shift+[BracketRight] | null | shift+[BracketRight] | NO | +| Ctrl+Shift+BracketRight | 」 | Ctrl+] | 2 | Ctrl+Shift+】 | ctrl+shift+[BracketRight] | null | ctrl+shift+[BracketRight] | NO | +| Alt+BracketRight | 】 | Alt+] | 1 | Option+】 | alt+[BracketRight] | null | alt+[BracketRight] | NO | +| Ctrl+Alt+BracketRight | ‘ | Ctrl+Alt+] | 1 | Ctrl+Option+】 | ctrl+alt+[BracketRight] | null | ctrl+alt+[BracketRight] | NO | +| Shift+Alt+BracketRight | 」 | Alt+] | 2 | Shift+Option+】 | shift+alt+[BracketRight] | null | shift+alt+[BracketRight] | NO | +| Ctrl+Shift+Alt+BracketRight | ’ | Ctrl+Alt+] | 2 | Ctrl+Shift+Option+】 | ctrl+shift+alt+[BracketRight] | null | ctrl+shift+alt+[BracketRight] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backslash | 、 | | | 、 | [Backslash] | null | [Backslash] | NO | +| Ctrl+Backslash | 、 | | | Ctrl+、 | ctrl+[Backslash] | null | ctrl+[Backslash] | NO | +| Shift+Backslash | | | | | Shift+、 | shift+[Backslash] | null | shift+[Backslash] | NO | +| Ctrl+Shift+Backslash | | | | | Ctrl+Shift+、 | ctrl+shift+[Backslash] | null | ctrl+shift+[Backslash] | NO | +| Alt+Backslash | 、 | | | Option+、 | alt+[Backslash] | null | alt+[Backslash] | NO | +| Ctrl+Alt+Backslash | « | | | Ctrl+Option+、 | ctrl+alt+[Backslash] | null | ctrl+alt+[Backslash] | NO | +| Shift+Alt+Backslash | | | | | Shift+Option+、 | shift+alt+[Backslash] | null | shift+alt+[Backslash] | NO | +| Ctrl+Shift+Alt+Backslash | » | | | Ctrl+Shift+Option+、 | ctrl+shift+alt+[Backslash] | null | ctrl+shift+alt+[Backslash] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlHash | --- | | | null | null | null | null | | +| Ctrl+IntlHash | --- | | | null | null | null | null | | +| Shift+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+IntlHash | --- | | | null | null | null | null | | +| Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Alt+IntlHash | --- | | | null | null | null | null | | +| Shift+Alt+IntlHash | --- | | | null | null | null | null | | +| Ctrl+Shift+Alt+IntlHash | --- | | | null | null | null | null | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Semicolon | ; | ; | | ; | ; | ; | [Semicolon] | NO | +| Ctrl+Semicolon | ; | Ctrl+; | | Ctrl+; | ctrl+; | Ctrl+; | ctrl+[Semicolon] | NO | +| Shift+Semicolon | : | Shift+; | | Shift+; | shift+; | Shift+; | shift+[Semicolon] | NO | +| Ctrl+Shift+Semicolon | : | Ctrl+Shift+; | | Ctrl+Shift+; | ctrl+shift+; | Ctrl+Shift+; | ctrl+shift+[Semicolon] | NO | +| Alt+Semicolon | ; | Alt+; | | Option+; | alt+; | Alt+; | alt+[Semicolon] | NO | +| Ctrl+Alt+Semicolon | … | Ctrl+Alt+; | | Ctrl+Option+; | ctrl+alt+; | Ctrl+Alt+; | ctrl+alt+[Semicolon] | NO | +| Shift+Alt+Semicolon | : | Shift+Alt+; | | Shift+Option+; | shift+alt+; | Shift+Alt+; | shift+alt+[Semicolon] | NO | +| Ctrl+Shift+Alt+Semicolon | Ú | Ctrl+Shift+Alt+; | | Ctrl+Shift+Option+; | ctrl+shift+alt+; | Ctrl+Shift+Alt+; | ctrl+shift+alt+[Semicolon] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Quote | ' | ' | | ' | ' | ' | [Quote] | | +| Ctrl+Quote | ' | Ctrl+' | | Ctrl+' | ctrl+' | Ctrl+' | ctrl+[Quote] | | +| Shift+Quote | " | Shift+' | | Shift+' | shift+' | Shift+' | shift+[Quote] | | +| Ctrl+Shift+Quote | " | Ctrl+Shift+' | | Ctrl+Shift+' | ctrl+shift+' | Ctrl+Shift+' | ctrl+shift+[Quote] | | +| Alt+Quote | ' | Alt+' | | Option+' | alt+' | Alt+' | alt+[Quote] | | +| Ctrl+Alt+Quote | æ | Ctrl+Alt+' | | Ctrl+Option+' | ctrl+alt+' | Ctrl+Alt+' | ctrl+alt+[Quote] | | +| Shift+Alt+Quote | " | Shift+Alt+' | | Shift+Option+' | shift+alt+' | Shift+Alt+' | shift+alt+[Quote] | | +| Ctrl+Shift+Alt+Quote | Æ | Ctrl+Shift+Alt+' | | Ctrl+Shift+Option+' | ctrl+shift+alt+' | Ctrl+Shift+Alt+' | ctrl+shift+alt+[Quote] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Backquote | · | | | · | [Backquote] | null | [Backquote] | NO | +| Ctrl+Backquote | · | | | Ctrl+· | ctrl+[Backquote] | null | ctrl+[Backquote] | NO | +| Shift+Backquote | ~ | | | Shift+· | shift+[Backquote] | null | shift+[Backquote] | NO | +| Ctrl+Shift+Backquote | ~ | | | Ctrl+Shift+· | ctrl+shift+[Backquote] | null | ctrl+shift+[Backquote] | NO | +| Alt+Backquote | · | | | Option+· | alt+[Backquote] | null | alt+[Backquote] | NO | +| Ctrl+Alt+Backquote | · | | | Ctrl+Option+· | ctrl+alt+[Backquote] | null | ctrl+alt+[Backquote] | NO | +| Shift+Alt+Backquote | ~ | | | Shift+Option+· | shift+alt+[Backquote] | null | shift+alt+[Backquote] | NO | +| Ctrl+Shift+Alt+Backquote | · | | | Ctrl+Shift+Option+· | ctrl+shift+alt+[Backquote] | null | ctrl+shift+alt+[Backquote] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Comma | , | , | | , | , | , | [Comma] | NO | +| Ctrl+Comma | , | Ctrl+, | | Ctrl+, | ctrl+, | Ctrl+, | ctrl+[Comma] | NO | +| Shift+Comma | 《 | Shift+, | | Shift+, | shift+, | Shift+, | shift+[Comma] | NO | +| Ctrl+Shift+Comma | 《 | Ctrl+Shift+, | | Ctrl+Shift+, | ctrl+shift+, | Ctrl+Shift+, | ctrl+shift+[Comma] | NO | +| Alt+Comma | , | Alt+, | | Option+, | alt+, | Alt+, | alt+[Comma] | NO | +| Ctrl+Alt+Comma | ≤ | Ctrl+Alt+, | | Ctrl+Option+, | ctrl+alt+, | Ctrl+Alt+, | ctrl+alt+[Comma] | NO | +| Shift+Alt+Comma | 《 | Shift+Alt+, | | Shift+Option+, | shift+alt+, | Shift+Alt+, | shift+alt+[Comma] | NO | +| Ctrl+Shift+Alt+Comma | ¯ | Ctrl+Shift+Alt+, | | Ctrl+Shift+Option+, | ctrl+shift+alt+, | Ctrl+Shift+Alt+, | ctrl+shift+alt+[Comma] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Period | 。 | . | | 。 | . | . | [Period] | NO | +| Ctrl+Period | 。 | Ctrl+. | | Ctrl+。 | ctrl+. | Ctrl+. | ctrl+[Period] | NO | +| Shift+Period | 》 | Shift+. | | Shift+。 | shift+. | Shift+. | shift+[Period] | NO | +| Ctrl+Shift+Period | 》 | Ctrl+Shift+. | | Ctrl+Shift+。 | ctrl+shift+. | Ctrl+Shift+. | ctrl+shift+[Period] | NO | +| Alt+Period | 。 | Alt+. | | Option+。 | alt+. | Alt+. | alt+[Period] | NO | +| Ctrl+Alt+Period | ≥ | Ctrl+Alt+. | | Ctrl+Option+。 | ctrl+alt+. | Ctrl+Alt+. | ctrl+alt+[Period] | NO | +| Shift+Alt+Period | 》 | Shift+Alt+. | | Shift+Option+。 | shift+alt+. | Shift+Alt+. | shift+alt+[Period] | NO | +| Ctrl+Shift+Alt+Period | ˘ | Ctrl+Shift+Alt+. | | Ctrl+Shift+Option+。 | ctrl+shift+alt+. | Ctrl+Shift+Alt+. | ctrl+shift+alt+[Period] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Slash | / | / | | / | / | / | [Slash] | | +| Ctrl+Slash | / | Ctrl+/ | | Ctrl+/ | ctrl+/ | Ctrl+/ | ctrl+[Slash] | | +| Shift+Slash | ? | Shift+/ | | Shift+/ | shift+/ | Shift+/ | shift+[Slash] | | +| Ctrl+Shift+Slash | ? | Ctrl+Shift+/ | | Ctrl+Shift+/ | ctrl+shift+/ | Ctrl+Shift+/ | ctrl+shift+[Slash] | | +| Alt+Slash | / | Alt+/ | | Option+/ | alt+/ | Alt+/ | alt+[Slash] | | +| Ctrl+Alt+Slash | ÷ | Ctrl+Alt+/ | | Ctrl+Option+/ | ctrl+alt+/ | Ctrl+Alt+/ | ctrl+alt+[Slash] | | +| Shift+Alt+Slash | ? | Shift+Alt+/ | | Shift+Option+/ | shift+alt+/ | Shift+Alt+/ | shift+alt+[Slash] | | +| Ctrl+Shift+Alt+Slash | ¿ | Ctrl+Shift+Alt+/ | | Ctrl+Shift+Option+/ | ctrl+shift+alt+/ | Ctrl+Shift+Alt+/ | ctrl+shift+alt+[Slash] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| ArrowUp | --- | UpArrow | | UpArrow | up | Up | [ArrowUp] | | +| Ctrl+ArrowUp | --- | Ctrl+UpArrow | | Ctrl+UpArrow | ctrl+up | Ctrl+Up | ctrl+[ArrowUp] | | +| Shift+ArrowUp | --- | Shift+UpArrow | | Shift+UpArrow | shift+up | Shift+Up | shift+[ArrowUp] | | +| Ctrl+Shift+ArrowUp | --- | Ctrl+Shift+UpArrow | | Ctrl+Shift+UpArrow | ctrl+shift+up | Ctrl+Shift+Up | ctrl+shift+[ArrowUp] | | +| Alt+ArrowUp | --- | Alt+UpArrow | | Option+UpArrow | alt+up | Alt+Up | alt+[ArrowUp] | | +| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | | Ctrl+Option+UpArrow | ctrl+alt+up | Ctrl+Alt+Up | ctrl+alt+[ArrowUp] | | +| Shift+Alt+ArrowUp | --- | Shift+Alt+UpArrow | | Shift+Option+UpArrow | shift+alt+up | Shift+Alt+Up | shift+alt+[ArrowUp] | | +| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | | Ctrl+Shift+Option+UpArrow | ctrl+shift+alt+up | Ctrl+Shift+Alt+Up | ctrl+shift+alt+[ArrowUp] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Numpad0 | --- | NumPad0 | | NumPad0 | numpad0 | null | [Numpad0] | | +| Ctrl+Numpad0 | --- | Ctrl+NumPad0 | | Ctrl+NumPad0 | ctrl+numpad0 | null | ctrl+[Numpad0] | | +| Shift+Numpad0 | --- | Shift+NumPad0 | | Shift+NumPad0 | shift+numpad0 | null | shift+[Numpad0] | | +| Ctrl+Shift+Numpad0 | --- | Ctrl+Shift+NumPad0 | | Ctrl+Shift+NumPad0 | ctrl+shift+numpad0 | null | ctrl+shift+[Numpad0] | | +| Alt+Numpad0 | --- | Alt+NumPad0 | | Option+NumPad0 | alt+numpad0 | null | alt+[Numpad0] | | +| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | | Ctrl+Option+NumPad0 | ctrl+alt+numpad0 | null | ctrl+alt+[Numpad0] | | +| Shift+Alt+Numpad0 | --- | Shift+Alt+NumPad0 | | Shift+Option+NumPad0 | shift+alt+numpad0 | null | shift+alt+[Numpad0] | | +| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | | Ctrl+Shift+Option+NumPad0 | ctrl+shift+alt+numpad0 | null | ctrl+shift+alt+[Numpad0] | | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlBackslash | § | | | § | [IntlBackslash] | null | [IntlBackslash] | NO | +| Ctrl+IntlBackslash | § | | | Ctrl+§ | ctrl+[IntlBackslash] | null | ctrl+[IntlBackslash] | NO | +| Shift+IntlBackslash | ± | | | Shift+§ | shift+[IntlBackslash] | null | shift+[IntlBackslash] | NO | +| Ctrl+Shift+IntlBackslash | ± | | | Ctrl+Shift+§ | ctrl+shift+[IntlBackslash] | null | ctrl+shift+[IntlBackslash] | NO | +| Alt+IntlBackslash | § | | | Option+§ | alt+[IntlBackslash] | null | alt+[IntlBackslash] | NO | +| Ctrl+Alt+IntlBackslash | § | | | Ctrl+Option+§ | ctrl+alt+[IntlBackslash] | null | ctrl+alt+[IntlBackslash] | NO | +| Shift+Alt+IntlBackslash | ± | | | Shift+Option+§ | shift+alt+[IntlBackslash] | null | shift+alt+[IntlBackslash] | NO | +| Ctrl+Shift+Alt+IntlBackslash | ± | | | Ctrl+Shift+Option+§ | ctrl+shift+alt+[IntlBackslash] | null | ctrl+shift+alt+[IntlBackslash] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlRo | --- | | | null | [IntlRo] | null | [IntlRo] | NO | +| Ctrl+IntlRo | --- | | | null | ctrl+[IntlRo] | null | ctrl+[IntlRo] | NO | +| Shift+IntlRo | --- | | | null | shift+[IntlRo] | null | shift+[IntlRo] | NO | +| Ctrl+Shift+IntlRo | --- | | | null | ctrl+shift+[IntlRo] | null | ctrl+shift+[IntlRo] | NO | +| Alt+IntlRo | --- | | | null | alt+[IntlRo] | null | alt+[IntlRo] | NO | +| Ctrl+Alt+IntlRo | --- | | | null | ctrl+alt+[IntlRo] | null | ctrl+alt+[IntlRo] | NO | +| Shift+Alt+IntlRo | --- | | | null | shift+alt+[IntlRo] | null | shift+alt+[IntlRo] | NO | +| Ctrl+Shift+Alt+IntlRo | --- | | | null | ctrl+shift+alt+[IntlRo] | null | ctrl+shift+alt+[IntlRo] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | Pri | UI label | User settings | Electron accelerator | Dispatching string | WYSIWYG | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| IntlYen | --- | | | null | [IntlYen] | null | [IntlYen] | NO | +| Ctrl+IntlYen | --- | | | null | ctrl+[IntlYen] | null | ctrl+[IntlYen] | NO | +| Shift+IntlYen | --- | | | null | shift+[IntlYen] | null | shift+[IntlYen] | NO | +| Ctrl+Shift+IntlYen | --- | | | null | ctrl+shift+[IntlYen] | null | ctrl+shift+[IntlYen] | NO | +| Alt+IntlYen | --- | | | null | alt+[IntlYen] | null | alt+[IntlYen] | NO | +| Ctrl+Alt+IntlYen | --- | | | null | ctrl+alt+[IntlYen] | null | ctrl+alt+[IntlYen] | NO | +| Shift+Alt+IntlYen | --- | | | null | shift+alt+[IntlYen] | null | shift+alt+[IntlYen] | NO | +| Ctrl+Shift+Alt+IntlYen | --- | | | null | ctrl+shift+alt+[IntlYen] | null | ctrl+shift+alt+[IntlYen] | NO | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/node/win_de_ch.js b/src/vs/workbench/services/keybinding/test/node/win_de_ch.js new file mode 100644 index 00000000000..a0e38d675e2 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/win_de_ch.js @@ -0,0 +1,1093 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +define({ + Sleep: { + vkey: 'VK_SLEEP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + WakeUp: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + KeyA: { + vkey: 'VK_A', + value: 'a', + withShift: 'A', + withAltGr: '', + withShiftAltGr: '' + }, + KeyB: { + vkey: 'VK_B', + value: 'b', + withShift: 'B', + withAltGr: '', + withShiftAltGr: '' + }, + KeyC: { + vkey: 'VK_C', + value: 'c', + withShift: 'C', + withAltGr: '', + withShiftAltGr: '' + }, + KeyD: { + vkey: 'VK_D', + value: 'd', + withShift: 'D', + withAltGr: '', + withShiftAltGr: '' + }, + KeyE: { + vkey: 'VK_E', + value: 'e', + withShift: 'E', + withAltGr: '€', + withShiftAltGr: '' + }, + KeyF: { + vkey: 'VK_F', + value: 'f', + withShift: 'F', + withAltGr: '', + withShiftAltGr: '' + }, + KeyG: { + vkey: 'VK_G', + value: 'g', + withShift: 'G', + withAltGr: '', + withShiftAltGr: '' + }, + KeyH: { + vkey: 'VK_H', + value: 'h', + withShift: 'H', + withAltGr: '', + withShiftAltGr: '' + }, + KeyI: { + vkey: 'VK_I', + value: 'i', + withShift: 'I', + withAltGr: '', + withShiftAltGr: '' + }, + KeyJ: { + vkey: 'VK_J', + value: 'j', + withShift: 'J', + withAltGr: '', + withShiftAltGr: '' + }, + KeyK: { + vkey: 'VK_K', + value: 'k', + withShift: 'K', + withAltGr: '', + withShiftAltGr: '' + }, + KeyL: { + vkey: 'VK_L', + value: 'l', + withShift: 'L', + withAltGr: '', + withShiftAltGr: '' + }, + KeyM: { + vkey: 'VK_M', + value: 'm', + withShift: 'M', + withAltGr: '', + withShiftAltGr: '' + }, + KeyN: { + vkey: 'VK_N', + value: 'n', + withShift: 'N', + withAltGr: '', + withShiftAltGr: '' + }, + KeyO: { + vkey: 'VK_O', + value: 'o', + withShift: 'O', + withAltGr: '', + withShiftAltGr: '' + }, + KeyP: { + vkey: 'VK_P', + value: 'p', + withShift: 'P', + withAltGr: '', + withShiftAltGr: '' + }, + KeyQ: { + vkey: 'VK_Q', + value: 'q', + withShift: 'Q', + withAltGr: '', + withShiftAltGr: '' + }, + KeyR: { + vkey: 'VK_R', + value: 'r', + withShift: 'R', + withAltGr: '', + withShiftAltGr: '' + }, + KeyS: { + vkey: 'VK_S', + value: 's', + withShift: 'S', + withAltGr: '', + withShiftAltGr: '' + }, + KeyT: { + vkey: 'VK_T', + value: 't', + withShift: 'T', + withAltGr: '', + withShiftAltGr: '' + }, + KeyU: { + vkey: 'VK_U', + value: 'u', + withShift: 'U', + withAltGr: '', + withShiftAltGr: '' + }, + KeyV: { + vkey: 'VK_V', + value: 'v', + withShift: 'V', + withAltGr: '', + withShiftAltGr: '' + }, + KeyW: { + vkey: 'VK_W', + value: 'w', + withShift: 'W', + withAltGr: '', + withShiftAltGr: '' + }, + KeyX: { + vkey: 'VK_X', + value: 'x', + withShift: 'X', + withAltGr: '', + withShiftAltGr: '' + }, + KeyY: { + vkey: 'VK_Z', + value: 'z', + withShift: 'Z', + withAltGr: '', + withShiftAltGr: '' + }, + KeyZ: { + vkey: 'VK_Y', + value: 'y', + withShift: 'Y', + withAltGr: '', + withShiftAltGr: '' + }, + Digit1: { + vkey: 'VK_1', + value: '1', + withShift: '+', + withAltGr: '¦', + withShiftAltGr: '' + }, + Digit2: { + vkey: 'VK_2', + value: '2', + withShift: '"', + withAltGr: '@', + withShiftAltGr: '' + }, + Digit3: { + vkey: 'VK_3', + value: '3', + withShift: '*', + withAltGr: '#', + withShiftAltGr: '' + }, + Digit4: { + vkey: 'VK_4', + value: '4', + withShift: 'ç', + withAltGr: '°', + withShiftAltGr: '' + }, + Digit5: { + vkey: 'VK_5', + value: '5', + withShift: '%', + withAltGr: '§', + withShiftAltGr: '' + }, + Digit6: { + vkey: 'VK_6', + value: '6', + withShift: '&', + withAltGr: '¬', + withShiftAltGr: '' + }, + Digit7: { + vkey: 'VK_7', + value: '7', + withShift: '/', + withAltGr: '|', + withShiftAltGr: '' + }, + Digit8: { + vkey: 'VK_8', + value: '8', + withShift: '(', + withAltGr: '¢', + withShiftAltGr: '' + }, + Digit9: { + vkey: 'VK_9', + value: '9', + withShift: ')', + withAltGr: '', + withShiftAltGr: '' + }, + Digit0: { + vkey: 'VK_0', + value: '0', + withShift: '=', + withAltGr: '', + withShiftAltGr: '' + }, + Enter: { + vkey: 'VK_RETURN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Escape: { + vkey: 'VK_ESCAPE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Backspace: { + vkey: 'VK_BACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Tab: { + vkey: 'VK_TAB', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Space: { + vkey: 'VK_SPACE', + value: ' ', + withShift: ' ', + withAltGr: '', + withShiftAltGr: '' + }, + Minus: { + vkey: 'VK_OEM_4', + value: '\'', + withShift: '?', + withAltGr: '´', + withShiftAltGr: '' + }, + Equal: { + vkey: 'VK_OEM_6', + value: '^', + withShift: '`', + withAltGr: '~', + withShiftAltGr: '' + }, + BracketLeft: { + vkey: 'VK_OEM_1', + value: 'ü', + withShift: 'è', + withAltGr: '[', + withShiftAltGr: '' + }, + BracketRight: { + vkey: 'VK_OEM_3', + value: '¨', + withShift: '!', + withAltGr: ']', + withShiftAltGr: '' + }, + Backslash: { + vkey: 'VK_OEM_8', + value: '$', + withShift: '£', + withAltGr: '}', + withShiftAltGr: '' + }, + Semicolon: { + vkey: 'VK_OEM_7', + value: 'ö', + withShift: 'é', + withAltGr: '', + withShiftAltGr: '' + }, + Quote: { + vkey: 'VK_OEM_5', + value: 'ä', + withShift: 'à', + withAltGr: '{', + withShiftAltGr: '' + }, + Backquote: { + vkey: 'VK_OEM_2', + value: '§', + withShift: '°', + withAltGr: '', + withShiftAltGr: '' + }, + Comma: { + vkey: 'VK_OEM_COMMA', + value: ',', + withShift: ';', + withAltGr: '', + withShiftAltGr: '' + }, + Period: { + vkey: 'VK_OEM_PERIOD', + value: '.', + withShift: ':', + withAltGr: '', + withShiftAltGr: '' + }, + Slash: { + vkey: 'VK_OEM_MINUS', + value: '-', + withShift: '_', + withAltGr: '', + withShiftAltGr: '' + }, + CapsLock: { + vkey: 'VK_CAPITAL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F1: { + vkey: 'VK_F1', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F2: { + vkey: 'VK_F2', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F3: { + vkey: 'VK_F3', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F4: { + vkey: 'VK_F4', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F5: { + vkey: 'VK_F5', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F6: { + vkey: 'VK_F6', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F7: { + vkey: 'VK_F7', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F8: { + vkey: 'VK_F8', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F9: { + vkey: 'VK_F9', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F10: { + vkey: 'VK_F10', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F11: { + vkey: 'VK_F11', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F12: { + vkey: 'VK_F12', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PrintScreen: { + vkey: 'VK_SNAPSHOT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ScrollLock: { + vkey: 'VK_SCROLL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Pause: { + vkey: 'VK_NUMLOCK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Insert: { + vkey: 'VK_INSERT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Home: { + vkey: 'VK_HOME', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PageUp: { + vkey: 'VK_PRIOR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Delete: { + vkey: 'VK_DELETE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + End: { + vkey: 'VK_END', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PageDown: { + vkey: 'VK_NEXT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowRight: { + vkey: 'VK_RIGHT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowLeft: { + vkey: 'VK_LEFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowDown: { + vkey: 'VK_DOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowUp: { + vkey: 'VK_UP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumLock: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadDivide: { + vkey: 'VK_DIVIDE', + value: '/', + withShift: '/', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadMultiply: { + vkey: 'VK_MULTIPLY', + value: '*', + withShift: '*', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadSubtract: { + vkey: 'VK_SUBTRACT', + value: '-', + withShift: '-', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadAdd: { + vkey: 'VK_ADD', + value: '+', + withShift: '+', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadEnter: { + vkey: 'VK_RETURN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad1: { + vkey: 'VK_END', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad2: { + vkey: 'VK_DOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad3: { + vkey: 'VK_NEXT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad4: { + vkey: 'VK_LEFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad5: { + vkey: 'VK_CLEAR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad6: { + vkey: 'VK_RIGHT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad7: { + vkey: 'VK_HOME', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad8: { + vkey: 'VK_UP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad9: { + vkey: 'VK_PRIOR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad0: { + vkey: 'VK_INSERT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadDecimal: { + vkey: 'VK_DELETE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + IntlBackslash: { + vkey: 'VK_OEM_102', + value: '<', + withShift: '>', + withAltGr: '\\', + withShiftAltGr: '' + }, + ContextMenu: { + vkey: 'VK_APPS', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Power: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadEqual: { + vkey: 'VK_CLEAR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F13: { + vkey: 'VK_F13', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F14: { + vkey: 'VK_F14', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F15: { + vkey: 'VK_F15', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F16: { + vkey: 'VK_F16', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F17: { + vkey: 'VK_F17', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F18: { + vkey: 'VK_F18', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F19: { + vkey: 'VK_F19', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F20: { + vkey: 'VK_F20', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F21: { + vkey: 'VK_F21', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F22: { + vkey: 'VK_F22', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F23: { + vkey: 'VK_F23', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F24: { + vkey: 'VK_F24', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Help: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Undo: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Cut: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Copy: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Paste: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeMute: { + vkey: 'VK_VOLUME_MUTE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeUp: { + vkey: 'VK_VOLUME_UP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeDown: { + vkey: 'VK_VOLUME_DOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadComma: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + IntlRo: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + KanaMode: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + IntlYen: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Convert: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NonConvert: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang1: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang2: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang3: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang4: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ControlLeft: { + vkey: 'VK_CONTROL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ShiftLeft: { + vkey: 'VK_SHIFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AltLeft: { + vkey: 'VK_MENU', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MetaLeft: { + vkey: 'VK_LWIN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ControlRight: { + vkey: 'VK_CONTROL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ShiftRight: { + vkey: 'VK_SHIFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AltRight: { + vkey: 'VK_MENU', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MetaRight: { + vkey: 'VK_RWIN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaTrackNext: { + vkey: 'VK_MEDIA_NEXT_TRACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaTrackPrevious: { + vkey: 'VK_MEDIA_PREV_TRACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaStop: { + vkey: 'VK_MEDIA_STOP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Eject: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaPlayPause: { + vkey: 'VK_MEDIA_PLAY_PAUSE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaSelect: { + vkey: 'VK_LAUNCH_MEDIA_SELECT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchMail: { + vkey: 'VK_LAUNCH_MAIL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchApp2: { + vkey: 'VK_LAUNCH_APP2', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchApp1: { + vkey: 'VK_LAUNCH_APP1', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserSearch: { + vkey: 'VK_BROWSER_SEARCH', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserHome: { + vkey: 'VK_BROWSER_HOME', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserBack: { + vkey: 'VK_BROWSER_BACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserForward: { + vkey: 'VK_BROWSER_FORWARD', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserStop: { + vkey: 'VK_BROWSER_STOP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserRefresh: { + vkey: 'VK_BROWSER_REFRESH', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserFavorites: { + vkey: 'VK_BROWSER_FAVORITES', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + } +}); diff --git a/src/vs/workbench/services/keybinding/test/node/win_de_ch.txt b/src/vs/workbench/services/keybinding/test/node/win_de_ch.txt new file mode 100644 index 00000000000..ac0575e250e --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/win_de_ch.txt @@ -0,0 +1,284 @@ +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyA | a | A | A | a | | +| Shift+KeyA | A | Shift+A | Shift+A | shift+a | | +| Ctrl+Alt+KeyA | --- | Ctrl+Alt+A | Ctrl+Alt+A | ctrl+alt+a | | +| Ctrl+Shift+Alt+KeyA | --- | Ctrl+Shift+Alt+A | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyB | b | B | B | b | | +| Shift+KeyB | B | Shift+B | Shift+B | shift+b | | +| Ctrl+Alt+KeyB | --- | Ctrl+Alt+B | Ctrl+Alt+B | ctrl+alt+b | | +| Ctrl+Shift+Alt+KeyB | --- | Ctrl+Shift+Alt+B | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyC | c | C | C | c | | +| Shift+KeyC | C | Shift+C | Shift+C | shift+c | | +| Ctrl+Alt+KeyC | --- | Ctrl+Alt+C | Ctrl+Alt+C | ctrl+alt+c | | +| Ctrl+Shift+Alt+KeyC | --- | Ctrl+Shift+Alt+C | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyD | d | D | D | d | | +| Shift+KeyD | D | Shift+D | Shift+D | shift+d | | +| Ctrl+Alt+KeyD | --- | Ctrl+Alt+D | Ctrl+Alt+D | ctrl+alt+d | | +| Ctrl+Shift+Alt+KeyD | --- | Ctrl+Shift+Alt+D | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyE | e | E | E | e | | +| Shift+KeyE | E | Shift+E | Shift+E | shift+e | | +| Ctrl+Alt+KeyE | € | Ctrl+Alt+E | Ctrl+Alt+E | ctrl+alt+e | | +| Ctrl+Shift+Alt+KeyE | --- | Ctrl+Shift+Alt+E | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyF | f | F | F | f | | +| Shift+KeyF | F | Shift+F | Shift+F | shift+f | | +| Ctrl+Alt+KeyF | --- | Ctrl+Alt+F | Ctrl+Alt+F | ctrl+alt+f | | +| Ctrl+Shift+Alt+KeyF | --- | Ctrl+Shift+Alt+F | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyG | g | G | G | g | | +| Shift+KeyG | G | Shift+G | Shift+G | shift+g | | +| Ctrl+Alt+KeyG | --- | Ctrl+Alt+G | Ctrl+Alt+G | ctrl+alt+g | | +| Ctrl+Shift+Alt+KeyG | --- | Ctrl+Shift+Alt+G | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyH | h | H | H | h | | +| Shift+KeyH | H | Shift+H | Shift+H | shift+h | | +| Ctrl+Alt+KeyH | --- | Ctrl+Alt+H | Ctrl+Alt+H | ctrl+alt+h | | +| Ctrl+Shift+Alt+KeyH | --- | Ctrl+Shift+Alt+H | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyI | i | I | I | i | | +| Shift+KeyI | I | Shift+I | Shift+I | shift+i | | +| Ctrl+Alt+KeyI | --- | Ctrl+Alt+I | Ctrl+Alt+I | ctrl+alt+i | | +| Ctrl+Shift+Alt+KeyI | --- | Ctrl+Shift+Alt+I | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyJ | j | J | J | j | | +| Shift+KeyJ | J | Shift+J | Shift+J | shift+j | | +| Ctrl+Alt+KeyJ | --- | Ctrl+Alt+J | Ctrl+Alt+J | ctrl+alt+j | | +| Ctrl+Shift+Alt+KeyJ | --- | Ctrl+Shift+Alt+J | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyK | k | K | K | k | | +| Shift+KeyK | K | Shift+K | Shift+K | shift+k | | +| Ctrl+Alt+KeyK | --- | Ctrl+Alt+K | Ctrl+Alt+K | ctrl+alt+k | | +| Ctrl+Shift+Alt+KeyK | --- | Ctrl+Shift+Alt+K | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyL | l | L | L | l | | +| Shift+KeyL | L | Shift+L | Shift+L | shift+l | | +| Ctrl+Alt+KeyL | --- | Ctrl+Alt+L | Ctrl+Alt+L | ctrl+alt+l | | +| Ctrl+Shift+Alt+KeyL | --- | Ctrl+Shift+Alt+L | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyM | m | M | M | m | | +| Shift+KeyM | M | Shift+M | Shift+M | shift+m | | +| Ctrl+Alt+KeyM | --- | Ctrl+Alt+M | Ctrl+Alt+M | ctrl+alt+m | | +| Ctrl+Shift+Alt+KeyM | --- | Ctrl+Shift+Alt+M | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyN | n | N | N | n | | +| Shift+KeyN | N | Shift+N | Shift+N | shift+n | | +| Ctrl+Alt+KeyN | --- | Ctrl+Alt+N | Ctrl+Alt+N | ctrl+alt+n | | +| Ctrl+Shift+Alt+KeyN | --- | Ctrl+Shift+Alt+N | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyO | o | O | O | o | | +| Shift+KeyO | O | Shift+O | Shift+O | shift+o | | +| Ctrl+Alt+KeyO | --- | Ctrl+Alt+O | Ctrl+Alt+O | ctrl+alt+o | | +| Ctrl+Shift+Alt+KeyO | --- | Ctrl+Shift+Alt+O | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyP | p | P | P | p | | +| Shift+KeyP | P | Shift+P | Shift+P | shift+p | | +| Ctrl+Alt+KeyP | --- | Ctrl+Alt+P | Ctrl+Alt+P | ctrl+alt+p | | +| Ctrl+Shift+Alt+KeyP | --- | Ctrl+Shift+Alt+P | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyQ | q | Q | Q | q | | +| Shift+KeyQ | Q | Shift+Q | Shift+Q | shift+q | | +| Ctrl+Alt+KeyQ | --- | Ctrl+Alt+Q | Ctrl+Alt+Q | ctrl+alt+q | | +| Ctrl+Shift+Alt+KeyQ | --- | Ctrl+Shift+Alt+Q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyR | r | R | R | r | | +| Shift+KeyR | R | Shift+R | Shift+R | shift+r | | +| Ctrl+Alt+KeyR | --- | Ctrl+Alt+R | Ctrl+Alt+R | ctrl+alt+r | | +| Ctrl+Shift+Alt+KeyR | --- | Ctrl+Shift+Alt+R | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyS | s | S | S | s | | +| Shift+KeyS | S | Shift+S | Shift+S | shift+s | | +| Ctrl+Alt+KeyS | --- | Ctrl+Alt+S | Ctrl+Alt+S | ctrl+alt+s | | +| Ctrl+Shift+Alt+KeyS | --- | Ctrl+Shift+Alt+S | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyT | t | T | T | t | | +| Shift+KeyT | T | Shift+T | Shift+T | shift+t | | +| Ctrl+Alt+KeyT | --- | Ctrl+Alt+T | Ctrl+Alt+T | ctrl+alt+t | | +| Ctrl+Shift+Alt+KeyT | --- | Ctrl+Shift+Alt+T | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyU | u | U | U | u | | +| Shift+KeyU | U | Shift+U | Shift+U | shift+u | | +| Ctrl+Alt+KeyU | --- | Ctrl+Alt+U | Ctrl+Alt+U | ctrl+alt+u | | +| Ctrl+Shift+Alt+KeyU | --- | Ctrl+Shift+Alt+U | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyV | v | V | V | v | | +| Shift+KeyV | V | Shift+V | Shift+V | shift+v | | +| Ctrl+Alt+KeyV | --- | Ctrl+Alt+V | Ctrl+Alt+V | ctrl+alt+v | | +| Ctrl+Shift+Alt+KeyV | --- | Ctrl+Shift+Alt+V | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyW | w | W | W | w | | +| Shift+KeyW | W | Shift+W | Shift+W | shift+w | | +| Ctrl+Alt+KeyW | --- | Ctrl+Alt+W | Ctrl+Alt+W | ctrl+alt+w | | +| Ctrl+Shift+Alt+KeyW | --- | Ctrl+Shift+Alt+W | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyX | x | X | X | x | | +| Shift+KeyX | X | Shift+X | Shift+X | shift+x | | +| Ctrl+Alt+KeyX | --- | Ctrl+Alt+X | Ctrl+Alt+X | ctrl+alt+x | | +| Ctrl+Shift+Alt+KeyX | --- | Ctrl+Shift+Alt+X | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyY | z | Z | Z | z | | +| Shift+KeyY | Z | Shift+Z | Shift+Z | shift+z | | +| Ctrl+Alt+KeyY | --- | Ctrl+Alt+Z | Ctrl+Alt+Z | ctrl+alt+z | | +| Ctrl+Shift+Alt+KeyY | --- | Ctrl+Shift+Alt+Z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyZ | y | Y | Y | y | | +| Shift+KeyZ | Y | Shift+Y | Shift+Y | shift+y | | +| Ctrl+Alt+KeyZ | --- | Ctrl+Alt+Y | Ctrl+Alt+Y | ctrl+alt+y | | +| Ctrl+Shift+Alt+KeyZ | --- | Ctrl+Shift+Alt+Y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit1 | 1 | 1 | 1 | 1 | | +| Shift+Digit1 | + | Shift+1 | Shift+1 | shift+1 | | +| Ctrl+Alt+Digit1 | ¦ | Ctrl+Alt+1 | Ctrl+Alt+1 | ctrl+alt+1 | | +| Ctrl+Shift+Alt+Digit1 | --- | Ctrl+Shift+Alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit2 | 2 | 2 | 2 | 2 | | +| Shift+Digit2 | " | Shift+2 | Shift+2 | shift+2 | | +| Ctrl+Alt+Digit2 | @ | Ctrl+Alt+2 | Ctrl+Alt+2 | ctrl+alt+2 | | +| Ctrl+Shift+Alt+Digit2 | --- | Ctrl+Shift+Alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit3 | 3 | 3 | 3 | 3 | | +| Shift+Digit3 | * | Shift+3 | Shift+3 | shift+3 | | +| Ctrl+Alt+Digit3 | # | Ctrl+Alt+3 | Ctrl+Alt+3 | ctrl+alt+3 | | +| Ctrl+Shift+Alt+Digit3 | --- | Ctrl+Shift+Alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit4 | 4 | 4 | 4 | 4 | | +| Shift+Digit4 | ç | Shift+4 | Shift+4 | shift+4 | | +| Ctrl+Alt+Digit4 | ° | Ctrl+Alt+4 | Ctrl+Alt+4 | ctrl+alt+4 | | +| Ctrl+Shift+Alt+Digit4 | --- | Ctrl+Shift+Alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit5 | 5 | 5 | 5 | 5 | | +| Shift+Digit5 | % | Shift+5 | Shift+5 | shift+5 | | +| Ctrl+Alt+Digit5 | § | Ctrl+Alt+5 | Ctrl+Alt+5 | ctrl+alt+5 | | +| Ctrl+Shift+Alt+Digit5 | --- | Ctrl+Shift+Alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit6 | 6 | 6 | 6 | 6 | | +| Shift+Digit6 | & | Shift+6 | Shift+6 | shift+6 | | +| Ctrl+Alt+Digit6 | ¬ | Ctrl+Alt+6 | Ctrl+Alt+6 | ctrl+alt+6 | | +| Ctrl+Shift+Alt+Digit6 | --- | Ctrl+Shift+Alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit7 | 7 | 7 | 7 | 7 | | +| Shift+Digit7 | / | Shift+7 | Shift+7 | shift+7 | | +| Ctrl+Alt+Digit7 | | | Ctrl+Alt+7 | Ctrl+Alt+7 | ctrl+alt+7 | | +| Ctrl+Shift+Alt+Digit7 | --- | Ctrl+Shift+Alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit8 | 8 | 8 | 8 | 8 | | +| Shift+Digit8 | ( | Shift+8 | Shift+8 | shift+8 | | +| Ctrl+Alt+Digit8 | ¢ | Ctrl+Alt+8 | Ctrl+Alt+8 | ctrl+alt+8 | | +| Ctrl+Shift+Alt+Digit8 | --- | Ctrl+Shift+Alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit9 | 9 | 9 | 9 | 9 | | +| Shift+Digit9 | ) | Shift+9 | Shift+9 | shift+9 | | +| Ctrl+Alt+Digit9 | --- | Ctrl+Alt+9 | Ctrl+Alt+9 | ctrl+alt+9 | | +| Ctrl+Shift+Alt+Digit9 | --- | Ctrl+Shift+Alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit0 | 0 | 0 | 0 | 0 | | +| Shift+Digit0 | = | Shift+0 | Shift+0 | shift+0 | | +| Ctrl+Alt+Digit0 | --- | Ctrl+Alt+0 | Ctrl+Alt+0 | ctrl+alt+0 | | +| Ctrl+Shift+Alt+Digit0 | --- | Ctrl+Shift+Alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| Minus | ' | [ | ' | oem_4 | NO | +| Shift+Minus | ? | Shift+[ | Shift+' | shift+oem_4 | NO | +| Ctrl+Alt+Minus | ´ | Ctrl+Alt+[ | Ctrl+Alt+' | ctrl+alt+oem_4 | NO | +| Ctrl+Shift+Alt+Minus | --- | Ctrl+Shift+Alt+[ | Ctrl+Shift+Alt+' | ctrl+shift+alt+oem_4 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Equal | ^ | ] | ^ | oem_6 | NO | +| Shift+Equal | ` | Shift+] | Shift+^ | shift+oem_6 | NO | +| Ctrl+Alt+Equal | ~ | Ctrl+Alt+] | Ctrl+Alt+^ | ctrl+alt+oem_6 | NO | +| Ctrl+Shift+Alt+Equal | --- | Ctrl+Shift+Alt+] | Ctrl+Shift+Alt+^ | ctrl+shift+alt+oem_6 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| BracketLeft | ü | ; | ü | oem_1 | NO | +| Shift+BracketLeft | è | Shift+; | Shift+ü | shift+oem_1 | NO | +| Ctrl+Alt+BracketLeft | [ | Ctrl+Alt+; | Ctrl+Alt+ü | ctrl+alt+oem_1 | NO | +| Ctrl+Shift+Alt+BracketLeft | --- | Ctrl+Shift+Alt+; | Ctrl+Shift+Alt+ü | ctrl+shift+alt+oem_1 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| BracketRight | ¨ | ` | ¨ | oem_3 | NO | +| Shift+BracketRight | ! | Shift+` | Shift+¨ | shift+oem_3 | NO | +| Ctrl+Alt+BracketRight | ] | Ctrl+Alt+` | Ctrl+Alt+¨ | ctrl+alt+oem_3 | NO | +| Ctrl+Shift+Alt+BracketRight | --- | Ctrl+Shift+Alt+` | Ctrl+Shift+Alt+¨ | ctrl+shift+alt+oem_3 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Backslash | $ | OEM_8 | $ | oem_8 | NO | +| Shift+Backslash | £ | Shift+OEM_8 | Shift+$ | shift+oem_8 | NO | +| Ctrl+Alt+Backslash | } | Ctrl+Alt+OEM_8 | Ctrl+Alt+$ | ctrl+alt+oem_8 | NO | +| Ctrl+Shift+Alt+Backslash | --- | Ctrl+Shift+Alt+OEM_8 | Ctrl+Shift+Alt+$ | ctrl+shift+alt+oem_8 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlHash | --- | null | null | null | NO | +| Shift+IntlHash | --- | null | null | null | NO | +| Ctrl+Alt+IntlHash | --- | null | null | null | NO | +| Ctrl+Shift+Alt+IntlHash | --- | null | null | null | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| Semicolon | ö | ' | ö | oem_7 | NO | +| Shift+Semicolon | é | Shift+' | Shift+ö | shift+oem_7 | NO | +| Ctrl+Alt+Semicolon | --- | Ctrl+Alt+' | Ctrl+Alt+ö | ctrl+alt+oem_7 | NO | +| Ctrl+Shift+Alt+Semicolon | --- | Ctrl+Shift+Alt+' | Ctrl+Shift+Alt+ö | ctrl+shift+alt+oem_7 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Quote | ä | \ | ä | oem_5 | NO | +| Shift+Quote | à | Shift+\ | Shift+ä | shift+oem_5 | NO | +| Ctrl+Alt+Quote | { | Ctrl+Alt+\ | Ctrl+Alt+ä | ctrl+alt+oem_5 | NO | +| Ctrl+Shift+Alt+Quote | --- | Ctrl+Shift+Alt+\ | Ctrl+Shift+Alt+ä | ctrl+shift+alt+oem_5 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Backquote | § | / | § | oem_2 | NO | +| Shift+Backquote | ° | Shift+/ | Shift+§ | shift+oem_2 | NO | +| Ctrl+Alt+Backquote | --- | Ctrl+Alt+/ | Ctrl+Alt+§ | ctrl+alt+oem_2 | NO | +| Ctrl+Shift+Alt+Backquote | --- | Ctrl+Shift+Alt+/ | Ctrl+Shift+Alt+§ | ctrl+shift+alt+oem_2 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Comma | , | , | , | oem_comma | NO | +| Shift+Comma | ; | Shift+, | Shift+, | shift+oem_comma | NO | +| Ctrl+Alt+Comma | --- | Ctrl+Alt+, | Ctrl+Alt+, | ctrl+alt+oem_comma | NO | +| Ctrl+Shift+Alt+Comma | --- | Ctrl+Shift+Alt+, | Ctrl+Shift+Alt+, | ctrl+shift+alt+oem_comma | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Period | . | . | . | oem_period | NO | +| Shift+Period | : | Shift+. | Shift+. | shift+oem_period | NO | +| Ctrl+Alt+Period | --- | Ctrl+Alt+. | Ctrl+Alt+. | ctrl+alt+oem_period | NO | +| Ctrl+Shift+Alt+Period | --- | Ctrl+Shift+Alt+. | Ctrl+Shift+Alt+. | ctrl+shift+alt+oem_period | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Slash | - | - | - | oem_minus | NO | +| Shift+Slash | _ | Shift+- | Shift+- | shift+oem_minus | NO | +| Ctrl+Alt+Slash | --- | Ctrl+Alt+- | Ctrl+Alt+- | ctrl+alt+oem_minus | NO | +| Ctrl+Shift+Alt+Slash | --- | Ctrl+Shift+Alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+oem_minus | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| ArrowUp | --- | UpArrow | UpArrow | up | | +| Shift+ArrowUp | --- | Shift+UpArrow | Shift+UpArrow | shift+up | | +| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | Ctrl+Alt+UpArrow | ctrl+alt+up | | +| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Numpad0 | --- | NumPad0 | NumPad0 | numpad0 | | +| Shift+Numpad0 | --- | Shift+NumPad0 | Shift+NumPad0 | shift+numpad0 | | +| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | | +| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlBackslash | < | OEM_102 | < | oem_102 | NO | +| Shift+IntlBackslash | > | Shift+OEM_102 | Shift+< | shift+oem_102 | NO | +| Ctrl+Alt+IntlBackslash | \ | Ctrl+Alt+OEM_102 | Ctrl+Alt+< | ctrl+alt+oem_102 | NO | +| Ctrl+Shift+Alt+IntlBackslash | --- | Ctrl+Shift+Alt+OEM_102 | Ctrl+Shift+Alt+< | ctrl+shift+alt+oem_102 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlRo | --- | null | null | null | NO | +| Shift+IntlRo | --- | null | null | null | NO | +| Ctrl+Alt+IntlRo | --- | null | null | null | NO | +| Ctrl+Shift+Alt+IntlRo | --- | null | null | null | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlYen | --- | null | null | null | NO | +| Shift+IntlYen | --- | null | null | null | NO | +| Ctrl+Alt+IntlYen | --- | null | null | null | NO | +| Ctrl+Shift+Alt+IntlYen | --- | null | null | null | NO | +----------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/node/win_en_us.js b/src/vs/workbench/services/keybinding/test/node/win_en_us.js new file mode 100644 index 00000000000..6961ed286fe --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/win_en_us.js @@ -0,0 +1,1093 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +define({ + Sleep: { + vkey: 'VK_SLEEP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + WakeUp: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + KeyA: { + vkey: 'VK_A', + value: 'a', + withShift: 'A', + withAltGr: '', + withShiftAltGr: '' + }, + KeyB: { + vkey: 'VK_B', + value: 'b', + withShift: 'B', + withAltGr: '', + withShiftAltGr: '' + }, + KeyC: { + vkey: 'VK_C', + value: 'c', + withShift: 'C', + withAltGr: '', + withShiftAltGr: '' + }, + KeyD: { + vkey: 'VK_D', + value: 'd', + withShift: 'D', + withAltGr: '', + withShiftAltGr: '' + }, + KeyE: { + vkey: 'VK_E', + value: 'e', + withShift: 'E', + withAltGr: '', + withShiftAltGr: '' + }, + KeyF: { + vkey: 'VK_F', + value: 'f', + withShift: 'F', + withAltGr: '', + withShiftAltGr: '' + }, + KeyG: { + vkey: 'VK_G', + value: 'g', + withShift: 'G', + withAltGr: '', + withShiftAltGr: '' + }, + KeyH: { + vkey: 'VK_H', + value: 'h', + withShift: 'H', + withAltGr: '', + withShiftAltGr: '' + }, + KeyI: { + vkey: 'VK_I', + value: 'i', + withShift: 'I', + withAltGr: '', + withShiftAltGr: '' + }, + KeyJ: { + vkey: 'VK_J', + value: 'j', + withShift: 'J', + withAltGr: '', + withShiftAltGr: '' + }, + KeyK: { + vkey: 'VK_K', + value: 'k', + withShift: 'K', + withAltGr: '', + withShiftAltGr: '' + }, + KeyL: { + vkey: 'VK_L', + value: 'l', + withShift: 'L', + withAltGr: '', + withShiftAltGr: '' + }, + KeyM: { + vkey: 'VK_M', + value: 'm', + withShift: 'M', + withAltGr: '', + withShiftAltGr: '' + }, + KeyN: { + vkey: 'VK_N', + value: 'n', + withShift: 'N', + withAltGr: '', + withShiftAltGr: '' + }, + KeyO: { + vkey: 'VK_O', + value: 'o', + withShift: 'O', + withAltGr: '', + withShiftAltGr: '' + }, + KeyP: { + vkey: 'VK_P', + value: 'p', + withShift: 'P', + withAltGr: '', + withShiftAltGr: '' + }, + KeyQ: { + vkey: 'VK_Q', + value: 'q', + withShift: 'Q', + withAltGr: '', + withShiftAltGr: '' + }, + KeyR: { + vkey: 'VK_R', + value: 'r', + withShift: 'R', + withAltGr: '', + withShiftAltGr: '' + }, + KeyS: { + vkey: 'VK_S', + value: 's', + withShift: 'S', + withAltGr: '', + withShiftAltGr: '' + }, + KeyT: { + vkey: 'VK_T', + value: 't', + withShift: 'T', + withAltGr: '', + withShiftAltGr: '' + }, + KeyU: { + vkey: 'VK_U', + value: 'u', + withShift: 'U', + withAltGr: '', + withShiftAltGr: '' + }, + KeyV: { + vkey: 'VK_V', + value: 'v', + withShift: 'V', + withAltGr: '', + withShiftAltGr: '' + }, + KeyW: { + vkey: 'VK_W', + value: 'w', + withShift: 'W', + withAltGr: '', + withShiftAltGr: '' + }, + KeyX: { + vkey: 'VK_X', + value: 'x', + withShift: 'X', + withAltGr: '', + withShiftAltGr: '' + }, + KeyY: { + vkey: 'VK_Y', + value: 'y', + withShift: 'Y', + withAltGr: '', + withShiftAltGr: '' + }, + KeyZ: { + vkey: 'VK_Z', + value: 'z', + withShift: 'Z', + withAltGr: '', + withShiftAltGr: '' + }, + Digit1: { + vkey: 'VK_1', + value: '1', + withShift: '!', + withAltGr: '', + withShiftAltGr: '' + }, + Digit2: { + vkey: 'VK_2', + value: '2', + withShift: '@', + withAltGr: '', + withShiftAltGr: '' + }, + Digit3: { + vkey: 'VK_3', + value: '3', + withShift: '#', + withAltGr: '', + withShiftAltGr: '' + }, + Digit4: { + vkey: 'VK_4', + value: '4', + withShift: '$', + withAltGr: '', + withShiftAltGr: '' + }, + Digit5: { + vkey: 'VK_5', + value: '5', + withShift: '%', + withAltGr: '', + withShiftAltGr: '' + }, + Digit6: { + vkey: 'VK_6', + value: '6', + withShift: '^', + withAltGr: '', + withShiftAltGr: '' + }, + Digit7: { + vkey: 'VK_7', + value: '7', + withShift: '&', + withAltGr: '', + withShiftAltGr: '' + }, + Digit8: { + vkey: 'VK_8', + value: '8', + withShift: '*', + withAltGr: '', + withShiftAltGr: '' + }, + Digit9: { + vkey: 'VK_9', + value: '9', + withShift: '(', + withAltGr: '', + withShiftAltGr: '' + }, + Digit0: { + vkey: 'VK_0', + value: '0', + withShift: ')', + withAltGr: '', + withShiftAltGr: '' + }, + Enter: { + vkey: 'VK_RETURN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Escape: { + vkey: 'VK_ESCAPE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Backspace: { + vkey: 'VK_BACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Tab: { + vkey: 'VK_TAB', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Space: { + vkey: 'VK_SPACE', + value: ' ', + withShift: ' ', + withAltGr: '', + withShiftAltGr: '' + }, + Minus: { + vkey: 'VK_OEM_MINUS', + value: '-', + withShift: '_', + withAltGr: '', + withShiftAltGr: '' + }, + Equal: { + vkey: 'VK_OEM_PLUS', + value: '=', + withShift: '+', + withAltGr: '', + withShiftAltGr: '' + }, + BracketLeft: { + vkey: 'VK_OEM_4', + value: '[', + withShift: '{', + withAltGr: '', + withShiftAltGr: '' + }, + BracketRight: { + vkey: 'VK_OEM_6', + value: ']', + withShift: '}', + withAltGr: '', + withShiftAltGr: '' + }, + Backslash: { + vkey: 'VK_OEM_5', + value: '\\', + withShift: '|', + withAltGr: '', + withShiftAltGr: '' + }, + Semicolon: { + vkey: 'VK_OEM_1', + value: ';', + withShift: ':', + withAltGr: '', + withShiftAltGr: '' + }, + Quote: { + vkey: 'VK_OEM_7', + value: '\'', + withShift: '"', + withAltGr: '', + withShiftAltGr: '' + }, + Backquote: { + vkey: 'VK_OEM_3', + value: '`', + withShift: '~', + withAltGr: '', + withShiftAltGr: '' + }, + Comma: { + vkey: 'VK_OEM_COMMA', + value: ',', + withShift: '<', + withAltGr: '', + withShiftAltGr: '' + }, + Period: { + vkey: 'VK_OEM_PERIOD', + value: '.', + withShift: '>', + withAltGr: '', + withShiftAltGr: '' + }, + Slash: { + vkey: 'VK_OEM_2', + value: '/', + withShift: '?', + withAltGr: '', + withShiftAltGr: '' + }, + CapsLock: { + vkey: 'VK_CAPITAL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F1: { + vkey: 'VK_F1', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F2: { + vkey: 'VK_F2', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F3: { + vkey: 'VK_F3', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F4: { + vkey: 'VK_F4', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F5: { + vkey: 'VK_F5', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F6: { + vkey: 'VK_F6', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F7: { + vkey: 'VK_F7', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F8: { + vkey: 'VK_F8', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F9: { + vkey: 'VK_F9', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F10: { + vkey: 'VK_F10', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F11: { + vkey: 'VK_F11', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F12: { + vkey: 'VK_F12', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PrintScreen: { + vkey: 'VK_SNAPSHOT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ScrollLock: { + vkey: 'VK_SCROLL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Pause: { + vkey: 'VK_NUMLOCK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Insert: { + vkey: 'VK_INSERT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Home: { + vkey: 'VK_HOME', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PageUp: { + vkey: 'VK_PRIOR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Delete: { + vkey: 'VK_DELETE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + End: { + vkey: 'VK_END', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PageDown: { + vkey: 'VK_NEXT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowRight: { + vkey: 'VK_RIGHT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowLeft: { + vkey: 'VK_LEFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowDown: { + vkey: 'VK_DOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowUp: { + vkey: 'VK_UP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumLock: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadDivide: { + vkey: 'VK_DIVIDE', + value: '/', + withShift: '/', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadMultiply: { + vkey: 'VK_MULTIPLY', + value: '*', + withShift: '*', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadSubtract: { + vkey: 'VK_SUBTRACT', + value: '-', + withShift: '-', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadAdd: { + vkey: 'VK_ADD', + value: '+', + withShift: '+', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadEnter: { + vkey: 'VK_RETURN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad1: { + vkey: 'VK_END', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad2: { + vkey: 'VK_DOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad3: { + vkey: 'VK_NEXT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad4: { + vkey: 'VK_LEFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad5: { + vkey: 'VK_CLEAR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad6: { + vkey: 'VK_RIGHT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad7: { + vkey: 'VK_HOME', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad8: { + vkey: 'VK_UP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad9: { + vkey: 'VK_PRIOR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad0: { + vkey: 'VK_INSERT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadDecimal: { + vkey: 'VK_DELETE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + IntlBackslash: { + vkey: 'VK_OEM_102', + value: '\\', + withShift: '|', + withAltGr: '', + withShiftAltGr: '' + }, + ContextMenu: { + vkey: 'VK_APPS', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Power: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadEqual: { + vkey: 'VK_CLEAR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F13: { + vkey: 'VK_F13', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F14: { + vkey: 'VK_F14', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F15: { + vkey: 'VK_F15', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F16: { + vkey: 'VK_F16', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F17: { + vkey: 'VK_F17', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F18: { + vkey: 'VK_F18', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F19: { + vkey: 'VK_F19', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F20: { + vkey: 'VK_F20', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F21: { + vkey: 'VK_F21', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F22: { + vkey: 'VK_F22', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F23: { + vkey: 'VK_F23', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F24: { + vkey: 'VK_F24', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Help: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Undo: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Cut: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Copy: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Paste: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeMute: { + vkey: 'VK_VOLUME_MUTE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeUp: { + vkey: 'VK_VOLUME_UP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeDown: { + vkey: 'VK_VOLUME_DOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadComma: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + IntlRo: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + KanaMode: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + IntlYen: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Convert: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NonConvert: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang1: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang2: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang3: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang4: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ControlLeft: { + vkey: 'VK_CONTROL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ShiftLeft: { + vkey: 'VK_SHIFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AltLeft: { + vkey: 'VK_MENU', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MetaLeft: { + vkey: 'VK_LWIN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ControlRight: { + vkey: 'VK_CONTROL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ShiftRight: { + vkey: 'VK_SHIFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AltRight: { + vkey: 'VK_MENU', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MetaRight: { + vkey: 'VK_RWIN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaTrackNext: { + vkey: 'VK_MEDIA_NEXT_TRACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaTrackPrevious: { + vkey: 'VK_MEDIA_PREV_TRACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaStop: { + vkey: 'VK_MEDIA_STOP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Eject: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaPlayPause: { + vkey: 'VK_MEDIA_PLAY_PAUSE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaSelect: { + vkey: 'VK_LAUNCH_MEDIA_SELECT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchMail: { + vkey: 'VK_LAUNCH_MAIL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchApp2: { + vkey: 'VK_LAUNCH_APP2', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchApp1: { + vkey: 'VK_LAUNCH_APP1', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserSearch: { + vkey: 'VK_BROWSER_SEARCH', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserHome: { + vkey: 'VK_BROWSER_HOME', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserBack: { + vkey: 'VK_BROWSER_BACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserForward: { + vkey: 'VK_BROWSER_FORWARD', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserStop: { + vkey: 'VK_BROWSER_STOP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserRefresh: { + vkey: 'VK_BROWSER_REFRESH', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserFavorites: { + vkey: 'VK_BROWSER_FAVORITES', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/node/win_en_us.txt b/src/vs/workbench/services/keybinding/test/node/win_en_us.txt new file mode 100644 index 00000000000..b011bd0be56 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/win_en_us.txt @@ -0,0 +1,284 @@ +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyA | a | A | A | a | | +| Shift+KeyA | A | Shift+A | Shift+A | shift+a | | +| Ctrl+Alt+KeyA | --- | Ctrl+Alt+A | Ctrl+Alt+A | ctrl+alt+a | | +| Ctrl+Shift+Alt+KeyA | --- | Ctrl+Shift+Alt+A | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyB | b | B | B | b | | +| Shift+KeyB | B | Shift+B | Shift+B | shift+b | | +| Ctrl+Alt+KeyB | --- | Ctrl+Alt+B | Ctrl+Alt+B | ctrl+alt+b | | +| Ctrl+Shift+Alt+KeyB | --- | Ctrl+Shift+Alt+B | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyC | c | C | C | c | | +| Shift+KeyC | C | Shift+C | Shift+C | shift+c | | +| Ctrl+Alt+KeyC | --- | Ctrl+Alt+C | Ctrl+Alt+C | ctrl+alt+c | | +| Ctrl+Shift+Alt+KeyC | --- | Ctrl+Shift+Alt+C | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyD | d | D | D | d | | +| Shift+KeyD | D | Shift+D | Shift+D | shift+d | | +| Ctrl+Alt+KeyD | --- | Ctrl+Alt+D | Ctrl+Alt+D | ctrl+alt+d | | +| Ctrl+Shift+Alt+KeyD | --- | Ctrl+Shift+Alt+D | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyE | e | E | E | e | | +| Shift+KeyE | E | Shift+E | Shift+E | shift+e | | +| Ctrl+Alt+KeyE | --- | Ctrl+Alt+E | Ctrl+Alt+E | ctrl+alt+e | | +| Ctrl+Shift+Alt+KeyE | --- | Ctrl+Shift+Alt+E | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyF | f | F | F | f | | +| Shift+KeyF | F | Shift+F | Shift+F | shift+f | | +| Ctrl+Alt+KeyF | --- | Ctrl+Alt+F | Ctrl+Alt+F | ctrl+alt+f | | +| Ctrl+Shift+Alt+KeyF | --- | Ctrl+Shift+Alt+F | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyG | g | G | G | g | | +| Shift+KeyG | G | Shift+G | Shift+G | shift+g | | +| Ctrl+Alt+KeyG | --- | Ctrl+Alt+G | Ctrl+Alt+G | ctrl+alt+g | | +| Ctrl+Shift+Alt+KeyG | --- | Ctrl+Shift+Alt+G | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyH | h | H | H | h | | +| Shift+KeyH | H | Shift+H | Shift+H | shift+h | | +| Ctrl+Alt+KeyH | --- | Ctrl+Alt+H | Ctrl+Alt+H | ctrl+alt+h | | +| Ctrl+Shift+Alt+KeyH | --- | Ctrl+Shift+Alt+H | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyI | i | I | I | i | | +| Shift+KeyI | I | Shift+I | Shift+I | shift+i | | +| Ctrl+Alt+KeyI | --- | Ctrl+Alt+I | Ctrl+Alt+I | ctrl+alt+i | | +| Ctrl+Shift+Alt+KeyI | --- | Ctrl+Shift+Alt+I | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyJ | j | J | J | j | | +| Shift+KeyJ | J | Shift+J | Shift+J | shift+j | | +| Ctrl+Alt+KeyJ | --- | Ctrl+Alt+J | Ctrl+Alt+J | ctrl+alt+j | | +| Ctrl+Shift+Alt+KeyJ | --- | Ctrl+Shift+Alt+J | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyK | k | K | K | k | | +| Shift+KeyK | K | Shift+K | Shift+K | shift+k | | +| Ctrl+Alt+KeyK | --- | Ctrl+Alt+K | Ctrl+Alt+K | ctrl+alt+k | | +| Ctrl+Shift+Alt+KeyK | --- | Ctrl+Shift+Alt+K | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyL | l | L | L | l | | +| Shift+KeyL | L | Shift+L | Shift+L | shift+l | | +| Ctrl+Alt+KeyL | --- | Ctrl+Alt+L | Ctrl+Alt+L | ctrl+alt+l | | +| Ctrl+Shift+Alt+KeyL | --- | Ctrl+Shift+Alt+L | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyM | m | M | M | m | | +| Shift+KeyM | M | Shift+M | Shift+M | shift+m | | +| Ctrl+Alt+KeyM | --- | Ctrl+Alt+M | Ctrl+Alt+M | ctrl+alt+m | | +| Ctrl+Shift+Alt+KeyM | --- | Ctrl+Shift+Alt+M | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyN | n | N | N | n | | +| Shift+KeyN | N | Shift+N | Shift+N | shift+n | | +| Ctrl+Alt+KeyN | --- | Ctrl+Alt+N | Ctrl+Alt+N | ctrl+alt+n | | +| Ctrl+Shift+Alt+KeyN | --- | Ctrl+Shift+Alt+N | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyO | o | O | O | o | | +| Shift+KeyO | O | Shift+O | Shift+O | shift+o | | +| Ctrl+Alt+KeyO | --- | Ctrl+Alt+O | Ctrl+Alt+O | ctrl+alt+o | | +| Ctrl+Shift+Alt+KeyO | --- | Ctrl+Shift+Alt+O | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyP | p | P | P | p | | +| Shift+KeyP | P | Shift+P | Shift+P | shift+p | | +| Ctrl+Alt+KeyP | --- | Ctrl+Alt+P | Ctrl+Alt+P | ctrl+alt+p | | +| Ctrl+Shift+Alt+KeyP | --- | Ctrl+Shift+Alt+P | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyQ | q | Q | Q | q | | +| Shift+KeyQ | Q | Shift+Q | Shift+Q | shift+q | | +| Ctrl+Alt+KeyQ | --- | Ctrl+Alt+Q | Ctrl+Alt+Q | ctrl+alt+q | | +| Ctrl+Shift+Alt+KeyQ | --- | Ctrl+Shift+Alt+Q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyR | r | R | R | r | | +| Shift+KeyR | R | Shift+R | Shift+R | shift+r | | +| Ctrl+Alt+KeyR | --- | Ctrl+Alt+R | Ctrl+Alt+R | ctrl+alt+r | | +| Ctrl+Shift+Alt+KeyR | --- | Ctrl+Shift+Alt+R | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyS | s | S | S | s | | +| Shift+KeyS | S | Shift+S | Shift+S | shift+s | | +| Ctrl+Alt+KeyS | --- | Ctrl+Alt+S | Ctrl+Alt+S | ctrl+alt+s | | +| Ctrl+Shift+Alt+KeyS | --- | Ctrl+Shift+Alt+S | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyT | t | T | T | t | | +| Shift+KeyT | T | Shift+T | Shift+T | shift+t | | +| Ctrl+Alt+KeyT | --- | Ctrl+Alt+T | Ctrl+Alt+T | ctrl+alt+t | | +| Ctrl+Shift+Alt+KeyT | --- | Ctrl+Shift+Alt+T | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyU | u | U | U | u | | +| Shift+KeyU | U | Shift+U | Shift+U | shift+u | | +| Ctrl+Alt+KeyU | --- | Ctrl+Alt+U | Ctrl+Alt+U | ctrl+alt+u | | +| Ctrl+Shift+Alt+KeyU | --- | Ctrl+Shift+Alt+U | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyV | v | V | V | v | | +| Shift+KeyV | V | Shift+V | Shift+V | shift+v | | +| Ctrl+Alt+KeyV | --- | Ctrl+Alt+V | Ctrl+Alt+V | ctrl+alt+v | | +| Ctrl+Shift+Alt+KeyV | --- | Ctrl+Shift+Alt+V | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyW | w | W | W | w | | +| Shift+KeyW | W | Shift+W | Shift+W | shift+w | | +| Ctrl+Alt+KeyW | --- | Ctrl+Alt+W | Ctrl+Alt+W | ctrl+alt+w | | +| Ctrl+Shift+Alt+KeyW | --- | Ctrl+Shift+Alt+W | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyX | x | X | X | x | | +| Shift+KeyX | X | Shift+X | Shift+X | shift+x | | +| Ctrl+Alt+KeyX | --- | Ctrl+Alt+X | Ctrl+Alt+X | ctrl+alt+x | | +| Ctrl+Shift+Alt+KeyX | --- | Ctrl+Shift+Alt+X | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyY | y | Y | Y | y | | +| Shift+KeyY | Y | Shift+Y | Shift+Y | shift+y | | +| Ctrl+Alt+KeyY | --- | Ctrl+Alt+Y | Ctrl+Alt+Y | ctrl+alt+y | | +| Ctrl+Shift+Alt+KeyY | --- | Ctrl+Shift+Alt+Y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyZ | z | Z | Z | z | | +| Shift+KeyZ | Z | Shift+Z | Shift+Z | shift+z | | +| Ctrl+Alt+KeyZ | --- | Ctrl+Alt+Z | Ctrl+Alt+Z | ctrl+alt+z | | +| Ctrl+Shift+Alt+KeyZ | --- | Ctrl+Shift+Alt+Z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit1 | 1 | 1 | 1 | 1 | | +| Shift+Digit1 | ! | Shift+1 | Shift+1 | shift+1 | | +| Ctrl+Alt+Digit1 | --- | Ctrl+Alt+1 | Ctrl+Alt+1 | ctrl+alt+1 | | +| Ctrl+Shift+Alt+Digit1 | --- | Ctrl+Shift+Alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit2 | 2 | 2 | 2 | 2 | | +| Shift+Digit2 | @ | Shift+2 | Shift+2 | shift+2 | | +| Ctrl+Alt+Digit2 | --- | Ctrl+Alt+2 | Ctrl+Alt+2 | ctrl+alt+2 | | +| Ctrl+Shift+Alt+Digit2 | --- | Ctrl+Shift+Alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit3 | 3 | 3 | 3 | 3 | | +| Shift+Digit3 | # | Shift+3 | Shift+3 | shift+3 | | +| Ctrl+Alt+Digit3 | --- | Ctrl+Alt+3 | Ctrl+Alt+3 | ctrl+alt+3 | | +| Ctrl+Shift+Alt+Digit3 | --- | Ctrl+Shift+Alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit4 | 4 | 4 | 4 | 4 | | +| Shift+Digit4 | $ | Shift+4 | Shift+4 | shift+4 | | +| Ctrl+Alt+Digit4 | --- | Ctrl+Alt+4 | Ctrl+Alt+4 | ctrl+alt+4 | | +| Ctrl+Shift+Alt+Digit4 | --- | Ctrl+Shift+Alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit5 | 5 | 5 | 5 | 5 | | +| Shift+Digit5 | % | Shift+5 | Shift+5 | shift+5 | | +| Ctrl+Alt+Digit5 | --- | Ctrl+Alt+5 | Ctrl+Alt+5 | ctrl+alt+5 | | +| Ctrl+Shift+Alt+Digit5 | --- | Ctrl+Shift+Alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit6 | 6 | 6 | 6 | 6 | | +| Shift+Digit6 | ^ | Shift+6 | Shift+6 | shift+6 | | +| Ctrl+Alt+Digit6 | --- | Ctrl+Alt+6 | Ctrl+Alt+6 | ctrl+alt+6 | | +| Ctrl+Shift+Alt+Digit6 | --- | Ctrl+Shift+Alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit7 | 7 | 7 | 7 | 7 | | +| Shift+Digit7 | & | Shift+7 | Shift+7 | shift+7 | | +| Ctrl+Alt+Digit7 | --- | Ctrl+Alt+7 | Ctrl+Alt+7 | ctrl+alt+7 | | +| Ctrl+Shift+Alt+Digit7 | --- | Ctrl+Shift+Alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit8 | 8 | 8 | 8 | 8 | | +| Shift+Digit8 | * | Shift+8 | Shift+8 | shift+8 | | +| Ctrl+Alt+Digit8 | --- | Ctrl+Alt+8 | Ctrl+Alt+8 | ctrl+alt+8 | | +| Ctrl+Shift+Alt+Digit8 | --- | Ctrl+Shift+Alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit9 | 9 | 9 | 9 | 9 | | +| Shift+Digit9 | ( | Shift+9 | Shift+9 | shift+9 | | +| Ctrl+Alt+Digit9 | --- | Ctrl+Alt+9 | Ctrl+Alt+9 | ctrl+alt+9 | | +| Ctrl+Shift+Alt+Digit9 | --- | Ctrl+Shift+Alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit0 | 0 | 0 | 0 | 0 | | +| Shift+Digit0 | ) | Shift+0 | Shift+0 | shift+0 | | +| Ctrl+Alt+Digit0 | --- | Ctrl+Alt+0 | Ctrl+Alt+0 | ctrl+alt+0 | | +| Ctrl+Shift+Alt+Digit0 | --- | Ctrl+Shift+Alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| Minus | - | - | - | - | | +| Shift+Minus | _ | Shift+- | Shift+- | shift+- | | +| Ctrl+Alt+Minus | --- | Ctrl+Alt+- | Ctrl+Alt+- | ctrl+alt+- | | +| Ctrl+Shift+Alt+Minus | --- | Ctrl+Shift+Alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+- | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Equal | = | = | = | = | | +| Shift+Equal | + | Shift+= | Shift+= | shift+= | | +| Ctrl+Alt+Equal | --- | Ctrl+Alt+= | Ctrl+Alt+= | ctrl+alt+= | | +| Ctrl+Shift+Alt+Equal | --- | Ctrl+Shift+Alt+= | Ctrl+Shift+Alt+= | ctrl+shift+alt+= | | +----------------------------------------------------------------------------------------------------------------------------------------- +| BracketLeft | [ | [ | [ | [ | | +| Shift+BracketLeft | { | Shift+[ | Shift+[ | shift+[ | | +| Ctrl+Alt+BracketLeft | --- | Ctrl+Alt+[ | Ctrl+Alt+[ | ctrl+alt+[ | | +| Ctrl+Shift+Alt+BracketLeft | --- | Ctrl+Shift+Alt+[ | Ctrl+Shift+Alt+[ | ctrl+shift+alt+[ | | +----------------------------------------------------------------------------------------------------------------------------------------- +| BracketRight | ] | ] | ] | ] | | +| Shift+BracketRight | } | Shift+] | Shift+] | shift+] | | +| Ctrl+Alt+BracketRight | --- | Ctrl+Alt+] | Ctrl+Alt+] | ctrl+alt+] | | +| Ctrl+Shift+Alt+BracketRight | --- | Ctrl+Shift+Alt+] | Ctrl+Shift+Alt+] | ctrl+shift+alt+] | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Backslash | \ | \ | \ | \ | | +| Shift+Backslash | | | Shift+\ | Shift+\ | shift+\ | | +| Ctrl+Alt+Backslash | --- | Ctrl+Alt+\ | Ctrl+Alt+\ | ctrl+alt+\ | | +| Ctrl+Shift+Alt+Backslash | --- | Ctrl+Shift+Alt+\ | Ctrl+Shift+Alt+\ | ctrl+shift+alt+\ | | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlHash | --- | null | null | null | NO | +| Shift+IntlHash | --- | null | null | null | NO | +| Ctrl+Alt+IntlHash | --- | null | null | null | NO | +| Ctrl+Shift+Alt+IntlHash | --- | null | null | null | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| Semicolon | ; | ; | ; | ; | | +| Shift+Semicolon | : | Shift+; | Shift+; | shift+; | | +| Ctrl+Alt+Semicolon | --- | Ctrl+Alt+; | Ctrl+Alt+; | ctrl+alt+; | | +| Ctrl+Shift+Alt+Semicolon | --- | Ctrl+Shift+Alt+; | Ctrl+Shift+Alt+; | ctrl+shift+alt+; | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Quote | ' | ' | ' | ' | | +| Shift+Quote | " | Shift+' | Shift+' | shift+' | | +| Ctrl+Alt+Quote | --- | Ctrl+Alt+' | Ctrl+Alt+' | ctrl+alt+' | | +| Ctrl+Shift+Alt+Quote | --- | Ctrl+Shift+Alt+' | Ctrl+Shift+Alt+' | ctrl+shift+alt+' | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Backquote | ` | ` | ` | ` | | +| Shift+Backquote | ~ | Shift+` | Shift+` | shift+` | | +| Ctrl+Alt+Backquote | --- | Ctrl+Alt+` | Ctrl+Alt+` | ctrl+alt+` | | +| Ctrl+Shift+Alt+Backquote | --- | Ctrl+Shift+Alt+` | Ctrl+Shift+Alt+` | ctrl+shift+alt+` | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Comma | , | , | , | , | | +| Shift+Comma | < | Shift+, | Shift+, | shift+, | | +| Ctrl+Alt+Comma | --- | Ctrl+Alt+, | Ctrl+Alt+, | ctrl+alt+, | | +| Ctrl+Shift+Alt+Comma | --- | Ctrl+Shift+Alt+, | Ctrl+Shift+Alt+, | ctrl+shift+alt+, | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Period | . | . | . | . | | +| Shift+Period | > | Shift+. | Shift+. | shift+. | | +| Ctrl+Alt+Period | --- | Ctrl+Alt+. | Ctrl+Alt+. | ctrl+alt+. | | +| Ctrl+Shift+Alt+Period | --- | Ctrl+Shift+Alt+. | Ctrl+Shift+Alt+. | ctrl+shift+alt+. | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Slash | / | / | / | / | | +| Shift+Slash | ? | Shift+/ | Shift+/ | shift+/ | | +| Ctrl+Alt+Slash | --- | Ctrl+Alt+/ | Ctrl+Alt+/ | ctrl+alt+/ | | +| Ctrl+Shift+Alt+Slash | --- | Ctrl+Shift+Alt+/ | Ctrl+Shift+Alt+/ | ctrl+shift+alt+/ | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| ArrowUp | --- | UpArrow | UpArrow | up | | +| Shift+ArrowUp | --- | Shift+UpArrow | Shift+UpArrow | shift+up | | +| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | Ctrl+Alt+UpArrow | ctrl+alt+up | | +| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Numpad0 | --- | NumPad0 | NumPad0 | numpad0 | | +| Shift+Numpad0 | --- | Shift+NumPad0 | Shift+NumPad0 | shift+numpad0 | | +| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | | +| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlBackslash | \ | OEM_102 | \ | oem_102 | NO | +| Shift+IntlBackslash | | | Shift+OEM_102 | Shift+\ | shift+oem_102 | NO | +| Ctrl+Alt+IntlBackslash | --- | Ctrl+Alt+OEM_102 | Ctrl+Alt+\ | ctrl+alt+oem_102 | NO | +| Ctrl+Shift+Alt+IntlBackslash | --- | Ctrl+Shift+Alt+OEM_102 | Ctrl+Shift+Alt+\ | ctrl+shift+alt+oem_102 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlRo | --- | null | null | null | NO | +| Shift+IntlRo | --- | null | null | null | NO | +| Ctrl+Alt+IntlRo | --- | null | null | null | NO | +| Ctrl+Shift+Alt+IntlRo | --- | null | null | null | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlYen | --- | null | null | null | NO | +| Shift+IntlYen | --- | null | null | null | NO | +| Ctrl+Alt+IntlYen | --- | null | null | null | NO | +| Ctrl+Shift+Alt+IntlYen | --- | null | null | null | NO | +----------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/node/win_por_ptb.js b/src/vs/workbench/services/keybinding/test/node/win_por_ptb.js new file mode 100644 index 00000000000..683b2e24113 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/win_por_ptb.js @@ -0,0 +1,1093 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +define({ + Sleep: { + vkey: 'VK_SLEEP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + WakeUp: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + KeyA: { + vkey: 'VK_A', + value: 'a', + withShift: 'A', + withAltGr: '', + withShiftAltGr: '' + }, + KeyB: { + vkey: 'VK_B', + value: 'b', + withShift: 'B', + withAltGr: '', + withShiftAltGr: '' + }, + KeyC: { + vkey: 'VK_C', + value: 'c', + withShift: 'C', + withAltGr: '₢', + withShiftAltGr: '' + }, + KeyD: { + vkey: 'VK_D', + value: 'd', + withShift: 'D', + withAltGr: '', + withShiftAltGr: '' + }, + KeyE: { + vkey: 'VK_E', + value: 'e', + withShift: 'E', + withAltGr: '°', + withShiftAltGr: '' + }, + KeyF: { + vkey: 'VK_F', + value: 'f', + withShift: 'F', + withAltGr: '', + withShiftAltGr: '' + }, + KeyG: { + vkey: 'VK_G', + value: 'g', + withShift: 'G', + withAltGr: '', + withShiftAltGr: '' + }, + KeyH: { + vkey: 'VK_H', + value: 'h', + withShift: 'H', + withAltGr: '', + withShiftAltGr: '' + }, + KeyI: { + vkey: 'VK_I', + value: 'i', + withShift: 'I', + withAltGr: '', + withShiftAltGr: '' + }, + KeyJ: { + vkey: 'VK_J', + value: 'j', + withShift: 'J', + withAltGr: '', + withShiftAltGr: '' + }, + KeyK: { + vkey: 'VK_K', + value: 'k', + withShift: 'K', + withAltGr: '', + withShiftAltGr: '' + }, + KeyL: { + vkey: 'VK_L', + value: 'l', + withShift: 'L', + withAltGr: '', + withShiftAltGr: '' + }, + KeyM: { + vkey: 'VK_M', + value: 'm', + withShift: 'M', + withAltGr: '', + withShiftAltGr: '' + }, + KeyN: { + vkey: 'VK_N', + value: 'n', + withShift: 'N', + withAltGr: '', + withShiftAltGr: '' + }, + KeyO: { + vkey: 'VK_O', + value: 'o', + withShift: 'O', + withAltGr: '', + withShiftAltGr: '' + }, + KeyP: { + vkey: 'VK_P', + value: 'p', + withShift: 'P', + withAltGr: '', + withShiftAltGr: '' + }, + KeyQ: { + vkey: 'VK_Q', + value: 'q', + withShift: 'Q', + withAltGr: '/', + withShiftAltGr: '' + }, + KeyR: { + vkey: 'VK_R', + value: 'r', + withShift: 'R', + withAltGr: '', + withShiftAltGr: '' + }, + KeyS: { + vkey: 'VK_S', + value: 's', + withShift: 'S', + withAltGr: '', + withShiftAltGr: '' + }, + KeyT: { + vkey: 'VK_T', + value: 't', + withShift: 'T', + withAltGr: '', + withShiftAltGr: '' + }, + KeyU: { + vkey: 'VK_U', + value: 'u', + withShift: 'U', + withAltGr: '', + withShiftAltGr: '' + }, + KeyV: { + vkey: 'VK_V', + value: 'v', + withShift: 'V', + withAltGr: '', + withShiftAltGr: '' + }, + KeyW: { + vkey: 'VK_W', + value: 'w', + withShift: 'W', + withAltGr: '?', + withShiftAltGr: '' + }, + KeyX: { + vkey: 'VK_X', + value: 'x', + withShift: 'X', + withAltGr: '', + withShiftAltGr: '' + }, + KeyY: { + vkey: 'VK_Y', + value: 'y', + withShift: 'Y', + withAltGr: '', + withShiftAltGr: '' + }, + KeyZ: { + vkey: 'VK_Z', + value: 'z', + withShift: 'Z', + withAltGr: '', + withShiftAltGr: '' + }, + Digit1: { + vkey: 'VK_1', + value: '1', + withShift: '!', + withAltGr: '¹', + withShiftAltGr: '' + }, + Digit2: { + vkey: 'VK_2', + value: '2', + withShift: '@', + withAltGr: '²', + withShiftAltGr: '' + }, + Digit3: { + vkey: 'VK_3', + value: '3', + withShift: '#', + withAltGr: '³', + withShiftAltGr: '' + }, + Digit4: { + vkey: 'VK_4', + value: '4', + withShift: '$', + withAltGr: '£', + withShiftAltGr: '' + }, + Digit5: { + vkey: 'VK_5', + value: '5', + withShift: '%', + withAltGr: '¢', + withShiftAltGr: '' + }, + Digit6: { + vkey: 'VK_6', + value: '6', + withShift: '¨', + withAltGr: '¬', + withShiftAltGr: '' + }, + Digit7: { + vkey: 'VK_7', + value: '7', + withShift: '&', + withAltGr: '', + withShiftAltGr: '' + }, + Digit8: { + vkey: 'VK_8', + value: '8', + withShift: '*', + withAltGr: '', + withShiftAltGr: '' + }, + Digit9: { + vkey: 'VK_9', + value: '9', + withShift: '(', + withAltGr: '', + withShiftAltGr: '' + }, + Digit0: { + vkey: 'VK_0', + value: '0', + withShift: ')', + withAltGr: '', + withShiftAltGr: '' + }, + Enter: { + vkey: 'VK_RETURN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Escape: { + vkey: 'VK_ESCAPE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Backspace: { + vkey: 'VK_BACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Tab: { + vkey: 'VK_TAB', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Space: { + vkey: 'VK_SPACE', + value: ' ', + withShift: ' ', + withAltGr: '', + withShiftAltGr: '' + }, + Minus: { + vkey: 'VK_OEM_MINUS', + value: '-', + withShift: '_', + withAltGr: '', + withShiftAltGr: '' + }, + Equal: { + vkey: 'VK_OEM_PLUS', + value: '=', + withShift: '+', + withAltGr: '§', + withShiftAltGr: '' + }, + BracketLeft: { + vkey: 'VK_OEM_4', + value: '´', + withShift: '`', + withAltGr: '', + withShiftAltGr: '' + }, + BracketRight: { + vkey: 'VK_OEM_6', + value: '[', + withShift: '{', + withAltGr: 'ª', + withShiftAltGr: '' + }, + Backslash: { + vkey: 'VK_OEM_5', + value: ']', + withShift: '}', + withAltGr: 'º', + withShiftAltGr: '' + }, + Semicolon: { + vkey: 'VK_OEM_1', + value: 'ç', + withShift: 'Ç', + withAltGr: '', + withShiftAltGr: '' + }, + Quote: { + vkey: 'VK_OEM_7', + value: '~', + withShift: '^', + withAltGr: '', + withShiftAltGr: '' + }, + Backquote: { + vkey: 'VK_OEM_3', + value: '\'', + withShift: '"', + withAltGr: '', + withShiftAltGr: '' + }, + Comma: { + vkey: 'VK_OEM_COMMA', + value: ',', + withShift: '<', + withAltGr: '', + withShiftAltGr: '' + }, + Period: { + vkey: 'VK_OEM_PERIOD', + value: '.', + withShift: '>', + withAltGr: '', + withShiftAltGr: '' + }, + Slash: { + vkey: 'VK_OEM_2', + value: ';', + withShift: ':', + withAltGr: '', + withShiftAltGr: '' + }, + CapsLock: { + vkey: 'VK_CAPITAL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F1: { + vkey: 'VK_F1', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F2: { + vkey: 'VK_F2', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F3: { + vkey: 'VK_F3', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F4: { + vkey: 'VK_F4', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F5: { + vkey: 'VK_F5', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F6: { + vkey: 'VK_F6', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F7: { + vkey: 'VK_F7', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F8: { + vkey: 'VK_F8', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F9: { + vkey: 'VK_F9', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F10: { + vkey: 'VK_F10', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F11: { + vkey: 'VK_F11', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F12: { + vkey: 'VK_F12', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PrintScreen: { + vkey: 'VK_SNAPSHOT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ScrollLock: { + vkey: 'VK_SCROLL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Pause: { + vkey: 'VK_NUMLOCK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Insert: { + vkey: 'VK_INSERT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Home: { + vkey: 'VK_HOME', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PageUp: { + vkey: 'VK_PRIOR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Delete: { + vkey: 'VK_DELETE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + End: { + vkey: 'VK_END', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PageDown: { + vkey: 'VK_NEXT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowRight: { + vkey: 'VK_RIGHT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowLeft: { + vkey: 'VK_LEFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowDown: { + vkey: 'VK_DOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowUp: { + vkey: 'VK_UP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumLock: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadDivide: { + vkey: 'VK_DIVIDE', + value: '/', + withShift: '/', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadMultiply: { + vkey: 'VK_MULTIPLY', + value: '*', + withShift: '*', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadSubtract: { + vkey: 'VK_SUBTRACT', + value: '-', + withShift: '-', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadAdd: { + vkey: 'VK_ADD', + value: '+', + withShift: '+', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadEnter: { + vkey: 'VK_RETURN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad1: { + vkey: 'VK_END', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad2: { + vkey: 'VK_DOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad3: { + vkey: 'VK_NEXT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad4: { + vkey: 'VK_LEFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad5: { + vkey: 'VK_CLEAR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad6: { + vkey: 'VK_RIGHT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad7: { + vkey: 'VK_HOME', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad8: { + vkey: 'VK_UP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad9: { + vkey: 'VK_PRIOR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad0: { + vkey: 'VK_INSERT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadDecimal: { + vkey: 'VK_DELETE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + IntlBackslash: { + vkey: 'VK_OEM_102', + value: '\\', + withShift: '|', + withAltGr: '', + withShiftAltGr: '' + }, + ContextMenu: { + vkey: 'VK_APPS', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Power: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadEqual: { + vkey: 'VK_CLEAR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F13: { + vkey: 'VK_F13', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F14: { + vkey: 'VK_F14', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F15: { + vkey: 'VK_F15', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F16: { + vkey: 'VK_F16', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F17: { + vkey: 'VK_F17', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F18: { + vkey: 'VK_F18', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F19: { + vkey: 'VK_F19', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F20: { + vkey: 'VK_F20', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F21: { + vkey: 'VK_F21', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F22: { + vkey: 'VK_F22', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F23: { + vkey: 'VK_F23', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F24: { + vkey: 'VK_F24', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Help: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Undo: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Cut: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Copy: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Paste: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeMute: { + vkey: 'VK_VOLUME_MUTE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeUp: { + vkey: 'VK_VOLUME_UP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeDown: { + vkey: 'VK_VOLUME_DOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadComma: { + vkey: 'VK_ABNT_C2', + value: '.', + withShift: '.', + withAltGr: '', + withShiftAltGr: '' + }, + IntlRo: { + vkey: 'VK_ABNT_C1', + value: '/', + withShift: '?', + withAltGr: '°', + withShiftAltGr: '' + }, + KanaMode: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + IntlYen: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Convert: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NonConvert: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang1: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang2: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang3: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang4: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ControlLeft: { + vkey: 'VK_CONTROL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ShiftLeft: { + vkey: 'VK_SHIFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AltLeft: { + vkey: 'VK_MENU', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MetaLeft: { + vkey: 'VK_LWIN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ControlRight: { + vkey: 'VK_CONTROL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ShiftRight: { + vkey: 'VK_SHIFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AltRight: { + vkey: 'VK_MENU', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MetaRight: { + vkey: 'VK_RWIN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaTrackNext: { + vkey: 'VK_MEDIA_NEXT_TRACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaTrackPrevious: { + vkey: 'VK_MEDIA_PREV_TRACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaStop: { + vkey: 'VK_MEDIA_STOP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Eject: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaPlayPause: { + vkey: 'VK_MEDIA_PLAY_PAUSE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaSelect: { + vkey: 'VK_LAUNCH_MEDIA_SELECT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchMail: { + vkey: 'VK_LAUNCH_MAIL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchApp2: { + vkey: 'VK_LAUNCH_APP2', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchApp1: { + vkey: 'VK_LAUNCH_APP1', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserSearch: { + vkey: 'VK_BROWSER_SEARCH', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserHome: { + vkey: 'VK_BROWSER_HOME', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserBack: { + vkey: 'VK_BROWSER_BACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserForward: { + vkey: 'VK_BROWSER_FORWARD', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserStop: { + vkey: 'VK_BROWSER_STOP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserRefresh: { + vkey: 'VK_BROWSER_REFRESH', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserFavorites: { + vkey: 'VK_BROWSER_FAVORITES', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/node/win_por_ptb.txt b/src/vs/workbench/services/keybinding/test/node/win_por_ptb.txt new file mode 100644 index 00000000000..c29ed546991 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/win_por_ptb.txt @@ -0,0 +1,284 @@ +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyA | a | A | A | a | | +| Shift+KeyA | A | Shift+A | Shift+A | shift+a | | +| Ctrl+Alt+KeyA | --- | Ctrl+Alt+A | Ctrl+Alt+A | ctrl+alt+a | | +| Ctrl+Shift+Alt+KeyA | --- | Ctrl+Shift+Alt+A | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyB | b | B | B | b | | +| Shift+KeyB | B | Shift+B | Shift+B | shift+b | | +| Ctrl+Alt+KeyB | --- | Ctrl+Alt+B | Ctrl+Alt+B | ctrl+alt+b | | +| Ctrl+Shift+Alt+KeyB | --- | Ctrl+Shift+Alt+B | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyC | c | C | C | c | | +| Shift+KeyC | C | Shift+C | Shift+C | shift+c | | +| Ctrl+Alt+KeyC | ₢ | Ctrl+Alt+C | Ctrl+Alt+C | ctrl+alt+c | | +| Ctrl+Shift+Alt+KeyC | --- | Ctrl+Shift+Alt+C | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyD | d | D | D | d | | +| Shift+KeyD | D | Shift+D | Shift+D | shift+d | | +| Ctrl+Alt+KeyD | --- | Ctrl+Alt+D | Ctrl+Alt+D | ctrl+alt+d | | +| Ctrl+Shift+Alt+KeyD | --- | Ctrl+Shift+Alt+D | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyE | e | E | E | e | | +| Shift+KeyE | E | Shift+E | Shift+E | shift+e | | +| Ctrl+Alt+KeyE | ° | Ctrl+Alt+E | Ctrl+Alt+E | ctrl+alt+e | | +| Ctrl+Shift+Alt+KeyE | --- | Ctrl+Shift+Alt+E | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyF | f | F | F | f | | +| Shift+KeyF | F | Shift+F | Shift+F | shift+f | | +| Ctrl+Alt+KeyF | --- | Ctrl+Alt+F | Ctrl+Alt+F | ctrl+alt+f | | +| Ctrl+Shift+Alt+KeyF | --- | Ctrl+Shift+Alt+F | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyG | g | G | G | g | | +| Shift+KeyG | G | Shift+G | Shift+G | shift+g | | +| Ctrl+Alt+KeyG | --- | Ctrl+Alt+G | Ctrl+Alt+G | ctrl+alt+g | | +| Ctrl+Shift+Alt+KeyG | --- | Ctrl+Shift+Alt+G | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyH | h | H | H | h | | +| Shift+KeyH | H | Shift+H | Shift+H | shift+h | | +| Ctrl+Alt+KeyH | --- | Ctrl+Alt+H | Ctrl+Alt+H | ctrl+alt+h | | +| Ctrl+Shift+Alt+KeyH | --- | Ctrl+Shift+Alt+H | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyI | i | I | I | i | | +| Shift+KeyI | I | Shift+I | Shift+I | shift+i | | +| Ctrl+Alt+KeyI | --- | Ctrl+Alt+I | Ctrl+Alt+I | ctrl+alt+i | | +| Ctrl+Shift+Alt+KeyI | --- | Ctrl+Shift+Alt+I | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyJ | j | J | J | j | | +| Shift+KeyJ | J | Shift+J | Shift+J | shift+j | | +| Ctrl+Alt+KeyJ | --- | Ctrl+Alt+J | Ctrl+Alt+J | ctrl+alt+j | | +| Ctrl+Shift+Alt+KeyJ | --- | Ctrl+Shift+Alt+J | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyK | k | K | K | k | | +| Shift+KeyK | K | Shift+K | Shift+K | shift+k | | +| Ctrl+Alt+KeyK | --- | Ctrl+Alt+K | Ctrl+Alt+K | ctrl+alt+k | | +| Ctrl+Shift+Alt+KeyK | --- | Ctrl+Shift+Alt+K | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyL | l | L | L | l | | +| Shift+KeyL | L | Shift+L | Shift+L | shift+l | | +| Ctrl+Alt+KeyL | --- | Ctrl+Alt+L | Ctrl+Alt+L | ctrl+alt+l | | +| Ctrl+Shift+Alt+KeyL | --- | Ctrl+Shift+Alt+L | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyM | m | M | M | m | | +| Shift+KeyM | M | Shift+M | Shift+M | shift+m | | +| Ctrl+Alt+KeyM | --- | Ctrl+Alt+M | Ctrl+Alt+M | ctrl+alt+m | | +| Ctrl+Shift+Alt+KeyM | --- | Ctrl+Shift+Alt+M | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyN | n | N | N | n | | +| Shift+KeyN | N | Shift+N | Shift+N | shift+n | | +| Ctrl+Alt+KeyN | --- | Ctrl+Alt+N | Ctrl+Alt+N | ctrl+alt+n | | +| Ctrl+Shift+Alt+KeyN | --- | Ctrl+Shift+Alt+N | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyO | o | O | O | o | | +| Shift+KeyO | O | Shift+O | Shift+O | shift+o | | +| Ctrl+Alt+KeyO | --- | Ctrl+Alt+O | Ctrl+Alt+O | ctrl+alt+o | | +| Ctrl+Shift+Alt+KeyO | --- | Ctrl+Shift+Alt+O | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyP | p | P | P | p | | +| Shift+KeyP | P | Shift+P | Shift+P | shift+p | | +| Ctrl+Alt+KeyP | --- | Ctrl+Alt+P | Ctrl+Alt+P | ctrl+alt+p | | +| Ctrl+Shift+Alt+KeyP | --- | Ctrl+Shift+Alt+P | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyQ | q | Q | Q | q | | +| Shift+KeyQ | Q | Shift+Q | Shift+Q | shift+q | | +| Ctrl+Alt+KeyQ | / | Ctrl+Alt+Q | Ctrl+Alt+Q | ctrl+alt+q | | +| Ctrl+Shift+Alt+KeyQ | --- | Ctrl+Shift+Alt+Q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyR | r | R | R | r | | +| Shift+KeyR | R | Shift+R | Shift+R | shift+r | | +| Ctrl+Alt+KeyR | --- | Ctrl+Alt+R | Ctrl+Alt+R | ctrl+alt+r | | +| Ctrl+Shift+Alt+KeyR | --- | Ctrl+Shift+Alt+R | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyS | s | S | S | s | | +| Shift+KeyS | S | Shift+S | Shift+S | shift+s | | +| Ctrl+Alt+KeyS | --- | Ctrl+Alt+S | Ctrl+Alt+S | ctrl+alt+s | | +| Ctrl+Shift+Alt+KeyS | --- | Ctrl+Shift+Alt+S | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyT | t | T | T | t | | +| Shift+KeyT | T | Shift+T | Shift+T | shift+t | | +| Ctrl+Alt+KeyT | --- | Ctrl+Alt+T | Ctrl+Alt+T | ctrl+alt+t | | +| Ctrl+Shift+Alt+KeyT | --- | Ctrl+Shift+Alt+T | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyU | u | U | U | u | | +| Shift+KeyU | U | Shift+U | Shift+U | shift+u | | +| Ctrl+Alt+KeyU | --- | Ctrl+Alt+U | Ctrl+Alt+U | ctrl+alt+u | | +| Ctrl+Shift+Alt+KeyU | --- | Ctrl+Shift+Alt+U | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyV | v | V | V | v | | +| Shift+KeyV | V | Shift+V | Shift+V | shift+v | | +| Ctrl+Alt+KeyV | --- | Ctrl+Alt+V | Ctrl+Alt+V | ctrl+alt+v | | +| Ctrl+Shift+Alt+KeyV | --- | Ctrl+Shift+Alt+V | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyW | w | W | W | w | | +| Shift+KeyW | W | Shift+W | Shift+W | shift+w | | +| Ctrl+Alt+KeyW | ? | Ctrl+Alt+W | Ctrl+Alt+W | ctrl+alt+w | | +| Ctrl+Shift+Alt+KeyW | --- | Ctrl+Shift+Alt+W | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyX | x | X | X | x | | +| Shift+KeyX | X | Shift+X | Shift+X | shift+x | | +| Ctrl+Alt+KeyX | --- | Ctrl+Alt+X | Ctrl+Alt+X | ctrl+alt+x | | +| Ctrl+Shift+Alt+KeyX | --- | Ctrl+Shift+Alt+X | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyY | y | Y | Y | y | | +| Shift+KeyY | Y | Shift+Y | Shift+Y | shift+y | | +| Ctrl+Alt+KeyY | --- | Ctrl+Alt+Y | Ctrl+Alt+Y | ctrl+alt+y | | +| Ctrl+Shift+Alt+KeyY | --- | Ctrl+Shift+Alt+Y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyZ | z | Z | Z | z | | +| Shift+KeyZ | Z | Shift+Z | Shift+Z | shift+z | | +| Ctrl+Alt+KeyZ | --- | Ctrl+Alt+Z | Ctrl+Alt+Z | ctrl+alt+z | | +| Ctrl+Shift+Alt+KeyZ | --- | Ctrl+Shift+Alt+Z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit1 | 1 | 1 | 1 | 1 | | +| Shift+Digit1 | ! | Shift+1 | Shift+1 | shift+1 | | +| Ctrl+Alt+Digit1 | ¹ | Ctrl+Alt+1 | Ctrl+Alt+1 | ctrl+alt+1 | | +| Ctrl+Shift+Alt+Digit1 | --- | Ctrl+Shift+Alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit2 | 2 | 2 | 2 | 2 | | +| Shift+Digit2 | @ | Shift+2 | Shift+2 | shift+2 | | +| Ctrl+Alt+Digit2 | ² | Ctrl+Alt+2 | Ctrl+Alt+2 | ctrl+alt+2 | | +| Ctrl+Shift+Alt+Digit2 | --- | Ctrl+Shift+Alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit3 | 3 | 3 | 3 | 3 | | +| Shift+Digit3 | # | Shift+3 | Shift+3 | shift+3 | | +| Ctrl+Alt+Digit3 | ³ | Ctrl+Alt+3 | Ctrl+Alt+3 | ctrl+alt+3 | | +| Ctrl+Shift+Alt+Digit3 | --- | Ctrl+Shift+Alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit4 | 4 | 4 | 4 | 4 | | +| Shift+Digit4 | $ | Shift+4 | Shift+4 | shift+4 | | +| Ctrl+Alt+Digit4 | £ | Ctrl+Alt+4 | Ctrl+Alt+4 | ctrl+alt+4 | | +| Ctrl+Shift+Alt+Digit4 | --- | Ctrl+Shift+Alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit5 | 5 | 5 | 5 | 5 | | +| Shift+Digit5 | % | Shift+5 | Shift+5 | shift+5 | | +| Ctrl+Alt+Digit5 | ¢ | Ctrl+Alt+5 | Ctrl+Alt+5 | ctrl+alt+5 | | +| Ctrl+Shift+Alt+Digit5 | --- | Ctrl+Shift+Alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit6 | 6 | 6 | 6 | 6 | | +| Shift+Digit6 | ¨ | Shift+6 | Shift+6 | shift+6 | | +| Ctrl+Alt+Digit6 | ¬ | Ctrl+Alt+6 | Ctrl+Alt+6 | ctrl+alt+6 | | +| Ctrl+Shift+Alt+Digit6 | --- | Ctrl+Shift+Alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit7 | 7 | 7 | 7 | 7 | | +| Shift+Digit7 | & | Shift+7 | Shift+7 | shift+7 | | +| Ctrl+Alt+Digit7 | --- | Ctrl+Alt+7 | Ctrl+Alt+7 | ctrl+alt+7 | | +| Ctrl+Shift+Alt+Digit7 | --- | Ctrl+Shift+Alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit8 | 8 | 8 | 8 | 8 | | +| Shift+Digit8 | * | Shift+8 | Shift+8 | shift+8 | | +| Ctrl+Alt+Digit8 | --- | Ctrl+Alt+8 | Ctrl+Alt+8 | ctrl+alt+8 | | +| Ctrl+Shift+Alt+Digit8 | --- | Ctrl+Shift+Alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit9 | 9 | 9 | 9 | 9 | | +| Shift+Digit9 | ( | Shift+9 | Shift+9 | shift+9 | | +| Ctrl+Alt+Digit9 | --- | Ctrl+Alt+9 | Ctrl+Alt+9 | ctrl+alt+9 | | +| Ctrl+Shift+Alt+Digit9 | --- | Ctrl+Shift+Alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit0 | 0 | 0 | 0 | 0 | | +| Shift+Digit0 | ) | Shift+0 | Shift+0 | shift+0 | | +| Ctrl+Alt+Digit0 | --- | Ctrl+Alt+0 | Ctrl+Alt+0 | ctrl+alt+0 | | +| Ctrl+Shift+Alt+Digit0 | --- | Ctrl+Shift+Alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| Minus | - | - | - | oem_minus | NO | +| Shift+Minus | _ | Shift+- | Shift+- | shift+oem_minus | NO | +| Ctrl+Alt+Minus | --- | Ctrl+Alt+- | Ctrl+Alt+- | ctrl+alt+oem_minus | NO | +| Ctrl+Shift+Alt+Minus | --- | Ctrl+Shift+Alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+oem_minus | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Equal | = | = | = | oem_plus | NO | +| Shift+Equal | + | Shift+= | Shift+= | shift+oem_plus | NO | +| Ctrl+Alt+Equal | § | Ctrl+Alt+= | Ctrl+Alt+= | ctrl+alt+oem_plus | NO | +| Ctrl+Shift+Alt+Equal | --- | Ctrl+Shift+Alt+= | Ctrl+Shift+Alt+= | ctrl+shift+alt+oem_plus | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| BracketLeft | ´ | [ | ´ | oem_4 | NO | +| Shift+BracketLeft | ` | Shift+[ | Shift+´ | shift+oem_4 | NO | +| Ctrl+Alt+BracketLeft | --- | Ctrl+Alt+[ | Ctrl+Alt+´ | ctrl+alt+oem_4 | NO | +| Ctrl+Shift+Alt+BracketLeft | --- | Ctrl+Shift+Alt+[ | Ctrl+Shift+Alt+´ | ctrl+shift+alt+oem_4 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| BracketRight | [ | ] | [ | oem_6 | NO | +| Shift+BracketRight | { | Shift+] | Shift+[ | shift+oem_6 | NO | +| Ctrl+Alt+BracketRight | ª | Ctrl+Alt+] | Ctrl+Alt+[ | ctrl+alt+oem_6 | NO | +| Ctrl+Shift+Alt+BracketRight | --- | Ctrl+Shift+Alt+] | Ctrl+Shift+Alt+[ | ctrl+shift+alt+oem_6 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Backslash | ] | \ | ] | oem_5 | NO | +| Shift+Backslash | } | Shift+\ | Shift+] | shift+oem_5 | NO | +| Ctrl+Alt+Backslash | º | Ctrl+Alt+\ | Ctrl+Alt+] | ctrl+alt+oem_5 | NO | +| Ctrl+Shift+Alt+Backslash | --- | Ctrl+Shift+Alt+\ | Ctrl+Shift+Alt+] | ctrl+shift+alt+oem_5 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlHash | --- | null | null | null | NO | +| Shift+IntlHash | --- | null | null | null | NO | +| Ctrl+Alt+IntlHash | --- | null | null | null | NO | +| Ctrl+Shift+Alt+IntlHash | --- | null | null | null | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| Semicolon | ç | ; | ç | oem_1 | NO | +| Shift+Semicolon | Ç | Shift+; | Shift+ç | shift+oem_1 | NO | +| Ctrl+Alt+Semicolon | --- | Ctrl+Alt+; | Ctrl+Alt+ç | ctrl+alt+oem_1 | NO | +| Ctrl+Shift+Alt+Semicolon | --- | Ctrl+Shift+Alt+; | Ctrl+Shift+Alt+ç | ctrl+shift+alt+oem_1 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Quote | ~ | ' | ~ | oem_7 | NO | +| Shift+Quote | ^ | Shift+' | Shift+~ | shift+oem_7 | NO | +| Ctrl+Alt+Quote | --- | Ctrl+Alt+' | Ctrl+Alt+~ | ctrl+alt+oem_7 | NO | +| Ctrl+Shift+Alt+Quote | --- | Ctrl+Shift+Alt+' | Ctrl+Shift+Alt+~ | ctrl+shift+alt+oem_7 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Backquote | ' | ` | ' | oem_3 | NO | +| Shift+Backquote | " | Shift+` | Shift+' | shift+oem_3 | NO | +| Ctrl+Alt+Backquote | --- | Ctrl+Alt+` | Ctrl+Alt+' | ctrl+alt+oem_3 | NO | +| Ctrl+Shift+Alt+Backquote | --- | Ctrl+Shift+Alt+` | Ctrl+Shift+Alt+' | ctrl+shift+alt+oem_3 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Comma | , | , | , | oem_comma | NO | +| Shift+Comma | < | Shift+, | Shift+, | shift+oem_comma | NO | +| Ctrl+Alt+Comma | --- | Ctrl+Alt+, | Ctrl+Alt+, | ctrl+alt+oem_comma | NO | +| Ctrl+Shift+Alt+Comma | --- | Ctrl+Shift+Alt+, | Ctrl+Shift+Alt+, | ctrl+shift+alt+oem_comma | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Period | . | . | . | oem_period | NO | +| Shift+Period | > | Shift+. | Shift+. | shift+oem_period | NO | +| Ctrl+Alt+Period | --- | Ctrl+Alt+. | Ctrl+Alt+. | ctrl+alt+oem_period | NO | +| Ctrl+Shift+Alt+Period | --- | Ctrl+Shift+Alt+. | Ctrl+Shift+Alt+. | ctrl+shift+alt+oem_period | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Slash | ; | / | ; | oem_2 | NO | +| Shift+Slash | : | Shift+/ | Shift+; | shift+oem_2 | NO | +| Ctrl+Alt+Slash | --- | Ctrl+Alt+/ | Ctrl+Alt+; | ctrl+alt+oem_2 | NO | +| Ctrl+Shift+Alt+Slash | --- | Ctrl+Shift+Alt+/ | Ctrl+Shift+Alt+; | ctrl+shift+alt+oem_2 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| ArrowUp | --- | UpArrow | UpArrow | up | | +| Shift+ArrowUp | --- | Shift+UpArrow | Shift+UpArrow | shift+up | | +| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | Ctrl+Alt+UpArrow | ctrl+alt+up | | +| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Numpad0 | --- | NumPad0 | NumPad0 | numpad0 | | +| Shift+Numpad0 | --- | Shift+NumPad0 | Shift+NumPad0 | shift+numpad0 | | +| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | | +| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlBackslash | \ | OEM_102 | \ | oem_102 | NO | +| Shift+IntlBackslash | | | Shift+OEM_102 | Shift+\ | shift+oem_102 | NO | +| Ctrl+Alt+IntlBackslash | --- | Ctrl+Alt+OEM_102 | Ctrl+Alt+\ | ctrl+alt+oem_102 | NO | +| Ctrl+Shift+Alt+IntlBackslash | --- | Ctrl+Shift+Alt+OEM_102 | Ctrl+Shift+Alt+\ | ctrl+shift+alt+oem_102 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlRo | / | ABNT_C1 | / | abnt_c1 | NO | +| Shift+IntlRo | ? | Shift+ABNT_C1 | Shift+/ | shift+abnt_c1 | NO | +| Ctrl+Alt+IntlRo | ° | Ctrl+Alt+ABNT_C1 | Ctrl+Alt+/ | ctrl+alt+abnt_c1 | NO | +| Ctrl+Shift+Alt+IntlRo | --- | Ctrl+Shift+Alt+ABNT_C1 | Ctrl+Shift+Alt+/ | ctrl+shift+alt+abnt_c1 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlYen | --- | null | null | null | NO | +| Shift+IntlYen | --- | null | null | null | NO | +| Ctrl+Alt+IntlYen | --- | null | null | null | NO | +| Ctrl+Shift+Alt+IntlYen | --- | null | null | null | NO | +----------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/node/win_ru.js b/src/vs/workbench/services/keybinding/test/node/win_ru.js new file mode 100644 index 00000000000..4f024d361eb --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/win_ru.js @@ -0,0 +1,1093 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +define({ + Sleep: { + vkey: 'VK_SLEEP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + WakeUp: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + KeyA: { + vkey: 'VK_A', + value: 'ф', + withShift: 'Ф', + withAltGr: '', + withShiftAltGr: '' + }, + KeyB: { + vkey: 'VK_B', + value: 'и', + withShift: 'И', + withAltGr: '', + withShiftAltGr: '' + }, + KeyC: { + vkey: 'VK_C', + value: 'с', + withShift: 'С', + withAltGr: '', + withShiftAltGr: '' + }, + KeyD: { + vkey: 'VK_D', + value: 'в', + withShift: 'В', + withAltGr: '', + withShiftAltGr: '' + }, + KeyE: { + vkey: 'VK_E', + value: 'у', + withShift: 'У', + withAltGr: '', + withShiftAltGr: '' + }, + KeyF: { + vkey: 'VK_F', + value: 'а', + withShift: 'А', + withAltGr: '', + withShiftAltGr: '' + }, + KeyG: { + vkey: 'VK_G', + value: 'п', + withShift: 'П', + withAltGr: '', + withShiftAltGr: '' + }, + KeyH: { + vkey: 'VK_H', + value: 'р', + withShift: 'Р', + withAltGr: '', + withShiftAltGr: '' + }, + KeyI: { + vkey: 'VK_I', + value: 'ш', + withShift: 'Ш', + withAltGr: '', + withShiftAltGr: '' + }, + KeyJ: { + vkey: 'VK_J', + value: 'о', + withShift: 'О', + withAltGr: '', + withShiftAltGr: '' + }, + KeyK: { + vkey: 'VK_K', + value: 'л', + withShift: 'Л', + withAltGr: '', + withShiftAltGr: '' + }, + KeyL: { + vkey: 'VK_L', + value: 'д', + withShift: 'Д', + withAltGr: '', + withShiftAltGr: '' + }, + KeyM: { + vkey: 'VK_M', + value: 'ь', + withShift: 'Ь', + withAltGr: '', + withShiftAltGr: '' + }, + KeyN: { + vkey: 'VK_N', + value: 'т', + withShift: 'Т', + withAltGr: '', + withShiftAltGr: '' + }, + KeyO: { + vkey: 'VK_O', + value: 'щ', + withShift: 'Щ', + withAltGr: '', + withShiftAltGr: '' + }, + KeyP: { + vkey: 'VK_P', + value: 'з', + withShift: 'З', + withAltGr: '', + withShiftAltGr: '' + }, + KeyQ: { + vkey: 'VK_Q', + value: 'й', + withShift: 'Й', + withAltGr: '', + withShiftAltGr: '' + }, + KeyR: { + vkey: 'VK_R', + value: 'к', + withShift: 'К', + withAltGr: '', + withShiftAltGr: '' + }, + KeyS: { + vkey: 'VK_S', + value: 'ы', + withShift: 'Ы', + withAltGr: '', + withShiftAltGr: '' + }, + KeyT: { + vkey: 'VK_T', + value: 'е', + withShift: 'Е', + withAltGr: '', + withShiftAltGr: '' + }, + KeyU: { + vkey: 'VK_U', + value: 'г', + withShift: 'Г', + withAltGr: '', + withShiftAltGr: '' + }, + KeyV: { + vkey: 'VK_V', + value: 'м', + withShift: 'М', + withAltGr: '', + withShiftAltGr: '' + }, + KeyW: { + vkey: 'VK_W', + value: 'ц', + withShift: 'Ц', + withAltGr: '', + withShiftAltGr: '' + }, + KeyX: { + vkey: 'VK_X', + value: 'ч', + withShift: 'Ч', + withAltGr: '', + withShiftAltGr: '' + }, + KeyY: { + vkey: 'VK_Y', + value: 'н', + withShift: 'Н', + withAltGr: '', + withShiftAltGr: '' + }, + KeyZ: { + vkey: 'VK_Z', + value: 'я', + withShift: 'Я', + withAltGr: '', + withShiftAltGr: '' + }, + Digit1: { + vkey: 'VK_1', + value: '1', + withShift: '!', + withAltGr: '', + withShiftAltGr: '' + }, + Digit2: { + vkey: 'VK_2', + value: '2', + withShift: '\"', + withAltGr: '', + withShiftAltGr: '' + }, + Digit3: { + vkey: 'VK_3', + value: '3', + withShift: '№', + withAltGr: '', + withShiftAltGr: '' + }, + Digit4: { + vkey: 'VK_4', + value: '4', + withShift: ';', + withAltGr: '', + withShiftAltGr: '' + }, + Digit5: { + vkey: 'VK_5', + value: '5', + withShift: '%', + withAltGr: '', + withShiftAltGr: '' + }, + Digit6: { + vkey: 'VK_6', + value: '6', + withShift: ':', + withAltGr: '', + withShiftAltGr: '' + }, + Digit7: { + vkey: 'VK_7', + value: '7', + withShift: '?', + withAltGr: '', + withShiftAltGr: '' + }, + Digit8: { + vkey: 'VK_8', + value: '8', + withShift: '*', + withAltGr: '₽', + withShiftAltGr: '' + }, + Digit9: { + vkey: 'VK_9', + value: '9', + withShift: '(', + withAltGr: '', + withShiftAltGr: '' + }, + Digit0: { + vkey: 'VK_0', + value: '0', + withShift: ')', + withAltGr: '', + withShiftAltGr: '' + }, + Enter: { + vkey: 'VK_RETURN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Escape: { + vkey: 'VK_ESCAPE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Backspace: { + vkey: 'VK_BACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Tab: { + vkey: 'VK_TAB', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Space: { + vkey: 'VK_SPACE', + value: ' ', + withShift: ' ', + withAltGr: '', + withShiftAltGr: '' + }, + Minus: { + vkey: 'VK_OEM_MINUS', + value: '-', + withShift: '_', + withAltGr: '', + withShiftAltGr: '' + }, + Equal: { + vkey: 'VK_OEM_PLUS', + value: '=', + withShift: '+', + withAltGr: '', + withShiftAltGr: '' + }, + BracketLeft: { + vkey: 'VK_OEM_4', + value: 'х', + withShift: 'Х', + withAltGr: '', + withShiftAltGr: '' + }, + BracketRight: { + vkey: 'VK_OEM_6', + value: 'ъ', + withShift: 'Ъ', + withAltGr: '', + withShiftAltGr: '' + }, + Backslash: { + vkey: 'VK_OEM_5', + value: '\\', + withShift: '/', + withAltGr: '', + withShiftAltGr: '' + }, + Semicolon: { + vkey: 'VK_OEM_1', + value: 'ж', + withShift: 'Ж', + withAltGr: '', + withShiftAltGr: '' + }, + Quote: { + vkey: 'VK_OEM_7', + value: 'э', + withShift: 'Э', + withAltGr: '', + withShiftAltGr: '' + }, + Backquote: { + vkey: 'VK_OEM_3', + value: 'ё', + withShift: 'Ё', + withAltGr: '', + withShiftAltGr: '' + }, + Comma: { + vkey: 'VK_OEM_COMMA', + value: 'б', + withShift: 'Б', + withAltGr: '', + withShiftAltGr: '' + }, + Period: { + vkey: 'VK_OEM_PERIOD', + value: 'ю', + withShift: 'Ю', + withAltGr: '', + withShiftAltGr: '' + }, + Slash: { + vkey: 'VK_OEM_2', + value: '.', + withShift: ',', + withAltGr: '', + withShiftAltGr: '' + }, + CapsLock: { + vkey: 'VK_CAPITAL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F1: { + vkey: 'VK_F1', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F2: { + vkey: 'VK_F2', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F3: { + vkey: 'VK_F3', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F4: { + vkey: 'VK_F4', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F5: { + vkey: 'VK_F5', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F6: { + vkey: 'VK_F6', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F7: { + vkey: 'VK_F7', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F8: { + vkey: 'VK_F8', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F9: { + vkey: 'VK_F9', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F10: { + vkey: 'VK_F10', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F11: { + vkey: 'VK_F11', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F12: { + vkey: 'VK_F12', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PrintScreen: { + vkey: 'VK_SNAPSHOT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ScrollLock: { + vkey: 'VK_SCROLL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Pause: { + vkey: 'VK_NUMLOCK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Insert: { + vkey: 'VK_INSERT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Home: { + vkey: 'VK_HOME', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PageUp: { + vkey: 'VK_PRIOR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Delete: { + vkey: 'VK_DELETE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + End: { + vkey: 'VK_END', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + PageDown: { + vkey: 'VK_NEXT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowRight: { + vkey: 'VK_RIGHT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowLeft: { + vkey: 'VK_LEFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowDown: { + vkey: 'VK_DOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ArrowUp: { + vkey: 'VK_UP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumLock: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadDivide: { + vkey: 'VK_DIVIDE', + value: '/', + withShift: '/', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadMultiply: { + vkey: 'VK_MULTIPLY', + value: '*', + withShift: '*', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadSubtract: { + vkey: 'VK_SUBTRACT', + value: '-', + withShift: '-', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadAdd: { + vkey: 'VK_ADD', + value: '+', + withShift: '+', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadEnter: { + vkey: 'VK_RETURN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad1: { + vkey: 'VK_END', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad2: { + vkey: 'VK_DOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad3: { + vkey: 'VK_NEXT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad4: { + vkey: 'VK_LEFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad5: { + vkey: 'VK_CLEAR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad6: { + vkey: 'VK_RIGHT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad7: { + vkey: 'VK_HOME', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad8: { + vkey: 'VK_UP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad9: { + vkey: 'VK_PRIOR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Numpad0: { + vkey: 'VK_INSERT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadDecimal: { + vkey: 'VK_DELETE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + IntlBackslash: { + vkey: 'VK_OEM_102', + value: '\\', + withShift: '/', + withAltGr: '', + withShiftAltGr: '' + }, + ContextMenu: { + vkey: 'VK_APPS', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Power: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadEqual: { + vkey: 'VK_CLEAR', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F13: { + vkey: 'VK_F13', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F14: { + vkey: 'VK_F14', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F15: { + vkey: 'VK_F15', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F16: { + vkey: 'VK_F16', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F17: { + vkey: 'VK_F17', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F18: { + vkey: 'VK_F18', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F19: { + vkey: 'VK_F19', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F20: { + vkey: 'VK_F20', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F21: { + vkey: 'VK_F21', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F22: { + vkey: 'VK_F22', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F23: { + vkey: 'VK_F23', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + F24: { + vkey: 'VK_F24', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Help: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Undo: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Cut: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Copy: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Paste: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeMute: { + vkey: 'VK_VOLUME_MUTE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeUp: { + vkey: 'VK_VOLUME_UP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AudioVolumeDown: { + vkey: 'VK_VOLUME_DOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NumpadComma: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + IntlRo: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + KanaMode: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + IntlYen: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Convert: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + NonConvert: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang1: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang2: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang3: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Lang4: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ControlLeft: { + vkey: 'VK_CONTROL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ShiftLeft: { + vkey: 'VK_SHIFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AltLeft: { + vkey: 'VK_MENU', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MetaLeft: { + vkey: 'VK_LWIN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ControlRight: { + vkey: 'VK_CONTROL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + ShiftRight: { + vkey: 'VK_SHIFT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + AltRight: { + vkey: 'VK_MENU', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MetaRight: { + vkey: 'VK_RWIN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaTrackNext: { + vkey: 'VK_MEDIA_NEXT_TRACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaTrackPrevious: { + vkey: 'VK_MEDIA_PREV_TRACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaStop: { + vkey: 'VK_MEDIA_STOP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + Eject: { + vkey: 'VK_UNKNOWN', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaPlayPause: { + vkey: 'VK_MEDIA_PLAY_PAUSE', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + MediaSelect: { + vkey: 'VK_LAUNCH_MEDIA_SELECT', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchMail: { + vkey: 'VK_LAUNCH_MAIL', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchApp2: { + vkey: 'VK_LAUNCH_APP2', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + LaunchApp1: { + vkey: 'VK_LAUNCH_APP1', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserSearch: { + vkey: 'VK_BROWSER_SEARCH', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserHome: { + vkey: 'VK_BROWSER_HOME', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserBack: { + vkey: 'VK_BROWSER_BACK', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserForward: { + vkey: 'VK_BROWSER_FORWARD', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserStop: { + vkey: 'VK_BROWSER_STOP', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserRefresh: { + vkey: 'VK_BROWSER_REFRESH', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + }, + BrowserFavorites: { + vkey: 'VK_BROWSER_FAVORITES', + value: '', + withShift: '', + withAltGr: '', + withShiftAltGr: '' + } +}); diff --git a/src/vs/workbench/services/keybinding/test/node/win_ru.txt b/src/vs/workbench/services/keybinding/test/node/win_ru.txt new file mode 100644 index 00000000000..61af5ab16e7 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/win_ru.txt @@ -0,0 +1,284 @@ +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyA | ф | A | A | a | | +| Shift+KeyA | Ф | Shift+A | Shift+A | shift+a | | +| Ctrl+Alt+KeyA | --- | Ctrl+Alt+A | Ctrl+Alt+A | ctrl+alt+a | | +| Ctrl+Shift+Alt+KeyA | --- | Ctrl+Shift+Alt+A | Ctrl+Shift+Alt+A | ctrl+shift+alt+a | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyB | и | B | B | b | | +| Shift+KeyB | И | Shift+B | Shift+B | shift+b | | +| Ctrl+Alt+KeyB | --- | Ctrl+Alt+B | Ctrl+Alt+B | ctrl+alt+b | | +| Ctrl+Shift+Alt+KeyB | --- | Ctrl+Shift+Alt+B | Ctrl+Shift+Alt+B | ctrl+shift+alt+b | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyC | с | C | C | c | | +| Shift+KeyC | С | Shift+C | Shift+C | shift+c | | +| Ctrl+Alt+KeyC | --- | Ctrl+Alt+C | Ctrl+Alt+C | ctrl+alt+c | | +| Ctrl+Shift+Alt+KeyC | --- | Ctrl+Shift+Alt+C | Ctrl+Shift+Alt+C | ctrl+shift+alt+c | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyD | в | D | D | d | | +| Shift+KeyD | В | Shift+D | Shift+D | shift+d | | +| Ctrl+Alt+KeyD | --- | Ctrl+Alt+D | Ctrl+Alt+D | ctrl+alt+d | | +| Ctrl+Shift+Alt+KeyD | --- | Ctrl+Shift+Alt+D | Ctrl+Shift+Alt+D | ctrl+shift+alt+d | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyE | у | E | E | e | | +| Shift+KeyE | У | Shift+E | Shift+E | shift+e | | +| Ctrl+Alt+KeyE | --- | Ctrl+Alt+E | Ctrl+Alt+E | ctrl+alt+e | | +| Ctrl+Shift+Alt+KeyE | --- | Ctrl+Shift+Alt+E | Ctrl+Shift+Alt+E | ctrl+shift+alt+e | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyF | а | F | F | f | | +| Shift+KeyF | А | Shift+F | Shift+F | shift+f | | +| Ctrl+Alt+KeyF | --- | Ctrl+Alt+F | Ctrl+Alt+F | ctrl+alt+f | | +| Ctrl+Shift+Alt+KeyF | --- | Ctrl+Shift+Alt+F | Ctrl+Shift+Alt+F | ctrl+shift+alt+f | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyG | п | G | G | g | | +| Shift+KeyG | П | Shift+G | Shift+G | shift+g | | +| Ctrl+Alt+KeyG | --- | Ctrl+Alt+G | Ctrl+Alt+G | ctrl+alt+g | | +| Ctrl+Shift+Alt+KeyG | --- | Ctrl+Shift+Alt+G | Ctrl+Shift+Alt+G | ctrl+shift+alt+g | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyH | р | H | H | h | | +| Shift+KeyH | Р | Shift+H | Shift+H | shift+h | | +| Ctrl+Alt+KeyH | --- | Ctrl+Alt+H | Ctrl+Alt+H | ctrl+alt+h | | +| Ctrl+Shift+Alt+KeyH | --- | Ctrl+Shift+Alt+H | Ctrl+Shift+Alt+H | ctrl+shift+alt+h | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyI | ш | I | I | i | | +| Shift+KeyI | Ш | Shift+I | Shift+I | shift+i | | +| Ctrl+Alt+KeyI | --- | Ctrl+Alt+I | Ctrl+Alt+I | ctrl+alt+i | | +| Ctrl+Shift+Alt+KeyI | --- | Ctrl+Shift+Alt+I | Ctrl+Shift+Alt+I | ctrl+shift+alt+i | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyJ | о | J | J | j | | +| Shift+KeyJ | О | Shift+J | Shift+J | shift+j | | +| Ctrl+Alt+KeyJ | --- | Ctrl+Alt+J | Ctrl+Alt+J | ctrl+alt+j | | +| Ctrl+Shift+Alt+KeyJ | --- | Ctrl+Shift+Alt+J | Ctrl+Shift+Alt+J | ctrl+shift+alt+j | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyK | л | K | K | k | | +| Shift+KeyK | Л | Shift+K | Shift+K | shift+k | | +| Ctrl+Alt+KeyK | --- | Ctrl+Alt+K | Ctrl+Alt+K | ctrl+alt+k | | +| Ctrl+Shift+Alt+KeyK | --- | Ctrl+Shift+Alt+K | Ctrl+Shift+Alt+K | ctrl+shift+alt+k | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyL | д | L | L | l | | +| Shift+KeyL | Д | Shift+L | Shift+L | shift+l | | +| Ctrl+Alt+KeyL | --- | Ctrl+Alt+L | Ctrl+Alt+L | ctrl+alt+l | | +| Ctrl+Shift+Alt+KeyL | --- | Ctrl+Shift+Alt+L | Ctrl+Shift+Alt+L | ctrl+shift+alt+l | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyM | ь | M | M | m | | +| Shift+KeyM | Ь | Shift+M | Shift+M | shift+m | | +| Ctrl+Alt+KeyM | --- | Ctrl+Alt+M | Ctrl+Alt+M | ctrl+alt+m | | +| Ctrl+Shift+Alt+KeyM | --- | Ctrl+Shift+Alt+M | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyN | т | N | N | n | | +| Shift+KeyN | Т | Shift+N | Shift+N | shift+n | | +| Ctrl+Alt+KeyN | --- | Ctrl+Alt+N | Ctrl+Alt+N | ctrl+alt+n | | +| Ctrl+Shift+Alt+KeyN | --- | Ctrl+Shift+Alt+N | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyO | щ | O | O | o | | +| Shift+KeyO | Щ | Shift+O | Shift+O | shift+o | | +| Ctrl+Alt+KeyO | --- | Ctrl+Alt+O | Ctrl+Alt+O | ctrl+alt+o | | +| Ctrl+Shift+Alt+KeyO | --- | Ctrl+Shift+Alt+O | Ctrl+Shift+Alt+O | ctrl+shift+alt+o | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyP | з | P | P | p | | +| Shift+KeyP | З | Shift+P | Shift+P | shift+p | | +| Ctrl+Alt+KeyP | --- | Ctrl+Alt+P | Ctrl+Alt+P | ctrl+alt+p | | +| Ctrl+Shift+Alt+KeyP | --- | Ctrl+Shift+Alt+P | Ctrl+Shift+Alt+P | ctrl+shift+alt+p | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyQ | й | Q | Q | q | | +| Shift+KeyQ | Й | Shift+Q | Shift+Q | shift+q | | +| Ctrl+Alt+KeyQ | --- | Ctrl+Alt+Q | Ctrl+Alt+Q | ctrl+alt+q | | +| Ctrl+Shift+Alt+KeyQ | --- | Ctrl+Shift+Alt+Q | Ctrl+Shift+Alt+Q | ctrl+shift+alt+q | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyR | к | R | R | r | | +| Shift+KeyR | К | Shift+R | Shift+R | shift+r | | +| Ctrl+Alt+KeyR | --- | Ctrl+Alt+R | Ctrl+Alt+R | ctrl+alt+r | | +| Ctrl+Shift+Alt+KeyR | --- | Ctrl+Shift+Alt+R | Ctrl+Shift+Alt+R | ctrl+shift+alt+r | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyS | ы | S | S | s | | +| Shift+KeyS | Ы | Shift+S | Shift+S | shift+s | | +| Ctrl+Alt+KeyS | --- | Ctrl+Alt+S | Ctrl+Alt+S | ctrl+alt+s | | +| Ctrl+Shift+Alt+KeyS | --- | Ctrl+Shift+Alt+S | Ctrl+Shift+Alt+S | ctrl+shift+alt+s | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyT | е | T | T | t | | +| Shift+KeyT | Е | Shift+T | Shift+T | shift+t | | +| Ctrl+Alt+KeyT | --- | Ctrl+Alt+T | Ctrl+Alt+T | ctrl+alt+t | | +| Ctrl+Shift+Alt+KeyT | --- | Ctrl+Shift+Alt+T | Ctrl+Shift+Alt+T | ctrl+shift+alt+t | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyU | г | U | U | u | | +| Shift+KeyU | Г | Shift+U | Shift+U | shift+u | | +| Ctrl+Alt+KeyU | --- | Ctrl+Alt+U | Ctrl+Alt+U | ctrl+alt+u | | +| Ctrl+Shift+Alt+KeyU | --- | Ctrl+Shift+Alt+U | Ctrl+Shift+Alt+U | ctrl+shift+alt+u | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyV | м | V | V | v | | +| Shift+KeyV | М | Shift+V | Shift+V | shift+v | | +| Ctrl+Alt+KeyV | --- | Ctrl+Alt+V | Ctrl+Alt+V | ctrl+alt+v | | +| Ctrl+Shift+Alt+KeyV | --- | Ctrl+Shift+Alt+V | Ctrl+Shift+Alt+V | ctrl+shift+alt+v | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyW | ц | W | W | w | | +| Shift+KeyW | Ц | Shift+W | Shift+W | shift+w | | +| Ctrl+Alt+KeyW | --- | Ctrl+Alt+W | Ctrl+Alt+W | ctrl+alt+w | | +| Ctrl+Shift+Alt+KeyW | --- | Ctrl+Shift+Alt+W | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyX | ч | X | X | x | | +| Shift+KeyX | Ч | Shift+X | Shift+X | shift+x | | +| Ctrl+Alt+KeyX | --- | Ctrl+Alt+X | Ctrl+Alt+X | ctrl+alt+x | | +| Ctrl+Shift+Alt+KeyX | --- | Ctrl+Shift+Alt+X | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyY | н | Y | Y | y | | +| Shift+KeyY | Н | Shift+Y | Shift+Y | shift+y | | +| Ctrl+Alt+KeyY | --- | Ctrl+Alt+Y | Ctrl+Alt+Y | ctrl+alt+y | | +| Ctrl+Shift+Alt+KeyY | --- | Ctrl+Shift+Alt+Y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | | +----------------------------------------------------------------------------------------------------------------------------------------- +| KeyZ | я | Z | Z | z | | +| Shift+KeyZ | Я | Shift+Z | Shift+Z | shift+z | | +| Ctrl+Alt+KeyZ | --- | Ctrl+Alt+Z | Ctrl+Alt+Z | ctrl+alt+z | | +| Ctrl+Shift+Alt+KeyZ | --- | Ctrl+Shift+Alt+Z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit1 | 1 | 1 | 1 | 1 | | +| Shift+Digit1 | ! | Shift+1 | Shift+1 | shift+1 | | +| Ctrl+Alt+Digit1 | --- | Ctrl+Alt+1 | Ctrl+Alt+1 | ctrl+alt+1 | | +| Ctrl+Shift+Alt+Digit1 | --- | Ctrl+Shift+Alt+1 | Ctrl+Shift+Alt+1 | ctrl+shift+alt+1 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit2 | 2 | 2 | 2 | 2 | | +| Shift+Digit2 | " | Shift+2 | Shift+2 | shift+2 | | +| Ctrl+Alt+Digit2 | --- | Ctrl+Alt+2 | Ctrl+Alt+2 | ctrl+alt+2 | | +| Ctrl+Shift+Alt+Digit2 | --- | Ctrl+Shift+Alt+2 | Ctrl+Shift+Alt+2 | ctrl+shift+alt+2 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit3 | 3 | 3 | 3 | 3 | | +| Shift+Digit3 | № | Shift+3 | Shift+3 | shift+3 | | +| Ctrl+Alt+Digit3 | --- | Ctrl+Alt+3 | Ctrl+Alt+3 | ctrl+alt+3 | | +| Ctrl+Shift+Alt+Digit3 | --- | Ctrl+Shift+Alt+3 | Ctrl+Shift+Alt+3 | ctrl+shift+alt+3 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit4 | 4 | 4 | 4 | 4 | | +| Shift+Digit4 | ; | Shift+4 | Shift+4 | shift+4 | | +| Ctrl+Alt+Digit4 | --- | Ctrl+Alt+4 | Ctrl+Alt+4 | ctrl+alt+4 | | +| Ctrl+Shift+Alt+Digit4 | --- | Ctrl+Shift+Alt+4 | Ctrl+Shift+Alt+4 | ctrl+shift+alt+4 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit5 | 5 | 5 | 5 | 5 | | +| Shift+Digit5 | % | Shift+5 | Shift+5 | shift+5 | | +| Ctrl+Alt+Digit5 | --- | Ctrl+Alt+5 | Ctrl+Alt+5 | ctrl+alt+5 | | +| Ctrl+Shift+Alt+Digit5 | --- | Ctrl+Shift+Alt+5 | Ctrl+Shift+Alt+5 | ctrl+shift+alt+5 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit6 | 6 | 6 | 6 | 6 | | +| Shift+Digit6 | : | Shift+6 | Shift+6 | shift+6 | | +| Ctrl+Alt+Digit6 | --- | Ctrl+Alt+6 | Ctrl+Alt+6 | ctrl+alt+6 | | +| Ctrl+Shift+Alt+Digit6 | --- | Ctrl+Shift+Alt+6 | Ctrl+Shift+Alt+6 | ctrl+shift+alt+6 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit7 | 7 | 7 | 7 | 7 | | +| Shift+Digit7 | ? | Shift+7 | Shift+7 | shift+7 | | +| Ctrl+Alt+Digit7 | --- | Ctrl+Alt+7 | Ctrl+Alt+7 | ctrl+alt+7 | | +| Ctrl+Shift+Alt+Digit7 | --- | Ctrl+Shift+Alt+7 | Ctrl+Shift+Alt+7 | ctrl+shift+alt+7 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit8 | 8 | 8 | 8 | 8 | | +| Shift+Digit8 | * | Shift+8 | Shift+8 | shift+8 | | +| Ctrl+Alt+Digit8 | ₽ | Ctrl+Alt+8 | Ctrl+Alt+8 | ctrl+alt+8 | | +| Ctrl+Shift+Alt+Digit8 | --- | Ctrl+Shift+Alt+8 | Ctrl+Shift+Alt+8 | ctrl+shift+alt+8 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit9 | 9 | 9 | 9 | 9 | | +| Shift+Digit9 | ( | Shift+9 | Shift+9 | shift+9 | | +| Ctrl+Alt+Digit9 | --- | Ctrl+Alt+9 | Ctrl+Alt+9 | ctrl+alt+9 | | +| Ctrl+Shift+Alt+Digit9 | --- | Ctrl+Shift+Alt+9 | Ctrl+Shift+Alt+9 | ctrl+shift+alt+9 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Digit0 | 0 | 0 | 0 | 0 | | +| Shift+Digit0 | ) | Shift+0 | Shift+0 | shift+0 | | +| Ctrl+Alt+Digit0 | --- | Ctrl+Alt+0 | Ctrl+Alt+0 | ctrl+alt+0 | | +| Ctrl+Shift+Alt+Digit0 | --- | Ctrl+Shift+Alt+0 | Ctrl+Shift+Alt+0 | ctrl+shift+alt+0 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| Minus | - | - | - | oem_minus | NO | +| Shift+Minus | _ | Shift+- | Shift+- | shift+oem_minus | NO | +| Ctrl+Alt+Minus | --- | Ctrl+Alt+- | Ctrl+Alt+- | ctrl+alt+oem_minus | NO | +| Ctrl+Shift+Alt+Minus | --- | Ctrl+Shift+Alt+- | Ctrl+Shift+Alt+- | ctrl+shift+alt+oem_minus | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Equal | = | = | = | oem_plus | NO | +| Shift+Equal | + | Shift+= | Shift+= | shift+oem_plus | NO | +| Ctrl+Alt+Equal | --- | Ctrl+Alt+= | Ctrl+Alt+= | ctrl+alt+oem_plus | NO | +| Ctrl+Shift+Alt+Equal | --- | Ctrl+Shift+Alt+= | Ctrl+Shift+Alt+= | ctrl+shift+alt+oem_plus | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| BracketLeft | х | [ | [ | oem_4 | NO | +| Shift+BracketLeft | Х | Shift+[ | Shift+[ | shift+oem_4 | NO | +| Ctrl+Alt+BracketLeft | --- | Ctrl+Alt+[ | Ctrl+Alt+[ | ctrl+alt+oem_4 | NO | +| Ctrl+Shift+Alt+BracketLeft | --- | Ctrl+Shift+Alt+[ | Ctrl+Shift+Alt+[ | ctrl+shift+alt+oem_4 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| BracketRight | ъ | ] | ] | oem_6 | NO | +| Shift+BracketRight | Ъ | Shift+] | Shift+] | shift+oem_6 | NO | +| Ctrl+Alt+BracketRight | --- | Ctrl+Alt+] | Ctrl+Alt+] | ctrl+alt+oem_6 | NO | +| Ctrl+Shift+Alt+BracketRight | --- | Ctrl+Shift+Alt+] | Ctrl+Shift+Alt+] | ctrl+shift+alt+oem_6 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Backslash | \ | \ | \ | oem_5 | NO | +| Shift+Backslash | / | Shift+\ | Shift+\ | shift+oem_5 | NO | +| Ctrl+Alt+Backslash | --- | Ctrl+Alt+\ | Ctrl+Alt+\ | ctrl+alt+oem_5 | NO | +| Ctrl+Shift+Alt+Backslash | --- | Ctrl+Shift+Alt+\ | Ctrl+Shift+Alt+\ | ctrl+shift+alt+oem_5 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlHash | --- | null | null | null | NO | +| Shift+IntlHash | --- | null | null | null | NO | +| Ctrl+Alt+IntlHash | --- | null | null | null | NO | +| Ctrl+Shift+Alt+IntlHash | --- | null | null | null | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| Semicolon | ж | ; | ; | oem_1 | NO | +| Shift+Semicolon | Ж | Shift+; | Shift+; | shift+oem_1 | NO | +| Ctrl+Alt+Semicolon | --- | Ctrl+Alt+; | Ctrl+Alt+; | ctrl+alt+oem_1 | NO | +| Ctrl+Shift+Alt+Semicolon | --- | Ctrl+Shift+Alt+; | Ctrl+Shift+Alt+; | ctrl+shift+alt+oem_1 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Quote | э | ' | ' | oem_7 | NO | +| Shift+Quote | Э | Shift+' | Shift+' | shift+oem_7 | NO | +| Ctrl+Alt+Quote | --- | Ctrl+Alt+' | Ctrl+Alt+' | ctrl+alt+oem_7 | NO | +| Ctrl+Shift+Alt+Quote | --- | Ctrl+Shift+Alt+' | Ctrl+Shift+Alt+' | ctrl+shift+alt+oem_7 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Backquote | ё | ` | ` | oem_3 | NO | +| Shift+Backquote | Ё | Shift+` | Shift+` | shift+oem_3 | NO | +| Ctrl+Alt+Backquote | --- | Ctrl+Alt+` | Ctrl+Alt+` | ctrl+alt+oem_3 | NO | +| Ctrl+Shift+Alt+Backquote | --- | Ctrl+Shift+Alt+` | Ctrl+Shift+Alt+` | ctrl+shift+alt+oem_3 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Comma | б | , | , | oem_comma | NO | +| Shift+Comma | Б | Shift+, | Shift+, | shift+oem_comma | NO | +| Ctrl+Alt+Comma | --- | Ctrl+Alt+, | Ctrl+Alt+, | ctrl+alt+oem_comma | NO | +| Ctrl+Shift+Alt+Comma | --- | Ctrl+Shift+Alt+, | Ctrl+Shift+Alt+, | ctrl+shift+alt+oem_comma | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Period | ю | . | . | oem_period | NO | +| Shift+Period | Ю | Shift+. | Shift+. | shift+oem_period | NO | +| Ctrl+Alt+Period | --- | Ctrl+Alt+. | Ctrl+Alt+. | ctrl+alt+oem_period | NO | +| Ctrl+Shift+Alt+Period | --- | Ctrl+Shift+Alt+. | Ctrl+Shift+Alt+. | ctrl+shift+alt+oem_period | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| Slash | . | / | / | oem_2 | NO | +| Shift+Slash | , | Shift+/ | Shift+/ | shift+oem_2 | NO | +| Ctrl+Alt+Slash | --- | Ctrl+Alt+/ | Ctrl+Alt+/ | ctrl+alt+oem_2 | NO | +| Ctrl+Shift+Alt+Slash | --- | Ctrl+Shift+Alt+/ | Ctrl+Shift+Alt+/ | ctrl+shift+alt+oem_2 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| HW Code combination | Key | KeyCode combination | UI label | User settings | WYSIWYG | +----------------------------------------------------------------------------------------------------------------------------------------- +| ArrowUp | --- | UpArrow | UpArrow | up | | +| Shift+ArrowUp | --- | Shift+UpArrow | Shift+UpArrow | shift+up | | +| Ctrl+Alt+ArrowUp | --- | Ctrl+Alt+UpArrow | Ctrl+Alt+UpArrow | ctrl+alt+up | | +| Ctrl+Shift+Alt+ArrowUp | --- | Ctrl+Shift+Alt+UpArrow | Ctrl+Shift+Alt+UpArrow | ctrl+shift+alt+up | | +----------------------------------------------------------------------------------------------------------------------------------------- +| Numpad0 | --- | NumPad0 | NumPad0 | numpad0 | | +| Shift+Numpad0 | --- | Shift+NumPad0 | Shift+NumPad0 | shift+numpad0 | | +| Ctrl+Alt+Numpad0 | --- | Ctrl+Alt+NumPad0 | Ctrl+Alt+NumPad0 | ctrl+alt+numpad0 | | +| Ctrl+Shift+Alt+Numpad0 | --- | Ctrl+Shift+Alt+NumPad0 | Ctrl+Shift+Alt+NumPad0 | ctrl+shift+alt+numpad0 | | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlBackslash | \ | OEM_102 | \ | oem_102 | NO | +| Shift+IntlBackslash | / | Shift+OEM_102 | Shift+\ | shift+oem_102 | NO | +| Ctrl+Alt+IntlBackslash | --- | Ctrl+Alt+OEM_102 | Ctrl+Alt+\ | ctrl+alt+oem_102 | NO | +| Ctrl+Shift+Alt+IntlBackslash | --- | Ctrl+Shift+Alt+OEM_102 | Ctrl+Shift+Alt+\ | ctrl+shift+alt+oem_102 | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlRo | --- | null | null | null | NO | +| Shift+IntlRo | --- | null | null | null | NO | +| Ctrl+Alt+IntlRo | --- | null | null | null | NO | +| Ctrl+Shift+Alt+IntlRo | --- | null | null | null | NO | +----------------------------------------------------------------------------------------------------------------------------------------- +| IntlYen | --- | null | null | null | NO | +| Shift+IntlYen | --- | null | null | null | NO | +| Ctrl+Alt+IntlYen | --- | null | null | null | NO | +| Ctrl+Shift+Alt+IntlYen | --- | null | null | null | NO | +----------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/node/windowsKeyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/node/windowsKeyboardMapper.test.ts new file mode 100644 index 00000000000..371d9b15f31 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/node/windowsKeyboardMapper.test.ts @@ -0,0 +1,658 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyChord, KeyCode, KeyMod, ScanCode } from 'vs/base/common/keyCodes'; +import { SimpleKeybinding, createKeybinding, ScanCodeBinding } from 'vs/base/common/keybindings'; +import { OperatingSystem } from 'vs/base/common/platform'; +import { WindowsKeyboardMapper } from 'vs/workbench/services/keybinding/common/windowsKeyboardMapper'; +import { IResolvedKeybinding, assertMapping, assertResolveKeybinding, assertResolveKeyboardEvent, assertResolveUserBinding, readRawMapping } from 'vs/workbench/services/keybinding/test/node/keyboardMapperTestUtils'; +import { IWindowsKeyboardMapping } from 'vs/platform/keyboardLayout/common/keyboardLayout'; + +const WRITE_FILE_IF_DIFFERENT = false; + +async function createKeyboardMapper(isUSStandard: boolean, file: string): Promise { + const rawMappings = await readRawMapping(file); + return new WindowsKeyboardMapper(isUSStandard, rawMappings); +} + +function _assertResolveKeybinding(mapper: WindowsKeyboardMapper, k: number, expected: IResolvedKeybinding[]): void { + const keyBinding = createKeybinding(k, OperatingSystem.Windows); + assertResolveKeybinding(mapper, keyBinding!, expected); +} + +suite('keyboardMapper - WINDOWS de_ch', () => { + + let mapper: WindowsKeyboardMapper; + + suiteSetup(async () => { + mapper = await createKeyboardMapper(false, 'win_de_ch'); + }); + + test('mapping', () => { + return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'win_de_ch.txt'); + }); + + test('resolveKeybinding Ctrl+A', () => { + _assertResolveKeybinding( + mapper, + KeyMod.CtrlCmd | KeyCode.KeyA, + [{ + label: 'Ctrl+A', + ariaLabel: 'Control+A', + electronAccelerator: 'Ctrl+A', + userSettingsLabel: 'ctrl+a', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+A'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+Z', () => { + _assertResolveKeybinding( + mapper, + KeyMod.CtrlCmd | KeyCode.KeyZ, + [{ + label: 'Ctrl+Z', + ariaLabel: 'Control+Z', + electronAccelerator: 'Ctrl+Z', + userSettingsLabel: 'ctrl+z', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+Z'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeyboardEvent Ctrl+Z', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: KeyCode.KeyZ, + code: null! + }, + { + label: 'Ctrl+Z', + ariaLabel: 'Control+Z', + electronAccelerator: 'Ctrl+Z', + userSettingsLabel: 'ctrl+z', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+Z'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveKeybinding Ctrl+]', () => { + _assertResolveKeybinding( + mapper, + KeyMod.CtrlCmd | KeyCode.BracketRight, + [{ + label: 'Ctrl+^', + ariaLabel: 'Control+^', + electronAccelerator: 'Ctrl+]', + userSettingsLabel: 'ctrl+oem_6', + isWYSIWYG: false, + isChord: false, + dispatchParts: ['ctrl+]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeyboardEvent Ctrl+]', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: KeyCode.BracketRight, + code: null! + }, + { + label: 'Ctrl+^', + ariaLabel: 'Control+^', + electronAccelerator: 'Ctrl+]', + userSettingsLabel: 'ctrl+oem_6', + isWYSIWYG: false, + isChord: false, + dispatchParts: ['ctrl+]'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveKeybinding Shift+]', () => { + _assertResolveKeybinding( + mapper, + KeyMod.Shift | KeyCode.BracketRight, + [{ + label: 'Shift+^', + ariaLabel: 'Shift+^', + electronAccelerator: 'Shift+]', + userSettingsLabel: 'shift+oem_6', + isWYSIWYG: false, + isChord: false, + dispatchParts: ['shift+]'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+/', () => { + _assertResolveKeybinding( + mapper, + KeyMod.CtrlCmd | KeyCode.Slash, + [{ + label: 'Ctrl+§', + ariaLabel: 'Control+§', + electronAccelerator: 'Ctrl+/', + userSettingsLabel: 'ctrl+oem_2', + isWYSIWYG: false, + isChord: false, + dispatchParts: ['ctrl+/'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+Shift+/', () => { + _assertResolveKeybinding( + mapper, + KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Slash, + [{ + label: 'Ctrl+Shift+§', + ariaLabel: 'Control+Shift+§', + electronAccelerator: 'Ctrl+Shift+/', + userSettingsLabel: 'ctrl+shift+oem_2', + isWYSIWYG: false, + isChord: false, + dispatchParts: ['ctrl+shift+/'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+K Ctrl+\\', () => { + _assertResolveKeybinding( + mapper, + KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Backslash), + [{ + label: 'Ctrl+K Ctrl+ä', + ariaLabel: 'Control+K Control+ä', + electronAccelerator: null, + userSettingsLabel: 'ctrl+k ctrl+oem_5', + isWYSIWYG: false, + isChord: true, + dispatchParts: ['ctrl+K', 'ctrl+\\'], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveKeybinding Ctrl+K Ctrl+=', () => { + _assertResolveKeybinding( + mapper, + KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Equal), + [] + ); + }); + + test('resolveKeybinding Ctrl+DownArrow', () => { + _assertResolveKeybinding( + mapper, + KeyMod.CtrlCmd | KeyCode.DownArrow, + [{ + label: 'Ctrl+DownArrow', + ariaLabel: 'Control+DownArrow', + electronAccelerator: 'Ctrl+Down', + userSettingsLabel: 'ctrl+down', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+DownArrow'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+NUMPAD_0', () => { + _assertResolveKeybinding( + mapper, + KeyMod.CtrlCmd | KeyCode.Numpad0, + [{ + label: 'Ctrl+NumPad0', + ariaLabel: 'Control+NumPad0', + electronAccelerator: null, + userSettingsLabel: 'ctrl+numpad0', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+NumPad0'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeybinding Ctrl+Home', () => { + _assertResolveKeybinding( + mapper, + KeyMod.CtrlCmd | KeyCode.Home, + [{ + label: 'Ctrl+Home', + ariaLabel: 'Control+Home', + electronAccelerator: 'Ctrl+Home', + userSettingsLabel: 'ctrl+home', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+Home'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeyboardEvent Ctrl+Home', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: KeyCode.Home, + code: null! + }, + { + label: 'Ctrl+Home', + ariaLabel: 'Control+Home', + electronAccelerator: 'Ctrl+Home', + userSettingsLabel: 'ctrl+home', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+Home'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveUserBinding empty', () => { + assertResolveUserBinding(mapper, [], []); + }); + + test('resolveUserBinding Ctrl+[Comma] Ctrl+/', () => { + assertResolveUserBinding( + mapper, [ + new ScanCodeBinding(true, false, false, false, ScanCode.Comma), + new SimpleKeybinding(true, false, false, false, KeyCode.Slash), + ], + [{ + label: 'Ctrl+, Ctrl+§', + ariaLabel: 'Control+, Control+§', + electronAccelerator: null, + userSettingsLabel: 'ctrl+oem_comma ctrl+oem_2', + isWYSIWYG: false, + isChord: true, + dispatchParts: ['ctrl+,', 'ctrl+/'], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveKeyboardEvent Single Modifier Ctrl+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: KeyCode.Ctrl, + code: null! + }, + { + label: 'Ctrl', + ariaLabel: 'Control', + electronAccelerator: null, + userSettingsLabel: 'ctrl', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['ctrl'], + } + ); + }); +}); + +suite('keyboardMapper - WINDOWS en_us', () => { + + let mapper: WindowsKeyboardMapper; + + suiteSetup(async () => { + mapper = await createKeyboardMapper(true, 'win_en_us'); + }); + + test('mapping', () => { + return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'win_en_us.txt'); + }); + + test('resolveKeybinding Ctrl+K Ctrl+\\', () => { + _assertResolveKeybinding( + mapper, + KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Backslash), + [{ + label: 'Ctrl+K Ctrl+\\', + ariaLabel: 'Control+K Control+\\', + electronAccelerator: null, + userSettingsLabel: 'ctrl+k ctrl+\\', + isWYSIWYG: true, + isChord: true, + dispatchParts: ['ctrl+K', 'ctrl+\\'], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveUserBinding Ctrl+[Comma] Ctrl+/', () => { + assertResolveUserBinding( + mapper, [ + new ScanCodeBinding(true, false, false, false, ScanCode.Comma), + new SimpleKeybinding(true, false, false, false, KeyCode.Slash), + ], + [{ + label: 'Ctrl+, Ctrl+/', + ariaLabel: 'Control+, Control+/', + electronAccelerator: null, + userSettingsLabel: 'ctrl+, ctrl+/', + isWYSIWYG: true, + isChord: true, + dispatchParts: ['ctrl+,', 'ctrl+/'], + singleModifierDispatchParts: [null, null], + }] + ); + }); + + test('resolveUserBinding Ctrl+[Comma]', () => { + assertResolveUserBinding( + mapper, [ + new ScanCodeBinding(true, false, false, false, ScanCode.Comma), + ], + [{ + label: 'Ctrl+,', + ariaLabel: 'Control+,', + electronAccelerator: 'Ctrl+,', + userSettingsLabel: 'ctrl+,', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+,'], + singleModifierDispatchParts: [null], + }] + ); + }); + + test('resolveKeyboardEvent Single Modifier Ctrl+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: KeyCode.Ctrl, + code: null! + }, + { + label: 'Ctrl', + ariaLabel: 'Control', + electronAccelerator: null, + userSettingsLabel: 'ctrl', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['ctrl'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier Shift+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: true, + altKey: false, + metaKey: false, + keyCode: KeyCode.Shift, + code: null! + }, + { + label: 'Shift', + ariaLabel: 'Shift', + electronAccelerator: null, + userSettingsLabel: 'shift', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['shift'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier Alt+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: true, + metaKey: false, + keyCode: KeyCode.Alt, + code: null! + }, + { + label: 'Alt', + ariaLabel: 'Alt', + electronAccelerator: null, + userSettingsLabel: 'alt', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['alt'], + } + ); + }); + + test('resolveKeyboardEvent Single Modifier Meta+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: false, + shiftKey: false, + altKey: false, + metaKey: true, + keyCode: KeyCode.Meta, + code: null! + }, + { + label: 'Windows', + ariaLabel: 'Windows', + electronAccelerator: null, + userSettingsLabel: 'win', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: ['meta'], + } + ); + }); + + test('resolveKeyboardEvent Only Modifiers Ctrl+Shift+', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: true, + altKey: false, + metaKey: false, + keyCode: KeyCode.Shift, + code: null! + }, + { + label: 'Ctrl+Shift', + ariaLabel: 'Control+Shift', + electronAccelerator: null, + userSettingsLabel: 'ctrl+shift', + isWYSIWYG: true, + isChord: false, + dispatchParts: [null], + singleModifierDispatchParts: [null], + } + ); + }); +}); + +suite('keyboardMapper - WINDOWS por_ptb', () => { + + let mapper: WindowsKeyboardMapper; + + suiteSetup(async () => { + mapper = await createKeyboardMapper(false, 'win_por_ptb'); + }); + + test('mapping', () => { + return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'win_por_ptb.txt'); + }); + + test('resolveKeyboardEvent Ctrl+[IntlRo]', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: KeyCode.ABNT_C1, + code: null! + }, + { + label: 'Ctrl+/', + ariaLabel: 'Control+/', + electronAccelerator: 'Ctrl+ABNT_C1', + userSettingsLabel: 'ctrl+abnt_c1', + isWYSIWYG: false, + isChord: false, + dispatchParts: ['ctrl+ABNT_C1'], + singleModifierDispatchParts: [null], + } + ); + }); + + test('resolveKeyboardEvent Ctrl+[NumpadComma]', () => { + assertResolveKeyboardEvent( + mapper, + { + _standardKeyboardEventBrand: true, + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: KeyCode.ABNT_C2, + code: null! + }, + { + label: 'Ctrl+.', + ariaLabel: 'Control+.', + electronAccelerator: 'Ctrl+ABNT_C2', + userSettingsLabel: 'ctrl+abnt_c2', + isWYSIWYG: false, + isChord: false, + dispatchParts: ['ctrl+ABNT_C2'], + singleModifierDispatchParts: [null], + } + ); + }); +}); + +suite('keyboardMapper - WINDOWS ru', () => { + + let mapper: WindowsKeyboardMapper; + + suiteSetup(async () => { + mapper = await createKeyboardMapper(false, 'win_ru'); + }); + + test('mapping', () => { + return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'win_ru.txt'); + }); + + test('issue ##24361: resolveKeybinding Ctrl+K Ctrl+K', () => { + _assertResolveKeybinding( + mapper, + KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyK), + [{ + label: 'Ctrl+K Ctrl+K', + ariaLabel: 'Control+K Control+K', + electronAccelerator: null, + userSettingsLabel: 'ctrl+k ctrl+k', + isWYSIWYG: true, + isChord: true, + dispatchParts: ['ctrl+K', 'ctrl+K'], + singleModifierDispatchParts: [null, null], + }] + ); + }); +}); + +suite('keyboardMapper - misc', () => { + test('issue #23513: Toggle Sidebar Visibility and Go to Line display same key mapping in Arabic keyboard', () => { + const mapper = new WindowsKeyboardMapper(false, { + 'KeyB': { + 'vkey': 'VK_B', + 'value': 'لا', + 'withShift': 'لآ', + 'withAltGr': '', + 'withShiftAltGr': '' + }, + 'KeyG': { + 'vkey': 'VK_G', + 'value': 'ل', + 'withShift': 'لأ', + 'withAltGr': '', + 'withShiftAltGr': '' + } + }); + + _assertResolveKeybinding( + mapper, + KeyMod.CtrlCmd | KeyCode.KeyB, + [{ + label: 'Ctrl+B', + ariaLabel: 'Control+B', + electronAccelerator: 'Ctrl+B', + userSettingsLabel: 'ctrl+b', + isWYSIWYG: true, + isChord: false, + dispatchParts: ['ctrl+B'], + singleModifierDispatchParts: [null], + }] + ); + }); +}); -- cgit v1.2.3 From 26852e0bcdec25c2f44fabd1ae9dfbcbc2ef2edb Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 11 Jul 2022 14:44:19 +0200 Subject: support to hide menu item from their context menu, have persisted menu item hide states in menu service, create `MenuItemAction` with an util that can hide itself and its siblings (from the same menu), some adoptions --- .../browser/dropdownWithPrimaryActionViewItem.ts | 6 +- .../actions/browser/menuEntryActionViewItem.ts | 6 +- src/vs/platform/actions/common/actions.ts | 19 ++- src/vs/platform/actions/common/menuService.ts | 184 +++++++++++++++++++-- .../actions/test/common/menuService.test.ts | 3 +- .../notebook/browser/controller/editActions.ts | 1 + .../notebook/browser/diff/diffComponents.ts | 2 +- .../notebook/browser/diff/notebookTextDiffList.ts | 2 +- .../browser/view/cellParts/cellActionView.ts | 25 +-- .../browser/view/cellParts/cellToolbars.ts | 2 +- .../browser/viewParts/notebookEditorToolbar.ts | 6 +- .../browser/viewParts/notebookTopCellToolbar.ts | 2 +- .../contrib/terminal/browser/terminalMenus.ts | 11 +- .../contrib/terminal/browser/terminalView.ts | 5 +- .../contrib/testing/browser/testingExplorerView.ts | 2 +- 15 files changed, 215 insertions(+), 61 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/actions/browser/dropdownWithPrimaryActionViewItem.ts b/src/vs/platform/actions/browser/dropdownWithPrimaryActionViewItem.ts index 64030e42b01..ec2a105e9cb 100644 --- a/src/vs/platform/actions/browser/dropdownWithPrimaryActionViewItem.ts +++ b/src/vs/platform/actions/browser/dropdownWithPrimaryActionViewItem.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IContextMenuProvider } from 'vs/base/browser/contextmenu'; import * as DOM from 'vs/base/browser/dom'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { ActionViewItem, BaseActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems'; @@ -18,6 +17,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; export interface IDropdownWithPrimaryActionViewItemOptions { getKeyBinding?: (action: IAction) => ResolvedKeybinding | undefined; @@ -38,7 +38,7 @@ export class DropdownWithPrimaryActionViewItem extends BaseActionViewItem { dropdownAction: IAction, dropdownMenuActions: IAction[], className: string, - private readonly _contextMenuProvider: IContextMenuProvider, + private readonly _contextMenuProvider: IContextMenuService, private readonly _options: IDropdownWithPrimaryActionViewItemOptions | undefined, @IKeybindingService _keybindingService: IKeybindingService, @INotificationService _notificationService: INotificationService, @@ -46,7 +46,7 @@ export class DropdownWithPrimaryActionViewItem extends BaseActionViewItem { @IThemeService _themeService: IThemeService ) { super(null, primaryAction); - this._primaryAction = new MenuEntryActionViewItem(primaryAction, undefined, _keybindingService, _notificationService, _contextKeyService, _themeService); + this._primaryAction = new MenuEntryActionViewItem(primaryAction, undefined, _keybindingService, _notificationService, _contextKeyService, _themeService, _contextMenuProvider); this._dropdown = new DropdownMenuActionViewItem(dropdownAction, dropdownMenuActions, this._contextMenuProvider, { menuAsChild: true, classNames: ['codicon', 'codicon-chevron-down'], diff --git a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts index f2e093420db..a5f2338647d 100644 --- a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts +++ b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts @@ -206,12 +206,16 @@ export class MenuEntryActionViewItem extends ActionViewItem { this._register(addDisposableListener(container, 'contextmenu', event => { + if (!this._menuItemAction.hideActions) { + return; + } + event.preventDefault(); event.stopPropagation(); this._contextMenuService.showContextMenu({ getAnchor: () => container, - getActions: () => this._menuItemAction.hideActions.asList() + getActions: () => this._menuItemAction.hideActions!.asList() }); }, true)); } diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index a840260130c..17d74df8b6f 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -353,6 +353,22 @@ export class SubmenuItemAction extends SubmenuAction { } } +export class MenuItemActionManageActions { + constructor( + private readonly _hideThis: IAction, + private readonly _toggleAny: IAction[][], + ) { } + + asList(): IAction[] { + let result: IAction[] = [this._hideThis]; + for (const n of this._toggleAny) { + result.push(new Separator()); + result = result.concat(n); + } + return result; + } +} + // implements IAction, does NOT extend Action, so that no one // subscribes to events of Action or modified properties export class MenuItemAction implements IAction { @@ -373,6 +389,7 @@ export class MenuItemAction implements IAction { item: ICommandAction, alt: ICommandAction | undefined, options: IMenuActionOptions | undefined, + readonly hideActions: MenuItemActionManageActions | undefined, @IContextKeyService contextKeyService: IContextKeyService, @ICommandService private _commandService: ICommandService ) { @@ -399,7 +416,7 @@ export class MenuItemAction implements IAction { } this.item = item; - this.alt = alt ? new MenuItemAction(alt, undefined, options, contextKeyService, _commandService) : undefined; + this.alt = alt ? new MenuItemAction(alt, undefined, options, hideActions, contextKeyService, _commandService) : undefined; this._options = options; if (ThemeIcon.isThemeIcon(item.icon)) { this.class = CSSIcon.asClassName(item.icon); diff --git a/src/vs/platform/actions/common/menuService.ts b/src/vs/platform/actions/common/menuService.ts index e0f60280e33..67146c282c3 100644 --- a/src/vs/platform/actions/common/menuService.ts +++ b/src/vs/platform/actions/common/menuService.ts @@ -6,32 +6,98 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { Emitter, Event } from 'vs/base/common/event'; import { DisposableStore } from 'vs/base/common/lifecycle'; -import { IMenu, IMenuActionOptions, IMenuCreateOptions, IMenuItem, IMenuService, isIMenuItem, ISubmenuItem, MenuId, MenuItemAction, MenuRegistry, SubmenuItemAction } from 'vs/platform/actions/common/actions'; -import { ILocalizedString } from 'vs/platform/action/common/action'; +import { IMenu, IMenuActionOptions, IMenuCreateOptions, IMenuItem, IMenuService, isIMenuItem, ISubmenuItem, MenuId, MenuItemAction, MenuItemActionManageActions, MenuRegistry, SubmenuItemAction } from 'vs/platform/actions/common/actions'; +import { ICommandAction, ILocalizedString } from 'vs/platform/action/common/action'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { ContextKeyExpression, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IAction, SubmenuAction } from 'vs/base/common/actions'; +import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; +import { removeFastWithoutKeepingOrder } from 'vs/base/common/arrays'; +import { localize } from 'vs/nls'; export class MenuService implements IMenuService { declare readonly _serviceBrand: undefined; + private readonly _hiddenStates: PersistedMenuHideState; + constructor( - @ICommandService private readonly _commandService: ICommandService + @ICommandService private readonly _commandService: ICommandService, + @IStorageService storageService: IStorageService, ) { - // + this._hiddenStates = new PersistedMenuHideState(storageService); } /** * Create a new menu for the given menu identifier. A menu sends events when it's entries - * have changed (placement, enablement, checked-state). By default it does send events for - * sub menu entries. That is more expensive and must be explicitly enabled with the + * have changed (placement, enablement, checked-state). By default it does not send events for + * submenu entries. That is more expensive and must be explicitly enabled with the * `emitEventsForSubmenuChanges` flag. */ createMenu(id: MenuId, contextKeyService: IContextKeyService, options?: IMenuCreateOptions): IMenu { - return new Menu(id, { emitEventsForSubmenuChanges: false, eventDebounceDelay: 50, ...options }, this._commandService, contextKeyService, this); + return new Menu(id, this._hiddenStates, { emitEventsForSubmenuChanges: false, eventDebounceDelay: 50, ...options }, this._commandService, contextKeyService, this); } } +class PersistedMenuHideState { + + private static readonly _key = 'menu.hiddenCommands'; + + readonly onDidChange: Event; + private readonly _disposables = new DisposableStore(); + private readonly _data: Record; + + constructor(@IStorageService private readonly _storageService: IStorageService) { + try { + const raw = _storageService.get(PersistedMenuHideState._key, StorageScope.PROFILE, '{}'); + this._data = JSON.parse(raw); + } catch (err) { + this._data = Object.create(null); + } + + this.onDidChange = Event.filter(_storageService.onDidChangeValue, e => e.key === PersistedMenuHideState._key, this._disposables); + } + + dispose() { + this._disposables.dispose(); + } + + isHidden(menu: MenuId, commandId: string): boolean { + return this._data[menu.id]?.includes(commandId) ?? false; + } + + updateHidden(menu: MenuId, commandId: string, hidden: boolean): void { + const entries = this._data[menu.id]; + if (!hidden) { + // remove and cleanup + if (entries) { + const idx = entries.indexOf(commandId); + if (idx >= 0) { + removeFastWithoutKeepingOrder(entries, idx); + } + if (entries.length === 0) { + delete this._data[menu.id]; + } + } + } else { + // add unless already added + if (!entries) { + this._data[menu.id] = [commandId]; + } else { + const idx = entries.indexOf(commandId); + if (idx < 0) { + entries.push(commandId); + } + } + } + this._persist(); + } + + private _persist(): void { + const raw = JSON.stringify(this._data); + this._storageService.store(PersistedMenuHideState._key, raw, StorageScope.PROFILE, StorageTarget.USER); + } +} type MenuItemGroup = [string, Array]; @@ -47,6 +113,7 @@ class Menu implements IMenu { constructor( private readonly _id: MenuId, + private readonly _hiddenStates: PersistedMenuHideState, private readonly _options: Required, @ICommandService private readonly _commandService: ICommandService, @IContextKeyService private readonly _contextKeyService: IContextKeyService, @@ -68,24 +135,27 @@ class Menu implements IMenu { } })); - // When context keys change we need to check if the menu also has changed. However, - // we only do that when someone listens on this menu because (1) context key events are + // When context keys or storage state changes we need to check if the menu also has changed. However, + // we only do that when someone listens on this menu because (1) these events are // firing often and (2) menu are often leaked - const contextKeyListener = this._disposables.add(new DisposableStore()); - const startContextKeyListener = () => { + const lazyListener = this._disposables.add(new DisposableStore()); + const startLazyListener = () => { const fireChangeSoon = new RunOnceScheduler(() => this._onDidChange.fire(this), _options.eventDebounceDelay); - contextKeyListener.add(fireChangeSoon); - contextKeyListener.add(_contextKeyService.onDidChangeContext(e => { + lazyListener.add(fireChangeSoon); + lazyListener.add(_contextKeyService.onDidChangeContext(e => { if (e.affectsSome(this._contextKeys)) { fireChangeSoon.schedule(); } })); + lazyListener.add(_hiddenStates.onDidChange(() => { + fireChangeSoon.schedule(); + })); }; this._onDidChange = new Emitter({ // start/stop context key listener - onFirstListenerAdd: startContextKeyListener, - onLastListenerRemove: contextKeyListener.clear.bind(contextKeyListener) + onFirstListenerAdd: startLazyListener, + onLastListenerRemove: lazyListener.clear.bind(lazyListener) }); this.onDidChange = this._onDidChange.event; @@ -145,20 +215,47 @@ class Menu implements IMenu { getActions(options?: IMenuActionOptions): [string, Array][] { const result: [string, Array][] = []; + const allToggleActions: IAction[][] = []; + for (const group of this._menuGroups) { const [id, items] = group; + + const toggleActions: IAction[] = []; + const activeActions: Array = []; for (const item of items) { if (this._contextKeyService.contextMatchesRules(item.when)) { let action: MenuItemAction | SubmenuItemAction | undefined; if (isIMenuItem(item)) { - action = new MenuItemAction(item.command, item.alt, options, this._contextKeyService, this._commandService); + if (!this._hiddenStates.isHidden(this._id, item.command.id)) { + action = new MenuItemAction( + item.command, item.alt, options, + new MenuItemActionManageActions(new HideMenuItemAction(this._id, item.command, this._hiddenStates), allToggleActions), + this._contextKeyService, this._commandService + ); + } + // add toggle commmand + toggleActions.push(new ToggleMenuItemAction(this._id, item.command, this._hiddenStates)); } else { action = new SubmenuItemAction(item, this._menuService, this._contextKeyService, options); if (action.actions.length === 0) { action.dispose(); action = undefined; } + // add toggle submenu + if (action) { + // todo@jrieken this isn't good and O(n2) because this recurses for each submenu... + const makeToggleCommand = (id: MenuId, action: IAction): IAction => { + if (action instanceof SubmenuItemAction) { + return new SubmenuAction(action.id, action.label, action.actions.map(a => makeToggleCommand(action.item.submenu, a))); + } else if (action instanceof MenuItemAction) { + return new ToggleMenuItemAction(id, action.item, this._hiddenStates); + } else { + return action; + } + }; + toggleActions.push(makeToggleCommand(this._id, action)); + } } if (action) { @@ -169,6 +266,9 @@ class Menu implements IMenu { if (activeActions.length > 0) { result.push([id, activeActions]); } + if (toggleActions.length > 0) { + allToggleActions.push(toggleActions); + } } return result; } @@ -231,3 +331,55 @@ class Menu implements IMenu { return aStr.localeCompare(bStr); } } + +class ToggleMenuItemAction implements IAction { + + readonly id: string; + readonly label: string; + readonly enabled: boolean = true; + readonly tooltip: string = ''; + + readonly checked: boolean; + readonly class: undefined; + + run: () => void; + + constructor(id: MenuId, command: ICommandAction, hiddenStates: PersistedMenuHideState) { + this.id = `toggle/${id.id}/${command.id}`; + this.label = typeof command.title === 'string' ? command.title : command.title.value; + + let isHidden = hiddenStates.isHidden(id, command.id); + this.checked = !isHidden; + this.run = () => { + isHidden = !isHidden; + hiddenStates.updateHidden(id, command.id, isHidden); + }; + } + + dispose(): void { + // NOTHING + } +} + +class HideMenuItemAction implements IAction { + + readonly id: string; + readonly label: string; + readonly enabled: boolean = true; + readonly tooltip: string = ''; + + readonly checked: undefined; + readonly class: undefined; + + run: () => void; + + constructor(id: MenuId, command: ICommandAction, hiddenStates: PersistedMenuHideState) { + this.id = `hide/${id.id}/${command.id}`; + this.label = localize('hide.label', 'Hide \'{0}\'', typeof command.title === 'string' ? command.title : command.title.value); + this.run = () => { hiddenStates.updateHidden(id, command.id, true); }; + } + + dispose(): void { + // NOTHING + } +} diff --git a/src/vs/platform/actions/test/common/menuService.test.ts b/src/vs/platform/actions/test/common/menuService.test.ts index 0a3807b9ef6..e869c726cd1 100644 --- a/src/vs/platform/actions/test/common/menuService.test.ts +++ b/src/vs/platform/actions/test/common/menuService.test.ts @@ -9,6 +9,7 @@ import { isIMenuItem, MenuId, MenuRegistry } from 'vs/platform/actions/common/ac import { MenuService } from 'vs/platform/actions/common/menuService'; import { NullCommandService } from 'vs/platform/commands/common/commands'; import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; +import { InMemoryStorageService } from 'vs/platform/storage/common/storage'; // --- service instances @@ -27,7 +28,7 @@ suite('MenuService', function () { let testMenuId: MenuId; setup(function () { - menuService = new MenuService(NullCommandService); + menuService = new MenuService(NullCommandService, new InMemoryStorageService()); testMenuId = new MenuId('testo'); disposables.clear(); }); diff --git a/src/vs/workbench/contrib/notebook/browser/controller/editActions.ts b/src/vs/workbench/contrib/notebook/browser/controller/editActions.ts index ebcdf94c782..1f64bddb5e3 100644 --- a/src/vs/workbench/contrib/notebook/browser/controller/editActions.ts +++ b/src/vs/workbench/contrib/notebook/browser/controller/editActions.ts @@ -49,6 +49,7 @@ export class DeleteCellAction extends MenuItemAction { }, undefined, { shouldForwardArgs: true }, + undefined, contextKeyService, commandService); } diff --git a/src/vs/workbench/contrib/notebook/browser/diff/diffComponents.ts b/src/vs/workbench/contrib/notebook/browser/diff/diffComponents.ts index c7d1f0d6594..da1a9c3a04a 100644 --- a/src/vs/workbench/contrib/notebook/browser/diff/diffComponents.ts +++ b/src/vs/workbench/contrib/notebook/browser/diff/diffComponents.ts @@ -156,7 +156,7 @@ class PropertyHeader extends Disposable { this._toolbar = new ToolBar(cellToolbarContainer, this.contextMenuService, { actionViewItemProvider: action => { if (action instanceof MenuItemAction) { - const item = new CodiconActionViewItem(action, this.keybindingService, this.notificationService, this.contextKeyService, this.themeService); + const item = new CodiconActionViewItem(action, undefined, this.keybindingService, this.notificationService, this.contextKeyService, this.themeService, this.contextMenuService); return item; } diff --git a/src/vs/workbench/contrib/notebook/browser/diff/notebookTextDiffList.ts b/src/vs/workbench/contrib/notebook/browser/diff/notebookTextDiffList.ts index 07374920577..244f65f50ca 100644 --- a/src/vs/workbench/contrib/notebook/browser/diff/notebookTextDiffList.ts +++ b/src/vs/workbench/contrib/notebook/browser/diff/notebookTextDiffList.ts @@ -187,7 +187,7 @@ export class CellDiffSideBySideRenderer implements IListRenderer { if (action instanceof MenuItemAction) { - const item = new CodiconActionViewItem(action, this.keybindingService, this.notificationService, this.contextKeyService, this.themeService); + const item = new CodiconActionViewItem(action, undefined, this.keybindingService, this.notificationService, this.contextKeyService, this.themeService, this.contextMenuService); return item; } diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellActionView.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellActionView.ts index fe682e0e9aa..1808c007e8f 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellActionView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellActionView.ts @@ -6,22 +6,9 @@ import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels'; import * as DOM from 'vs/base/browser/dom'; import { MenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem'; -import { MenuItemAction } from 'vs/platform/actions/common/actions'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { INotificationService } from 'vs/platform/notification/common/notification'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; export class CodiconActionViewItem extends MenuEntryActionViewItem { - constructor( - _action: MenuItemAction, - @IKeybindingService keybindingService: IKeybindingService, - @INotificationService notificationService: INotificationService, - @IContextKeyService contextKeyService: IContextKeyService, - @IThemeService themeService: IThemeService, - ) { - super(_action, undefined, keybindingService, notificationService, contextKeyService, themeService); - } + override updateLabel(): void { if (this.options.label && this.label) { DOM.reset(this.label, ...renderLabelWithIcons(this._commandAction.label ?? '')); @@ -32,16 +19,6 @@ export class CodiconActionViewItem extends MenuEntryActionViewItem { export class ActionViewWithLabel extends MenuEntryActionViewItem { private _actionLabel?: HTMLAnchorElement; - constructor( - _action: MenuItemAction, - @IKeybindingService keybindingService: IKeybindingService, - @INotificationService notificationService: INotificationService, - @IContextKeyService contextKeyService: IContextKeyService, - @IThemeService themeService: IThemeService, - ) { - super(_action, undefined, keybindingService, notificationService, contextKeyService, themeService); - } - override render(container: HTMLElement): void { super.render(container); container.classList.add('notebook-action-view-item'); diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellToolbars.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellToolbars.ts index c84443b70ab..35502e4e1a9 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellToolbars.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellToolbars.ts @@ -42,7 +42,7 @@ export class BetweenCellToolbar extends CellPart { actionViewItemProvider: action => { if (action instanceof MenuItemAction) { if (this._notebookEditor.notebookOptions.getLayoutConfiguration().insertToolbarAlignment === 'center') { - return instantiationService.createInstance(CodiconActionViewItem, action); + return instantiationService.createInstance(CodiconActionViewItem, action, undefined); } else { return instantiationService.createInstance(MenuEntryActionViewItem, action, undefined); } diff --git a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorToolbar.ts b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorToolbar.ts index 1d1d38c2689..c80acf0d2ec 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorToolbar.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorToolbar.ts @@ -69,7 +69,7 @@ class FixedLabelStrategy implements IActionLayoutStrategy { const a = this.editorToolbar.primaryActions.find(a => a.action.id === action.id); if (a && a.renderLabel) { - return action instanceof MenuItemAction ? this.instantiationService.createInstance(ActionViewWithLabel, action) : undefined; + return action instanceof MenuItemAction ? this.instantiationService.createInstance(ActionViewWithLabel, action, undefined) : undefined; } else { return action instanceof MenuItemAction ? this.instantiationService.createInstance(MenuEntryActionViewItem, action, undefined) : undefined; } @@ -144,7 +144,7 @@ class DynamicLabelStrategy implements IActionLayoutStrategy { const a = this.editorToolbar.primaryActions.find(a => a.action.id === action.id); if (a && a.renderLabel) { - return action instanceof MenuItemAction ? this.instantiationService.createInstance(ActionViewWithLabel, action) : undefined; + return action instanceof MenuItemAction ? this.instantiationService.createInstance(ActionViewWithLabel, action, undefined) : undefined; } else { return action instanceof MenuItemAction ? this.instantiationService.createInstance(MenuEntryActionViewItem, action, undefined) : undefined; } @@ -360,7 +360,7 @@ export class NotebookEditorToolbar extends Disposable { if (this._renderLabel !== RenderLabel.Never) { const a = this._primaryActions.find(a => a.action.id === action.id); if (a && a.renderLabel) { - return action instanceof MenuItemAction ? this.instantiationService.createInstance(ActionViewWithLabel, action) : undefined; + return action instanceof MenuItemAction ? this.instantiationService.createInstance(ActionViewWithLabel, action, undefined) : undefined; } else { return action instanceof MenuItemAction ? this.instantiationService.createInstance(MenuEntryActionViewItem, action, undefined) : undefined; } diff --git a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookTopCellToolbar.ts b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookTopCellToolbar.ts index 92d6c18e45f..ab97127c986 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookTopCellToolbar.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookTopCellToolbar.ts @@ -37,7 +37,7 @@ export class ListTopCellToolbar extends Disposable { this.toolbar = this._register(new ToolBar(this.topCellToolbar, this.contextMenuService, { actionViewItemProvider: action => { if (action instanceof MenuItemAction) { - const item = this.instantiationService.createInstance(CodiconActionViewItem, action); + const item = this.instantiationService.createInstance(CodiconActionViewItem, action, undefined); return item; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts b/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts index c6e6700e280..af2d55a2242 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts @@ -752,11 +752,11 @@ export function getTerminalActionBarArgs(location: ITerminalLocationOptions, pro shouldForwardArgs: true }; if (isDefault) { - dropdownActions.unshift(new MenuItemAction({ id: TerminalCommandId.NewWithProfile, title: localize('defaultTerminalProfile', "{0} (Default)", p.profileName), category: TerminalTabContextMenuGroup.Profile }, undefined, options, contextKeyService, commandService)); - submenuActions.unshift(new MenuItemAction({ id: TerminalCommandId.Split, title: localize('defaultTerminalProfile', "{0} (Default)", p.profileName), category: TerminalTabContextMenuGroup.Profile }, undefined, splitOptions, contextKeyService, commandService)); + dropdownActions.unshift(new MenuItemAction({ id: TerminalCommandId.NewWithProfile, title: localize('defaultTerminalProfile', "{0} (Default)", p.profileName), category: TerminalTabContextMenuGroup.Profile }, undefined, options, undefined, contextKeyService, commandService)); + submenuActions.unshift(new MenuItemAction({ id: TerminalCommandId.Split, title: localize('defaultTerminalProfile', "{0} (Default)", p.profileName), category: TerminalTabContextMenuGroup.Profile }, undefined, splitOptions, undefined, contextKeyService, commandService)); } else { - dropdownActions.push(new MenuItemAction({ id: TerminalCommandId.NewWithProfile, title: p.profileName.replace(/[\n\r\t]/g, ''), category: TerminalTabContextMenuGroup.Profile }, undefined, options, contextKeyService, commandService)); - submenuActions.push(new MenuItemAction({ id: TerminalCommandId.Split, title: p.profileName.replace(/[\n\r\t]/g, ''), category: TerminalTabContextMenuGroup.Profile }, undefined, splitOptions, contextKeyService, commandService)); + dropdownActions.push(new MenuItemAction({ id: TerminalCommandId.NewWithProfile, title: p.profileName.replace(/[\n\r\t]/g, ''), category: TerminalTabContextMenuGroup.Profile }, undefined, options, undefined, contextKeyService, commandService)); + submenuActions.push(new MenuItemAction({ id: TerminalCommandId.Split, title: p.profileName.replace(/[\n\r\t]/g, ''), category: TerminalTabContextMenuGroup.Profile }, undefined, splitOptions, undefined, contextKeyService, commandService)); } } @@ -823,7 +823,8 @@ export function getTerminalActionBarArgs(location: ITerminalLocationOptions, pro { shouldForwardArgs: true, arg: { location } as ICreateTerminalOptions, - }); + }, + undefined); const dropdownAction = new Action('refresh profiles', 'Launch Profile...', 'codicon-chevron-down', true); return { primaryAction, dropdownAction, dropdownMenuActions: dropdownActions, className: `terminal-tab-actions-${terminalService.resolveLocation(location)}` }; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalView.ts b/src/vs/workbench/contrib/terminal/browser/terminalView.ts index f3f77734984..9dc9017d20f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalView.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalView.ts @@ -373,7 +373,7 @@ class SingleTerminalTabActionViewItem extends MenuEntryActionViewItem { @IThemeService themeService: IThemeService, @ITerminalService private readonly _terminalService: ITerminalService, @ITerminalGroupService private readonly _terminalGroupService: ITerminalGroupService, - @IContextMenuService private readonly _contextMenuService: IContextMenuService, + @IContextMenuService contextMenuService: IContextMenuService, @ICommandService private readonly _commandService: ICommandService, @IConfigurationService configurationService: IConfigurationService, @IInstantiationService private readonly _instantiationService: IInstantiationService, @@ -390,11 +390,12 @@ class SingleTerminalTabActionViewItem extends MenuEntryActionViewItem { icon: Codicon.splitHorizontal }, undefined, + undefined, contextKeyService, _commandService ), { draggable: true - }, keybindingService, notificationService, contextKeyService, themeService); + }, keybindingService, notificationService, contextKeyService, themeService, contextMenuService); // Register listeners to update the tab this._register(this._terminalService.onDidChangeInstancePrimaryStatus(e => this.updateLabel(e))); diff --git a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts index 0c639a29c53..66ffbef2595 100644 --- a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts +++ b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts @@ -337,7 +337,7 @@ export class TestingExplorerView extends ViewPane { icon: group === TestRunProfileBitset.Run ? icons.testingRunAllIcon : icons.testingDebugAllIcon, - }, undefined, undefined); + }, undefined, undefined, undefined); const dropdownAction = new Action('selectRunConfig', 'Select Configuration...', 'codicon-chevron-down', true); -- cgit v1.2.3 From 4dc9d90a61fa84580d4b77fec8bdcb4acfb70ff1 Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 11 Jul 2022 14:58:53 +0200 Subject: make to react properly to storage change events --- src/vs/platform/actions/common/menuService.ts | 32 ++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/actions/common/menuService.ts b/src/vs/platform/actions/common/menuService.ts index 67146c282c3..0e596777725 100644 --- a/src/vs/platform/actions/common/menuService.ts +++ b/src/vs/platform/actions/common/menuService.ts @@ -43,9 +43,12 @@ class PersistedMenuHideState { private static readonly _key = 'menu.hiddenCommands'; - readonly onDidChange: Event; private readonly _disposables = new DisposableStore(); - private readonly _data: Record; + private readonly _onDidChange = new Emitter(); + readonly onDidChange: Event = this._onDidChange.event; + + private _ignoreChangeEvent: boolean = false; + private _data: Record; constructor(@IStorageService private readonly _storageService: IStorageService) { try { @@ -55,10 +58,24 @@ class PersistedMenuHideState { this._data = Object.create(null); } - this.onDidChange = Event.filter(_storageService.onDidChangeValue, e => e.key === PersistedMenuHideState._key, this._disposables); + this._disposables.add(_storageService.onDidChangeValue(e => { + if (e.key !== PersistedMenuHideState._key) { + return; + } + if (!this._ignoreChangeEvent) { + try { + const raw = _storageService.get(PersistedMenuHideState._key, StorageScope.PROFILE, '{}'); + this._data = JSON.parse(raw); + } catch (err) { + console.log('FAILED to read storage after UPDATE', err); + } + } + this._onDidChange.fire(); + })); } dispose() { + this._onDidChange.dispose(); this._disposables.dispose(); } @@ -94,8 +111,13 @@ class PersistedMenuHideState { } private _persist(): void { - const raw = JSON.stringify(this._data); - this._storageService.store(PersistedMenuHideState._key, raw, StorageScope.PROFILE, StorageTarget.USER); + try { + this._ignoreChangeEvent = true; + const raw = JSON.stringify(this._data); + this._storageService.store(PersistedMenuHideState._key, raw, StorageScope.PROFILE, StorageTarget.USER); + } finally { + this._ignoreChangeEvent = false; + } } } -- cgit v1.2.3 From da71a350cb85d8a93d96ceac407595779532079c Mon Sep 17 00:00:00 2001 From: PieterBranderhorst <63430877+PieterBranderhorst@users.noreply.github.com> Date: Mon, 11 Jul 2022 06:19:13 -0700 Subject: =?UTF-8?q?Make=20hidden=20fold=20ranges=20independent=20of=20rang?= =?UTF-8?q?e=20provider,=20add=20manual=20fol=E2=80=A6=20(#139779)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * squash all changes for keepCollapsedFolds * change manual fold icon, auto unfold when del at end of first line Co-authored-by: Martin Aeschlimann --- src/vs/editor/contrib/folding/browser/folding.ts | 112 +++++++----- .../contrib/folding/browser/foldingDecorations.ts | 29 ++- .../editor/contrib/folding/browser/foldingModel.ts | 186 ++++++++++--------- .../contrib/folding/browser/foldingRanges.ts | 200 +++++++++++++++++++-- .../contrib/folding/browser/hiddenRangeModel.ts | 24 +-- .../folding/browser/intializingRangeProvider.ts | 65 ------- .../folding/test/browser/foldingRanges.test.ts | 129 ++++++++++++- 7 files changed, 504 insertions(+), 241 deletions(-) delete mode 100644 src/vs/editor/contrib/folding/browser/intializingRangeProvider.ts (limited to 'src/vs') diff --git a/src/vs/editor/contrib/folding/browser/folding.ts b/src/vs/editor/contrib/folding/browser/folding.ts index c38e6071eef..64339450d95 100644 --- a/src/vs/editor/contrib/folding/browser/folding.ts +++ b/src/vs/editor/contrib/folding/browser/folding.ts @@ -26,15 +26,14 @@ import { ILanguageConfigurationService } from 'vs/editor/common/languages/langua import { CollapseMemento, FoldingModel, getNextFoldLine, getParentFoldLine as getParentFoldLine, getPreviousFoldLine, setCollapseStateAtLevel, setCollapseStateForMatchingLines, setCollapseStateForRest, setCollapseStateForType, setCollapseStateLevelsDown, setCollapseStateLevelsUp, setCollapseStateUp, toggleCollapseState } from 'vs/editor/contrib/folding/browser/foldingModel'; import { HiddenRangeModel } from 'vs/editor/contrib/folding/browser/hiddenRangeModel'; import { IndentRangeProvider } from 'vs/editor/contrib/folding/browser/indentRangeProvider'; -import { ID_INIT_PROVIDER, InitializingRangeProvider } from 'vs/editor/contrib/folding/browser/intializingRangeProvider'; import * as nls from 'vs/nls'; import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { editorSelectionBackground, iconForeground, registerColor, transparent } from 'vs/platform/theme/common/colorRegistry'; import { registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService'; -import { foldingCollapsedIcon, FoldingDecorationProvider, foldingExpandedIcon } from './foldingDecorations'; -import { FoldingRegion, FoldingRegions } from './foldingRanges'; -import { ID_SYNTAX_PROVIDER, SyntaxRangeProvider } from './syntaxRangeProvider'; +import { foldingCollapsedIcon, FoldingDecorationProvider, foldingExpandedIcon, foldingManualIcon } from './foldingDecorations'; +import { FoldingRegion, FoldingRegions, FoldRange } from './foldingRanges'; +import { SyntaxRangeProvider } from './syntaxRangeProvider'; import { INotificationService } from 'vs/platform/notification/common/notification'; import Severity from 'vs/base/common/severity'; import { IFeatureDebounceInformation, ILanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce'; @@ -84,8 +83,6 @@ export class FoldingController extends Disposable implements IEditorContribution private rangeProvider: RangeProvider | null; private foldingRegionPromise: CancelablePromise | null; - private foldingStateMemento: FoldingStateMemento | null; - private foldingModelPromise: Promise | null; private updateScheduler: Delayer | null; private readonly updateDebounceInfo: IFeatureDebounceInformation; @@ -120,7 +117,6 @@ export class FoldingController extends Disposable implements IEditorContribution this.hiddenRangeModel = null; this.rangeProvider = null; this.foldingRegionPromise = null; - this.foldingStateMemento = null; this.foldingModelPromise = null; this.updateScheduler = null; this.cursorChangedScheduler = null; @@ -186,7 +182,7 @@ export class FoldingController extends Disposable implements IEditorContribution return {}; } if (this.foldingModel) { // disposed ? - const collapsedRegions = this.foldingModel.isInitialized ? this.foldingModel.getMemento() : this.hiddenRangeModel!.getMemento(); + const collapsedRegions = this.foldingModel.getMemento(); const provider = this.rangeProvider ? this.rangeProvider.id : undefined; return { collapsedRegions, lineCount: model.getLineCount(), provider, foldedImports: this._currentModelHasFoldedImports }; } @@ -206,29 +202,12 @@ export class FoldingController extends Disposable implements IEditorContribution } this._currentModelHasFoldedImports = !!state.foldedImports; - if (!state.collapsedRegions) { - return; - } - - if (state.provider === ID_SYNTAX_PROVIDER || state.provider === ID_INIT_PROVIDER) { - this.foldingStateMemento = state; - } - - const collapsedRegions = state.collapsedRegions; - // set the hidden ranges right away, before waiting for the folding model. - if (this.hiddenRangeModel.applyMemento(collapsedRegions)) { - const foldingModel = this.getFoldingModel(); - if (foldingModel) { - foldingModel.then(foldingModel => { - if (foldingModel) { - this._restoringViewState = true; - try { - foldingModel.applyMemento(collapsedRegions); - } finally { - this._restoringViewState = false; - } - } - }).then(undefined, onUnexpectedError); + if (state.collapsedRegions && state.collapsedRegions.length > 0 && this.foldingModel) { + this._restoringViewState = true; + try { + this.foldingModel.applyMemento(state.collapsedRegions!); + } finally { + this._restoringViewState = false; } } } @@ -243,7 +222,7 @@ export class FoldingController extends Disposable implements IEditorContribution } this._currentModelHasFoldedImports = false; - this.foldingModel = new FoldingModel(model, this.foldingDecorationProvider); + this.foldingModel = new FoldingModel(model, this.foldingDecorationProvider, this.triggerFoldingModelChanged.bind(this)); this.localToDispose.add(this.foldingModel); this.hiddenRangeModel = new HiddenRangeModel(this.foldingModel); @@ -274,7 +253,6 @@ export class FoldingController extends Disposable implements IEditorContribution this.foldingModelPromise = null; this.hiddenRangeModel = null; this.cursorChangedScheduler = null; - this.foldingStateMemento = null; if (this.rangeProvider) { this.rangeProvider.dispose(); } @@ -297,21 +275,12 @@ export class FoldingController extends Disposable implements IEditorContribution return this.rangeProvider; } this.rangeProvider = new IndentRangeProvider(editorModel, this.languageConfigurationService, this._maxFoldingRegions); // fallback - if (this._useFoldingProviders && this.foldingModel) { const foldingProviders = this.languageFeaturesService.foldingRangeProvider.ordered(this.foldingModel.textModel); - if (foldingProviders.length === 0 && this.foldingStateMemento && this.foldingStateMemento.collapsedRegions) { - const rangeProvider = this.rangeProvider = new InitializingRangeProvider(editorModel, this.foldingStateMemento.collapsedRegions, () => { - // if after 30 the InitializingRangeProvider is still not replaced, force a refresh - this.foldingStateMemento = null; - this.onFoldingStrategyChanged(); - }, 30000); - return rangeProvider; // keep memento in case there are still no foldingProviders on the next request. - } else if (foldingProviders.length > 0) { + if (foldingProviders.length > 0) { this.rangeProvider = new SyntaxRangeProvider(editorModel, foldingProviders, () => this.triggerFoldingModelChanged(), this._maxFoldingRegions); } } - this.foldingStateMemento = null; return this.rangeProvider; } @@ -1097,6 +1066,59 @@ class GotoNextFoldAction extends FoldingAction { } } +class FoldSelectedAction extends FoldingAction { + + constructor() { + super({ + id: 'editor.foldSelected', + label: nls.localize('foldSelectedAction.label', "Fold Selected Lines"), + alias: 'Fold Selected Lines', + precondition: CONTEXT_FOLDING_ENABLED, + kbOpts: { + kbExpr: EditorContextKeys.editorTextFocus, + primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Period), + weight: KeybindingWeight.EditorContrib + } + }); + } + + invoke(_foldingController: FoldingController, foldingModel: FoldingModel, editor: ICodeEditor): void { + const collapseRanges: FoldRange[] = []; + const selections = editor.getSelections(); + if (selections) { + for (const selection of selections) { + let endLineNumber = selection.endLineNumber; + if (selection.endColumn === 1) { + --endLineNumber; + } + if (endLineNumber > selection.startLineNumber) { + collapseRanges.push({ + startLineNumber: selection.startLineNumber, + endLineNumber: endLineNumber, + type: undefined, + isCollapsed: true, + isManualSelection: true + }); + editor.setSelection({ + startLineNumber: selection.startLineNumber, + startColumn: 1, + endLineNumber: selection.startLineNumber, + endColumn: 1 + }); + } + } + if (collapseRanges.length > 0) { + collapseRanges.sort((a, b) => { + return a.startLineNumber - b.startLineNumber; + }); + const newRanges = FoldingRegions.sanitizeAndMerge(foldingModel.regions, collapseRanges, editor.getModel()?.getLineCount()); + foldingModel.updatePost(FoldingRegions.fromFoldRanges(newRanges)); + } + } + } +} + + registerEditorContribution(FoldingController.ID, FoldingController); registerEditorAction(UnfoldAction); registerEditorAction(UnFoldRecursivelyAction); @@ -1113,6 +1135,7 @@ registerEditorAction(ToggleFoldAction); registerEditorAction(GotoParentFoldAction); registerEditorAction(GotoPreviousFoldAction); registerEditorAction(GotoNextFoldAction); +registerEditorAction(FoldSelectedAction); for (let i = 1; i <= 7; i++) { registerInstantiatedEditorAction( @@ -1143,7 +1166,8 @@ registerThemingParticipant((theme, collector) => { if (editorFoldColor) { collector.addRule(` .monaco-editor .cldr${ThemeIcon.asCSSSelector(foldingExpandedIcon)}, - .monaco-editor .cldr${ThemeIcon.asCSSSelector(foldingCollapsedIcon)} { + .monaco-editor .cldr${ThemeIcon.asCSSSelector(foldingCollapsedIcon)}, + .monaco-editor .cldr${ThemeIcon.asCSSSelector(foldingManualIcon)} { color: ${editorFoldColor} !important; } `); diff --git a/src/vs/editor/contrib/folding/browser/foldingDecorations.ts b/src/vs/editor/contrib/folding/browser/foldingDecorations.ts index 348b1e7da1a..132dd19a9fa 100644 --- a/src/vs/editor/contrib/folding/browser/foldingDecorations.ts +++ b/src/vs/editor/contrib/folding/browser/foldingDecorations.ts @@ -5,7 +5,7 @@ import { Codicon } from 'vs/base/common/codicons'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { IModelDecorationsChangeAccessor, TrackedRangeStickiness } from 'vs/editor/common/model'; +import { IModelDecorationOptions, IModelDecorationsChangeAccessor, TrackedRangeStickiness } from 'vs/editor/common/model'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; import { IDecorationProvider } from 'vs/editor/contrib/folding/browser/foldingModel'; import { localize } from 'vs/nls'; @@ -14,6 +14,7 @@ import { ThemeIcon } from 'vs/platform/theme/common/themeService'; export const foldingExpandedIcon = registerIcon('folding-expanded', Codicon.chevronDown, localize('foldingExpandedIcon', 'Icon for expanded ranges in the editor glyph margin.')); export const foldingCollapsedIcon = registerIcon('folding-collapsed', Codicon.chevronRight, localize('foldingCollapsedIcon', 'Icon for collapsed ranges in the editor glyph margin.')); +export const foldingManualIcon = registerIcon('folding-manual', Codicon.ellipsis, localize('foldingManualIcon', 'Icon for manually collapsed ranges in the editor glyph margin.')); export class FoldingDecorationProvider implements IDecorationProvider { private static readonly COLLAPSED_VISUAL_DECORATION = ModelDecorationOptions.register({ @@ -33,6 +34,23 @@ export class FoldingDecorationProvider implements IDecorationProvider { firstLineDecorationClassName: ThemeIcon.asClassName(foldingCollapsedIcon) }); + private static readonly MANUALLY_COLLAPSED_VISUAL_DECORATION = ModelDecorationOptions.register({ + description: 'folding-manually-collapsed-visual-decoration', + stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges, + afterContentClassName: 'inline-folded', + isWholeLine: true, + firstLineDecorationClassName: ThemeIcon.asClassName(foldingManualIcon) + }); + + private static readonly MANUALLY_COLLAPSED_HIGHLIGHTED_VISUAL_DECORATION = ModelDecorationOptions.register({ + description: 'folding-manually-collapsed-highlighted-visual-decoration', + stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges, + afterContentClassName: 'inline-folded', + className: 'folded-background', + isWholeLine: true, + firstLineDecorationClassName: ThemeIcon.asClassName(foldingManualIcon) + }); + private static readonly EXPANDED_AUTO_HIDE_VISUAL_DECORATION = ModelDecorationOptions.register({ description: 'folding-expanded-auto-hide-visual-decoration', stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges, @@ -59,12 +77,15 @@ export class FoldingDecorationProvider implements IDecorationProvider { constructor(private readonly editor: ICodeEditor) { } - getDecorationOption(isCollapsed: boolean, isHidden: boolean): ModelDecorationOptions { - if (isHidden || this.showFoldingControls === 'never') { + getDecorationOption(isCollapsed: boolean, isHidden: boolean, isManualSelection: boolean): IModelDecorationOptions { + if (isHidden // is inside another collapsed region + || this.showFoldingControls === 'never' || (isManualSelection && !isCollapsed)) { // return FoldingDecorationProvider.HIDDEN_RANGE_DECORATION; } if (isCollapsed) { - return this.showFoldingHighlights ? FoldingDecorationProvider.COLLAPSED_HIGHLIGHTED_VISUAL_DECORATION : FoldingDecorationProvider.COLLAPSED_VISUAL_DECORATION; + return isManualSelection ? + (this.showFoldingHighlights ? FoldingDecorationProvider.MANUALLY_COLLAPSED_HIGHLIGHTED_VISUAL_DECORATION : FoldingDecorationProvider.MANUALLY_COLLAPSED_VISUAL_DECORATION) + : (this.showFoldingHighlights ? FoldingDecorationProvider.COLLAPSED_HIGHLIGHTED_VISUAL_DECORATION : FoldingDecorationProvider.COLLAPSED_VISUAL_DECORATION); } else if (this.showFoldingControls === 'mouseover') { return FoldingDecorationProvider.EXPANDED_AUTO_HIDE_VISUAL_DECORATION; } else { diff --git a/src/vs/editor/contrib/folding/browser/foldingModel.ts b/src/vs/editor/contrib/folding/browser/foldingModel.ts index ba52acfdea8..59083ae1d3e 100644 --- a/src/vs/editor/contrib/folding/browser/foldingModel.ts +++ b/src/vs/editor/contrib/folding/browser/foldingModel.ts @@ -5,10 +5,11 @@ import { Emitter, Event } from 'vs/base/common/event'; import { IModelDecorationOptions, IModelDecorationsChangeAccessor, IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model'; -import { FoldingRegion, FoldingRegions, ILineRange } from './foldingRanges'; +import { FoldingRegion, FoldingRegions, ILineRange, FoldRange } from './foldingRanges'; +import { hash } from 'vs/base/common/hash'; export interface IDecorationProvider { - getDecorationOption(isCollapsed: boolean, isHidden: boolean): IModelDecorationOptions; + getDecorationOption(isCollapsed: boolean, isHidden: boolean, isManualSelection: boolean): IModelDecorationOptions; changeDecorations(callback: (changeAccessor: IModelDecorationsChangeAccessor) => T): T | null; removeDecorations(decorationIds: string[]): void; } @@ -18,30 +19,33 @@ export interface FoldingModelChangeEvent { collapseStateChanged?: FoldingRegion[]; } -export type CollapseMemento = ILineRange[]; +interface ILineMemento extends ILineRange { + checksum?: number; +} + +export type CollapseMemento = ILineMemento[]; export class FoldingModel { private readonly _textModel: ITextModel; private readonly _decorationProvider: IDecorationProvider; + private readonly _triggerRecomputeRanges: (() => void) | undefined; private _regions: FoldingRegions; private _editorDecorationIds: string[]; - private _isInitialized: boolean; private readonly _updateEventEmitter = new Emitter(); public readonly onDidChange: Event = this._updateEventEmitter.event; public get regions(): FoldingRegions { return this._regions; } public get textModel() { return this._textModel; } - public get isInitialized() { return this._isInitialized; } public get decorationProvider() { return this._decorationProvider; } - constructor(textModel: ITextModel, decorationProvider: IDecorationProvider) { + constructor(textModel: ITextModel, decorationProvider: IDecorationProvider, triggerRecomputeRanges?: () => void) { this._textModel = textModel; this._decorationProvider = decorationProvider; + this._triggerRecomputeRanges = triggerRecomputeRanges; this._regions = new FoldingRegions(new Uint32Array(0), new Uint32Array(0)); this._editorDecorationIds = []; - this._isInitialized = false; } public toggleCollapseState(toggledRegions: FoldingRegion[]) { @@ -51,6 +55,7 @@ export class FoldingModel { toggledRegions = toggledRegions.sort((r1, r2) => r1.regionIndex - r2.regionIndex); const processed: { [key: string]: boolean | undefined } = {}; + const manualExpanded = false; this._decorationProvider.changeDecorations(accessor => { let k = 0; // index from [0 ... this.regions.length] let dirtyRegionEndLine = -1; // end of the range where decorations need to be updated @@ -59,8 +64,9 @@ export class FoldingModel { while (k < index) { const endLineNumber = this._regions.getEndLineNumber(k); const isCollapsed = this._regions.isCollapsed(k); + const isManualSelection = this.regions.isManualSelection(k); if (endLineNumber <= dirtyRegionEndLine) { - accessor.changeDecorationOptions(this._editorDecorationIds[k], this._decorationProvider.getDecorationOption(isCollapsed, endLineNumber <= lastHiddenLine)); + accessor.changeDecorationOptions(this._editorDecorationIds[k], this._decorationProvider.getDecorationOption(isCollapsed, endLineNumber <= lastHiddenLine, isManualSelection)); } if (isCollapsed && endLineNumber > lastHiddenLine) { lastHiddenLine = endLineNumber; @@ -85,110 +91,94 @@ export class FoldingModel { updateDecorationsUntil(this._regions.length); }); this._updateEventEmitter.fire({ model: this, collapseStateChanged: toggledRegions }); + if (manualExpanded && this._triggerRecomputeRanges) { + // expanding a range which didn't originate from range provider might now enable ranges + // from the provider which were previously dropped due to the collapsed range + this._triggerRecomputeRanges(); + } } public update(newRegions: FoldingRegions, blockedLineNumers: number[] = []): void { - const newEditorDecorations: IModelDeltaDecoration[] = []; - - const isBlocked = (startLineNumber: number, endLineNumber: number) => { - for (const blockedLineNumber of blockedLineNumers) { - if (startLineNumber < blockedLineNumber && blockedLineNumber <= endLineNumber) { // first line is visible - return true; - } - } - return false; - }; + const hiddenRanges = this._currentHiddenRegions(blockedLineNumers); + const newRanges = FoldingRegions.sanitizeAndMerge(newRegions, hiddenRanges, this._textModel.getLineCount()); + this.updatePost(FoldingRegions.fromFoldRanges(newRanges)); + } + public updatePost(newRegions: FoldingRegions) { + const newEditorDecorations: IModelDeltaDecoration[] = []; let lastHiddenLine = -1; - - const initRange = (index: number, isCollapsed: boolean) => { + for (let index = 0, limit = newRegions.length; index < limit; index++) { const startLineNumber = newRegions.getStartLineNumber(index); const endLineNumber = newRegions.getEndLineNumber(index); - if (!isCollapsed) { - isCollapsed = newRegions.isCollapsed(index); - } - if (isCollapsed && isBlocked(startLineNumber, endLineNumber)) { - isCollapsed = false; - } - newRegions.setCollapsed(index, isCollapsed); - - const maxColumn = this._textModel.getLineMaxColumn(startLineNumber); + const isCollapsed = newRegions.isCollapsed(index); + const isManualSelection = newRegions.isManualSelection(index); const decorationRange = { startLineNumber: startLineNumber, - startColumn: Math.max(maxColumn - 1, 1), // make it length == 1 to detect deletions - endLineNumber: startLineNumber, - endColumn: maxColumn + startColumn: this._textModel.getLineMaxColumn(startLineNumber), + endLineNumber: endLineNumber, + endColumn: this._textModel.getLineMaxColumn(endLineNumber) + 1 }; - newEditorDecorations.push({ range: decorationRange, options: this._decorationProvider.getDecorationOption(isCollapsed, endLineNumber <= lastHiddenLine) }); + newEditorDecorations.push({ range: decorationRange, options: this._decorationProvider.getDecorationOption(isCollapsed, endLineNumber <= lastHiddenLine, isManualSelection) }); if (isCollapsed && endLineNumber > lastHiddenLine) { lastHiddenLine = endLineNumber; } - }; - let i = 0; - const nextCollapsed = () => { - while (i < this._regions.length) { - const isCollapsed = this._regions.isCollapsed(i); - i++; - if (isCollapsed) { - return i - 1; + } + this._decorationProvider.changeDecorations(accessor => this._editorDecorationIds = accessor.deltaDecorations(this._editorDecorationIds, newEditorDecorations)); + this._regions = newRegions; + this._updateEventEmitter.fire({ model: this }); + } + + private _currentHiddenRegions(blockedLineNumers: number[] = []): FoldRange[] { + + const isBlocked = (startLineNumber: number, endLineNumber: number) => { + for (const blockedLineNumber of blockedLineNumers) { + if (startLineNumber < blockedLineNumber && blockedLineNumber <= endLineNumber) { // first line is visible + return true; } } - return -1; + return false; }; - let k = 0; - let collapsedIndex = nextCollapsed(); - while (collapsedIndex !== -1 && k < newRegions.length) { - // get the latest range - const decRange = this._textModel.getDecorationRange(this._editorDecorationIds[collapsedIndex]); - if (decRange) { - const collapsedStartLineNumber = decRange.startLineNumber; - if (decRange.startColumn === Math.max(decRange.endColumn - 1, 1) && this._textModel.getLineMaxColumn(collapsedStartLineNumber) === decRange.endColumn) { // test that the decoration is still covering the full line else it got deleted - while (k < newRegions.length) { - const startLineNumber = newRegions.getStartLineNumber(k); - if (collapsedStartLineNumber >= startLineNumber) { - initRange(k, collapsedStartLineNumber === startLineNumber); - k++; - } else { - break; - } - } + const hiddenRanges: FoldRange[] = []; + for (let i = 0, limit = this._regions.length; i < limit; i++) { + if (this.regions.isCollapsed(i)) { + const hiddenRange = this._regions.toFoldRange(i); + const decRange = this._textModel.getDecorationRange(this._editorDecorationIds[i]); + if (decRange + && !isBlocked(decRange.startLineNumber, decRange.endLineNumber) + // if not same length user has modified it, skip and auto-expand + && decRange.endLineNumber - decRange.startLineNumber + === hiddenRange.endLineNumber - hiddenRange.startLineNumber) { + hiddenRanges.push({ + startLineNumber: decRange.startLineNumber, + endLineNumber: decRange.endLineNumber, + type: hiddenRange.type, + isCollapsed: true, + isManualSelection: hiddenRange.isManualSelection + }); } } - collapsedIndex = nextCollapsed(); - } - while (k < newRegions.length) { - initRange(k, false); - k++; } - this._decorationProvider.changeDecorations((changeAccessor) => { - this._editorDecorationIds = changeAccessor.deltaDecorations(this._editorDecorationIds, newEditorDecorations); - }); - this._regions = newRegions; - this._isInitialized = true; - this._updateEventEmitter.fire({ model: this }); + return hiddenRanges; } /** * Collapse state memento, for persistence only */ public getMemento(): CollapseMemento | undefined { - const collapsedRanges: ILineRange[] = []; - for (let i = 0; i < this._regions.length; i++) { - if (this._regions.isCollapsed(i)) { - const range = this._textModel.getDecorationRange(this._editorDecorationIds[i]); - if (range) { - const startLineNumber = range.startLineNumber; - const endLineNumber = range.endLineNumber + this._regions.getEndLineNumber(i) - this._regions.getStartLineNumber(i); - collapsedRanges.push({ startLineNumber, endLineNumber }); - } - } + const hiddenRegions = this._currentHiddenRegions(); + const result: ILineMemento[] = []; + for (let i = 0, limit = hiddenRegions.length; i < limit; i++) { + const range = hiddenRegions[i]; + const checksum = this._getLinesChecksum(range.startLineNumber + 1, range.endLineNumber); + result.push({ + startLineNumber: range.startLineNumber, + endLineNumber: range.endLineNumber, + checksum: checksum + }); } - if (collapsedRanges.length > 0) { - return collapsedRanges; - } - return undefined; + return (result.length > 0) ? result : undefined; } /** @@ -198,14 +188,32 @@ export class FoldingModel { if (!Array.isArray(state)) { return; } - const toToogle: FoldingRegion[] = []; + const hiddenRanges: FoldRange[] = []; + const maxLineNumber = this._textModel.getLineCount(); for (const range of state) { - const region = this.getRegionAtLine(range.startLineNumber); - if (region && !region.isCollapsed) { - toToogle.push(region); + if (range.startLineNumber >= range.endLineNumber || range.startLineNumber < 1 || range.endLineNumber > maxLineNumber) { + continue; + } + const checksum = this._getLinesChecksum(range.startLineNumber + 1, range.endLineNumber); + if (!range.checksum || checksum === range.checksum) { + hiddenRanges.push({ + startLineNumber: range.startLineNumber, + endLineNumber: range.endLineNumber, + type: undefined, + isCollapsed: true, + isManualSelection: true // converts to false when provider sends a match + }); } } - this.toggleCollapseState(toToogle); + + const newRanges = FoldingRegions.sanitizeAndMerge(this._regions, hiddenRanges, maxLineNumber); + this.updatePost(FoldingRegions.fromFoldRanges(newRanges)); + } + + private _getLinesChecksum(lineNumber1: number, lineNumber2: number): number { + const h = hash(this._textModel.getLineContent(lineNumber1) + + this._textModel.getLineContent(lineNumber2)); + return h % 1000000; // 6 digits is plenty } public dispose() { diff --git a/src/vs/editor/contrib/folding/browser/foldingRanges.ts b/src/vs/editor/contrib/folding/browser/foldingRanges.ts index 0d94a26fdad..b45c3222349 100644 --- a/src/vs/editor/contrib/folding/browser/foldingRanges.ts +++ b/src/vs/editor/contrib/folding/browser/foldingRanges.ts @@ -8,6 +8,14 @@ export interface ILineRange { endLineNumber: number; } +export interface FoldRange { + startLineNumber: number; + endLineNumber: number; + type: string | undefined; + isCollapsed: boolean; + isManualSelection: boolean; +} + export const MAX_FOLDING_REGIONS = 0xFFFF; export const MAX_LINE_NUMBER = 0xFFFFFF; @@ -17,6 +25,7 @@ export class FoldingRegions { private readonly _startIndexes: Uint32Array; private readonly _endIndexes: Uint32Array; private readonly _collapseStates: Uint32Array; + private readonly _manualStates: Uint32Array; private _parentsComputed: boolean; private readonly _types: Array | undefined; @@ -26,7 +35,9 @@ export class FoldingRegions { } this._startIndexes = startIndexes; this._endIndexes = endIndexes; - this._collapseStates = new Uint32Array(Math.ceil(startIndexes.length / 32)); + const numWords = Math.ceil(startIndexes.length / 32); + this._collapseStates = new Uint32Array(numWords); + this._manualStates = new Uint32Array(numWords); this._types = types; this._parentsComputed = false; } @@ -93,6 +104,23 @@ export class FoldingRegions { } } + public isManualSelection(index: number): boolean { + const arrayIndex = (index / 32) | 0; + const bit = index % 32; + return (this._manualStates[arrayIndex] & (1 << bit)) !== 0; + } + + public setManualSelection(index: number, newState: boolean) { + const arrayIndex = (index / 32) | 0; + const bit = index % 32; + const value = this._manualStates[arrayIndex]; + if (newState) { + this._manualStates[arrayIndex] = value | (1 << bit); + } else { + this._manualStates[arrayIndex] = value & ~(1 << bit); + } + } + public setCollapsedAllOfType(type: string, newState: boolean) { let hasChanged = false; if (this._types) { @@ -160,30 +188,174 @@ export class FoldingRegions { public toString() { const res: string[] = []; for (let i = 0; i < this.length; i++) { - res[i] = `[${this.isCollapsed(i) ? '+' : '-'}] ${this.getStartLineNumber(i)}/${this.getEndLineNumber(i)}`; + res[i] = `[${this.isManualSelection(i) ? '*' : ' '}${this.isCollapsed(i) ? '+' : '-'}] ${this.getStartLineNumber(i)}/${this.getEndLineNumber(i)}`; } return res.join(', '); } - public equals(b: FoldingRegions) { - if (this.length !== b.length) { - return false; - } + public toFoldRange(index: number): FoldRange { + return { + startLineNumber: this._startIndexes[index] & MAX_LINE_NUMBER, + endLineNumber: this._endIndexes[index] & MAX_LINE_NUMBER, + type: this._types ? this._types[index] : undefined, + isCollapsed: this.isCollapsed(index), + isManualSelection: this.isManualSelection(index) + }; + } - for (let i = 0; i < this.length; i++) { - if (this.getStartLineNumber(i) !== b.getStartLineNumber(i)) { - return false; + public static fromFoldRanges(ranges: FoldRange[]): FoldingRegions { + const rangesLength = ranges.length; + const startIndexes = new Uint32Array(rangesLength); + const endIndexes = new Uint32Array(rangesLength); + let types: Array | undefined = []; + let gotTypes = false; + for (let i = 0; i < rangesLength; i++) { + const range = ranges[i]; + startIndexes[i] = range.startLineNumber; + endIndexes[i] = range.endLineNumber; + types.push(range.type); + if (range.type) { + gotTypes = true; } - if (this.getEndLineNumber(i) !== b.getEndLineNumber(i)) { - return false; + } + if (!gotTypes) { + types = undefined; + } + const regions = new FoldingRegions(startIndexes, endIndexes, types); + for (let i = 0; i < rangesLength; i++) { + if (ranges[i].isCollapsed) { + regions.setCollapsed(i, true); } - if (this.getType(i) !== b.getType(i)) { - return false; + if (ranges[i].isManualSelection) { + regions.setManualSelection(i, true); } } + return regions; + } - return true; + /** + * Two inputs, each a FoldingRegions or a FoldRange[], are merged. + * Each input must be pre-sorted on startLineNumber. + * The first list is assumed to always include all regions currently defined by range providers. + * The second list only contains hidden ranges. + * When an entry in one list overlaps an entry in the other, the second list's entry "wins" and + * overlapping entries in the first list are discarded. With one exception: when there is just + * one such second list entry and it is not manual it is discarded, on the assumption that + * user editing has resulted in the range no longer existing. + * Invalid entries are discarded. An entry is invalid if: + * the start and end line numbers aren't a valid range of line numbers, + * it is out of sequence or has the same start line as a preceding entry, + * it overlaps a preceding entry and is not fully contained by that entry. + */ + public static sanitizeAndMerge( + rangesA: FoldingRegions | FoldRange[], + rangesB: FoldingRegions | FoldRange[], + maxLineNumber: number | undefined): FoldRange[] { + maxLineNumber = maxLineNumber ?? Number.MAX_VALUE; + let result = this._trySanitizeAndMerge(1, rangesA, rangesB, maxLineNumber); + if (!result) { // try again, converting hidden ranges to manually selected + result = this._trySanitizeAndMerge(2, rangesA, rangesB, maxLineNumber); + } + return result!; } + + private static _trySanitizeAndMerge( + passNumber: number, // it can take two passes to get this done + rangesA: FoldingRegions | FoldRange[], + rangesB: FoldingRegions | FoldRange[], + maxLineNumber: number): FoldRange[] | null { + + const getIndexedFunction = (r: FoldingRegions | FoldRange[], limit: number) => { + return Array.isArray(r) + ? ((i: number) => { return (i < limit) ? r[i] : undefined; }) + : ((i: number) => { return (i < limit) ? r.toFoldRange(i) : undefined; }); + }; + const getA = getIndexedFunction(rangesA, rangesA.length); + const getB = getIndexedFunction(rangesB, rangesB.length); + let indexA = 0; + let indexB = 0; + let nextA = getA(0); + let nextB = getB(0); + + const stackedRanges: FoldRange[] = []; + let topStackedRange: FoldRange | undefined; + let prevLineNumber = 0; + const resultRanges: FoldRange[] = []; + let numberAutoExpand = 0; + + while (nextA || nextB) { + + let useRange: FoldRange | undefined = undefined; + if (nextB && (!nextA || nextA.startLineNumber >= nextB.startLineNumber)) { + // nextB is next + if (nextA + && nextA.startLineNumber === nextB.startLineNumber + && nextA.endLineNumber === nextB.endLineNumber) { + // same range in both lists, merge the details + useRange = nextB; + useRange.isCollapsed = useRange.isCollapsed || nextA.isCollapsed; + // next line removes manual flag when range provider has matching range + useRange.isManualSelection = nextA.isManualSelection && nextB.isManualSelection; + if (!useRange.type) { + useRange.type = nextA.type; + } + nextA = getA(++indexA); // not necessary, just for speed + } else if (nextB.isCollapsed && !nextB.isManualSelection && passNumber === 1) { + if (++numberAutoExpand > 1) { + // do second pass keeping these, assuming something like an unmatched /* + return null; + } + // skip nextB (auto expand) by not setting useRange, assuming it was edited + } else { // use nextB + useRange = nextB; + if (useRange.isCollapsed) { + // doesn't match nextA, convert to a manual selection if it wasn't already + useRange.isManualSelection = true; + } + } + nextB = getB(++indexB); + } else { + // nextA is next. The B set takes precedence and we sometimes need to look + // ahead in it to check for an upcoming conflict. + let scanIndex = indexB; + let prescanB = nextB; + while (true) { + if (!prescanB || prescanB.startLineNumber > nextA!.endLineNumber) { + useRange = nextA; + break; // no conflict, use this nextA + } + if (prescanB.endLineNumber > nextA!.endLineNumber + && (!prescanB.isCollapsed || prescanB.isManualSelection || passNumber === 2)) { + break; // without setting nextResult, so this nextA gets skipped + } + prescanB = getB(++scanIndex); + } + nextA = getA(++indexA); + } + + if (useRange) { + while (topStackedRange + && topStackedRange.endLineNumber < useRange.startLineNumber) { + topStackedRange = stackedRanges.pop(); + } + if (useRange.endLineNumber > useRange.startLineNumber + && useRange.startLineNumber > prevLineNumber + && useRange.endLineNumber <= maxLineNumber + && (!topStackedRange + || topStackedRange.endLineNumber >= useRange.endLineNumber)) { + resultRanges.push(useRange); + prevLineNumber = useRange.startLineNumber; + if (topStackedRange) { + stackedRanges.push(topStackedRange); + } + topStackedRange = useRange; + } + } + + } + return resultRanges; + } + } export class FoldingRegion { diff --git a/src/vs/editor/contrib/folding/browser/hiddenRangeModel.ts b/src/vs/editor/contrib/folding/browser/hiddenRangeModel.ts index a9e6f07a1bd..ea8ff076531 100644 --- a/src/vs/editor/contrib/folding/browser/hiddenRangeModel.ts +++ b/src/vs/editor/contrib/folding/browser/hiddenRangeModel.ts @@ -11,7 +11,7 @@ import { IRange, Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { IModelContentChangedEvent } from 'vs/editor/common/textModelEvents'; import { countEOL } from 'vs/editor/common/core/eolCounter'; -import { CollapseMemento, FoldingModel } from 'vs/editor/contrib/folding/browser/foldingModel'; +import { FoldingModel } from 'vs/editor/contrib/folding/browser/foldingModel'; export class HiddenRangeModel { @@ -79,28 +79,6 @@ export class HiddenRangeModel { } } - public applyMemento(state: CollapseMemento): boolean { - if (!Array.isArray(state) || state.length === 0) { - return false; - } - const hiddenRanges: IRange[] = []; - for (const r of state) { - if (!r.startLineNumber || !r.endLineNumber) { - return false; - } - hiddenRanges.push(new Range(r.startLineNumber + 1, 1, r.endLineNumber, 1)); - } - this.applyHiddenRanges(hiddenRanges); - return true; - } - - /** - * Collapse state memento, for persistence only, only used if folding model is not yet initialized - */ - public getMemento(): CollapseMemento { - return this._hiddenRanges.map(r => ({ startLineNumber: r.startLineNumber - 1, endLineNumber: r.endLineNumber })); - } - private applyHiddenRanges(newHiddenAreas: IRange[]) { this._hiddenRanges = newHiddenAreas; this._hasLineChanges = false; diff --git a/src/vs/editor/contrib/folding/browser/intializingRangeProvider.ts b/src/vs/editor/contrib/folding/browser/intializingRangeProvider.ts deleted file mode 100644 index 8d8a0ec1901..00000000000 --- a/src/vs/editor/contrib/folding/browser/intializingRangeProvider.ts +++ /dev/null @@ -1,65 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { CancellationToken } from 'vs/base/common/cancellation'; -import { IModelDeltaDecoration, ITextModel, TrackedRangeStickiness } from 'vs/editor/common/model'; -import { FoldingRegions, ILineRange } from 'vs/editor/contrib/folding/browser/foldingRanges'; -import { IFoldingRangeData, sanitizeRanges } from 'vs/editor/contrib/folding/browser/syntaxRangeProvider'; -import { RangeProvider } from './folding'; - -export const ID_INIT_PROVIDER = 'init'; - -export class InitializingRangeProvider implements RangeProvider { - readonly id = ID_INIT_PROVIDER; - - private decorationIds: string[] | undefined; - private timeout: any; - - constructor(private readonly editorModel: ITextModel, initialRanges: ILineRange[], onTimeout: () => void, timeoutTime: number) { - if (initialRanges.length) { - const toDecorationRange = (range: ILineRange): IModelDeltaDecoration => { - return { - range: { - startLineNumber: range.startLineNumber, - startColumn: 0, - endLineNumber: range.endLineNumber, - endColumn: editorModel.getLineLength(range.endLineNumber) - }, - options: { - description: 'folding-initializing-range-provider', - stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges - } - }; - }; - this.decorationIds = editorModel.deltaDecorations([], initialRanges.map(toDecorationRange)); - this.timeout = setTimeout(onTimeout, timeoutTime); - } - } - - dispose(): void { - if (this.decorationIds) { - this.editorModel.deltaDecorations(this.decorationIds, []); - this.decorationIds = undefined; - } - if (typeof this.timeout === 'number') { - clearTimeout(this.timeout); - this.timeout = undefined; - } - } - - compute(cancelationToken: CancellationToken): Promise { - const foldingRangeData: IFoldingRangeData[] = []; - if (this.decorationIds) { - for (const id of this.decorationIds) { - const range = this.editorModel.getDecorationRange(id); - if (range) { - foldingRangeData.push({ start: range.startLineNumber, end: range.endLineNumber, rank: 1 }); - } - } - } - return Promise.resolve(sanitizeRanges(foldingRangeData, Number.MAX_VALUE)); - } -} - diff --git a/src/vs/editor/contrib/folding/test/browser/foldingRanges.test.ts b/src/vs/editor/contrib/folding/test/browser/foldingRanges.test.ts index 8fbfc240fe6..a1979da3c22 100644 --- a/src/vs/editor/contrib/folding/test/browser/foldingRanges.test.ts +++ b/src/vs/editor/contrib/folding/test/browser/foldingRanges.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import { FoldingMarkers } from 'vs/editor/common/languages/languageConfiguration'; -import { MAX_FOLDING_REGIONS } from 'vs/editor/contrib/folding/browser/foldingRanges'; +import { MAX_FOLDING_REGIONS, FoldRange, FoldingRegions } from 'vs/editor/contrib/folding/browser/foldingRanges'; import { computeRanges } from 'vs/editor/contrib/folding/browser/indentRangeProvider'; import { createTextModel } from 'vs/editor/test/common/testTextModel'; @@ -14,9 +14,24 @@ const markers: FoldingMarkers = { end: /^\s*#endregion\b/ }; - suite('FoldingRanges', () => { + const foldRange = (from: number, to: number, collapsed: boolean | undefined = undefined, manual: boolean | undefined = undefined, type: string | undefined = undefined) => + { + startLineNumber: from, + endLineNumber: to, + type: type, + isCollapsed: collapsed || false, + isManualSelection: manual || false + }; + const assertEqualRanges = (range1: FoldRange, range2: FoldRange, msg: string) => { + assert.strictEqual(range1.startLineNumber, range2.startLineNumber, msg + ' start'); + assert.strictEqual(range1.endLineNumber, range2.endLineNumber, msg + ' end'); + assert.strictEqual(range1.type, range2.type, msg + ' type'); + assert.strictEqual(range1.isCollapsed, range2.isCollapsed, msg + ' collapsed'); + assert.strictEqual(range1.isManualSelection, range2.isManualSelection, msg + ' manual'); + }; + test('test max folding regions', () => { const lines: string[] = []; const nRegions = MAX_FOLDING_REGIONS; @@ -103,4 +118,114 @@ suite('FoldingRanges', () => { } model.dispose(); }); + + test('sanitizeAndMerge1', () => { + const regionSet1: FoldRange[] = [ + foldRange(0, 100), // invalid, should be removed + foldRange(1, 100, false, false, 'A'), // valid + foldRange(1, 100, false, false, 'Z'), // invalid, duplicate start + foldRange(10, 10, false), // invalid, should be removed + foldRange(20, 80, false, false, 'C1'), // valid inside 'B' + foldRange(22, 80, true, false, 'D1'), // valid inside 'C1' + foldRange(90, 101), // invalid, should be removed + ]; + const regionSet2: FoldRange[] = [ + foldRange(2, 100, false, false, 'B'), // valid, inside 'A' + foldRange(20, 80, true), // should merge with C1 + foldRange(18, 80, true), // invalid, out of order + foldRange(21, 81, true, false, 'Z'), // invalid, overlapping + foldRange(22, 80, false, false, 'D2'), // should merge with D1 + ]; + let result = FoldingRegions.sanitizeAndMerge(regionSet1, regionSet2, 100); + assert.strictEqual(result.length, 4, 'result length1'); + assertEqualRanges(result[0], foldRange(1, 100, false, false, 'A'), 'A1'); + assertEqualRanges(result[1], foldRange(2, 100, false, false, 'B'), 'B1'); + assertEqualRanges(result[2], foldRange(20, 80, true, false, 'C1'), 'C1'); + assertEqualRanges(result[3], foldRange(22, 80, true, false, 'D2'), 'D1'); + const regionClass1 = FoldingRegions.fromFoldRanges(regionSet1); + const regionClass2 = FoldingRegions.fromFoldRanges(regionSet2); + // same tests again with inputs as FoldingRegions instead of FoldRange[] + result = FoldingRegions.sanitizeAndMerge(regionClass1, regionClass2, 100); + assert.strictEqual(result.length, 4, 'result length2'); + assertEqualRanges(result[0], foldRange(1, 100, false, false, 'A'), 'A2'); + assertEqualRanges(result[1], foldRange(2, 100, false, false, 'B'), 'B2'); + assertEqualRanges(result[2], foldRange(20, 80, true, false, 'C1'), 'C2'); + assertEqualRanges(result[3], foldRange(22, 80, true, false, 'D2'), 'D2'); + }); + + test('sanitizeAndMerge2', () => { + const regionSet1: FoldRange[] = [ + foldRange(1, 100, false, false, 'a1'), // valid + foldRange(2, 100, false, false, 'a2'), // valid + foldRange(3, 19, false, false, 'a3'), // valid + foldRange(20, 71, false, false, 'a4'), // overlaps b3 + foldRange(21, 29, false, false, 'a5'), // valid + foldRange(81, 91, false, false, 'a6'), // overlaps b4 + ]; + const regionSet2: FoldRange[] = [ + foldRange(30, 39, false, false, 'b1'), // valid + foldRange(40, 49, false, false, 'b2'), // valid + foldRange(50, 100, false, false, 'b3'), // overlaps a4 + foldRange(80, 90, false, false, 'b4'), // overlaps a6 + foldRange(92, 100, false, false, 'b5'), // valid + ]; + let result = FoldingRegions.sanitizeAndMerge(regionSet1, regionSet2, 100); + assert.strictEqual(result.length, 9, 'result length1'); + assertEqualRanges(result[0], foldRange(1, 100, false, false, 'a1'), 'P1'); + assertEqualRanges(result[1], foldRange(2, 100, false, false, 'a2'), 'P2'); + assertEqualRanges(result[2], foldRange(3, 19, false, false, 'a3'), 'P3'); + assertEqualRanges(result[3], foldRange(21, 29, false, false, 'a5'), 'P4'); + assertEqualRanges(result[4], foldRange(30, 39, false, false, 'b1'), 'P5'); + assertEqualRanges(result[5], foldRange(40, 49, false, false, 'b2'), 'P6'); + assertEqualRanges(result[6], foldRange(50, 100, false, false, 'b3'), 'P7'); + assertEqualRanges(result[7], foldRange(80, 90, false, false, 'b4'), 'P8'); + assertEqualRanges(result[8], foldRange(92, 100, false, false, 'b5'), 'P9'); + // reverse the two inputs + result = FoldingRegions.sanitizeAndMerge(regionSet2, regionSet1, 100); + assert.strictEqual(result.length, 9, 'result length2'); + assertEqualRanges(result[0], foldRange(1, 100, false, false, 'a1'), 'Q1'); + assertEqualRanges(result[1], foldRange(2, 100, false, false, 'a2'), 'Q2'); + assertEqualRanges(result[2], foldRange(3, 19, false, false, 'a3'), 'Q3'); + assertEqualRanges(result[3], foldRange(20, 71, false, false, 'a4'), 'Q4'); + assertEqualRanges(result[4], foldRange(21, 29, false, false, 'a5'), 'Q5'); + assertEqualRanges(result[5], foldRange(30, 39, false, false, 'b1'), 'Q6'); + assertEqualRanges(result[6], foldRange(40, 49, false, false, 'b2'), 'Q7'); + assertEqualRanges(result[7], foldRange(81, 91, false, false, 'a6'), 'Q8'); + assertEqualRanges(result[8], foldRange(92, 100, false, false, 'b5'), 'Q9'); + }); + + test('sanitizeAndMerge3', () => { + const regionSet1: FoldRange[] = [ + foldRange(1, 100, false, false, 'a1'), // valid + foldRange(10, 29, false, false, 'a2'), // matches manual hidden + foldRange(35, 39, true, true, 'a3'), // valid + ]; + const regionSet2: FoldRange[] = [ + foldRange(10, 29, true, true, 'b1'), // matches a + foldRange(20, 28, true, false, 'b2'), // should get dropped + foldRange(30, 39, true, true, 'b3'), // should remain + ]; + const result = FoldingRegions.sanitizeAndMerge(regionSet1, regionSet2, 100); + assert.strictEqual(result.length, 4, 'result length3'); + assertEqualRanges(result[0], foldRange(1, 100, false, false, 'a1'), 'R1'); + assertEqualRanges(result[1], foldRange(10, 29, true, false, 'b1'), 'R2'); + assertEqualRanges(result[2], foldRange(30, 39, true, true, 'b3'), 'R3'); + assertEqualRanges(result[3], foldRange(35, 39, true, true, 'a3'), 'R4'); + }); + + test('sanitizeAndMerge4', () => { + const regionSet1: FoldRange[] = [ + foldRange(1, 100, false, false, 'a1'), // valid + ]; + const regionSet2: FoldRange[] = [ + foldRange(20, 28, true, false, 'b1'), // hidden + foldRange(30, 38, true, false, 'b2'), // hidden + ]; + const result = FoldingRegions.sanitizeAndMerge(regionSet1, regionSet2, 100); + assert.strictEqual(result.length, 3, 'result length4'); + assertEqualRanges(result[0], foldRange(1, 100, false, false, 'a1'), 'R1'); + assertEqualRanges(result[1], foldRange(20, 28, true, true, 'b1'), 'R2'); + assertEqualRanges(result[2], foldRange(30, 38, true, true, 'b2'), 'R3'); + }); + }); -- cgit v1.2.3 From e209a0967f786f2b29cca012e97d6dcd853fbe79 Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 11 Jul 2022 15:44:04 +0200 Subject: fix tests... --- src/vs/platform/actions/test/common/menuService.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/platform/actions/test/common/menuService.test.ts b/src/vs/platform/actions/test/common/menuService.test.ts index e869c726cd1..d1eb35d24f8 100644 --- a/src/vs/platform/actions/test/common/menuService.test.ts +++ b/src/vs/platform/actions/test/common/menuService.test.ts @@ -5,6 +5,7 @@ import * as assert from 'assert'; import { DisposableStore } from 'vs/base/common/lifecycle'; +import { generateUuid } from 'vs/base/common/uuid'; import { isIMenuItem, MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; import { MenuService } from 'vs/platform/actions/common/menuService'; import { NullCommandService } from 'vs/platform/commands/common/commands'; @@ -29,7 +30,7 @@ suite('MenuService', function () { setup(function () { menuService = new MenuService(NullCommandService, new InMemoryStorageService()); - testMenuId = new MenuId('testo'); + testMenuId = new MenuId(`testo/${generateUuid()}`); disposables.clear(); }); -- cgit v1.2.3 From 6d71bae80763122910da47f9c09553078a66117c Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 11 Jul 2022 07:07:09 -0700 Subject: Remove onDidChangeName proposed API It's already stable --- src/vs/workbench/services/extensions/common/extensionsApiProposals.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index f735af27335..7eaccd716e3 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -55,7 +55,6 @@ export const allApiProposals = Object.freeze({ telemetry: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.telemetry.d.ts', terminalDataWriteEvent: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalDataWriteEvent.d.ts', terminalDimensions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalDimensions.d.ts', - terminalNameChangeEvent: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalNameChangeEvent.d.ts', testCoverage: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testCoverage.d.ts', testObserver: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testObserver.d.ts', textEditorDrop: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.textEditorDrop.d.ts', -- cgit v1.2.3 From 34b40746c78877d5aacb089c526b2ea665c548ab Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 11 Jul 2022 07:15:01 -0700 Subject: setExitCode -> setExitStatus --- src/vs/workbench/api/common/extHostTerminalService.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index 69560c5729d..0f5ebe088fb 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -203,7 +203,7 @@ export class ExtHostTerminal { this._name = name; } - public setExitCode(code: number | undefined, reason: TerminalExitReason) { + public setExitStatus(code: number | undefined, reason: TerminalExitReason) { this._exitStatus = Object.freeze({ code, reason }); } @@ -504,7 +504,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I const index = this._getTerminalObjectIndexById(this._terminals, id); if (index !== null) { const terminal = this._terminals.splice(index, 1)[0]; - terminal.setExitCode(exitCode, exitReason); + terminal.setExitStatus(exitCode, exitReason); this._onDidCloseTerminal.fire(terminal.value); } } -- cgit v1.2.3 From 51ae229d95023dbc1e191b7614f8c566f9db037c Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Mon, 11 Jul 2022 10:52:01 -0400 Subject: Move telemetry test from electron-browser to browser (#154805) Update appender tests --- src/vs/platform/telemetry/browser/1dsAppender.ts | 2 +- src/vs/platform/telemetry/common/1dsAppender.ts | 4 + .../telemetry/test/browser/1dsAppender.test.ts | 132 +++++++++++++++++++++ .../test/electron-browser/1dsAppender.test.ts | 132 --------------------- 4 files changed, 137 insertions(+), 133 deletions(-) create mode 100644 src/vs/platform/telemetry/test/browser/1dsAppender.test.ts delete mode 100644 src/vs/platform/telemetry/test/electron-browser/1dsAppender.test.ts (limited to 'src/vs') diff --git a/src/vs/platform/telemetry/browser/1dsAppender.ts b/src/vs/platform/telemetry/browser/1dsAppender.ts index 96db1e7890b..5075fdfc7df 100644 --- a/src/vs/platform/telemetry/browser/1dsAppender.ts +++ b/src/vs/platform/telemetry/browser/1dsAppender.ts @@ -10,7 +10,7 @@ import { AbstractOneDataSystemAppender } from 'vs/platform/telemetry/common/1dsA export class OneDataSystemWebAppender extends AbstractOneDataSystemAppender { constructor( - configurationService: IConfigurationService, + configurationService: IConfigurationService | undefined, eventPrefix: string, defaultData: { [key: string]: any } | null, iKeyOrClientFactory: string | (() => AppInsightsCore), // allow factory function for testing diff --git a/src/vs/platform/telemetry/common/1dsAppender.ts b/src/vs/platform/telemetry/common/1dsAppender.ts index ba7cac9d693..7823821070f 100644 --- a/src/vs/platform/telemetry/common/1dsAppender.ts +++ b/src/vs/platform/telemetry/common/1dsAppender.ts @@ -115,6 +115,10 @@ export abstract class AbstractOneDataSystemAppender implements ITelemetryAppende data = validateTelemetryData(data); const name = this._eventPrefix + '/' + eventName; + if (data?.properties?.version) { + data.properties.pluginVersionString = data.properties.version; + } + try { this._withAIClient((aiClient) => aiClient.track({ name, diff --git a/src/vs/platform/telemetry/test/browser/1dsAppender.test.ts b/src/vs/platform/telemetry/test/browser/1dsAppender.test.ts new file mode 100644 index 00000000000..0c0378845ab --- /dev/null +++ b/src/vs/platform/telemetry/test/browser/1dsAppender.test.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { AppInsightsCore } from '@microsoft/1ds-core-js'; +import * as assert from 'assert'; +import { OneDataSystemWebAppender } from 'vs/platform/telemetry/browser/1dsAppender'; + +class AppInsightsCoreMock extends AppInsightsCore { + public override config: any; + public events: any[] = []; + public IsTrackingPageView: boolean = false; + public exceptions: any[] = []; + + constructor() { + super(); + } + + public override track(event: any) { + this.events.push(event.baseData); + } + + public override flush(options: any): void { + // called on dispose + } +} + +suite('AIAdapter', () => { + let appInsightsMock: AppInsightsCoreMock; + let adapter: OneDataSystemWebAppender; + const prefix = 'prefix'; + + + setup(() => { + appInsightsMock = new AppInsightsCoreMock(); + adapter = new OneDataSystemWebAppender(undefined, prefix, undefined!, () => appInsightsMock); + }); + + teardown(() => { + adapter.flush(); + }); + + test('Simple event', () => { + adapter.log('testEvent'); + + assert.strictEqual(appInsightsMock.events.length, 1); + assert.strictEqual(appInsightsMock.events[0].name, `${prefix}/testEvent`); + }); + + test('addional data', () => { + adapter = new OneDataSystemWebAppender(undefined, prefix, { first: '1st', second: 2, third: true }, () => appInsightsMock); + adapter.log('testEvent'); + + assert.strictEqual(appInsightsMock.events.length, 1); + const [first] = appInsightsMock.events; + assert.strictEqual(first.name, `${prefix}/testEvent`); + assert.strictEqual(first.properties!['first'], '1st'); + assert.strictEqual(first.measurements!['second'], 2); + assert.strictEqual(first.measurements!['third'], 1); + }); + + test('property limits', () => { + let reallyLongPropertyName = 'abcdefghijklmnopqrstuvwxyz'; + for (let i = 0; i < 6; i++) { + reallyLongPropertyName += 'abcdefghijklmnopqrstuvwxyz'; + } + assert(reallyLongPropertyName.length > 150); + + let reallyLongPropertyValue = 'abcdefghijklmnopqrstuvwxyz012345678901234567890123'; + for (let i = 0; i < 400; i++) { + reallyLongPropertyValue += 'abcdefghijklmnopqrstuvwxyz012345678901234567890123'; + } + assert(reallyLongPropertyValue.length > 8192); + + const data = Object.create(null); + data[reallyLongPropertyName] = '1234'; + data['reallyLongPropertyValue'] = reallyLongPropertyValue; + adapter.log('testEvent', data); + + assert.strictEqual(appInsightsMock.events.length, 1); + + for (const prop in appInsightsMock.events[0].properties!) { + assert(prop.length < 150); + assert(appInsightsMock.events[0].properties![prop].length < 8192); + } + }); + + test('Different data types', () => { + const date = new Date(); + adapter.log('testEvent', { favoriteDate: date, likeRed: false, likeBlue: true, favoriteNumber: 1, favoriteColor: 'blue', favoriteCars: ['bmw', 'audi', 'ford'] }); + + assert.strictEqual(appInsightsMock.events.length, 1); + assert.strictEqual(appInsightsMock.events[0].name, `${prefix}/testEvent`); + assert.strictEqual(appInsightsMock.events[0].properties!['favoriteColor'], 'blue'); + assert.strictEqual(appInsightsMock.events[0].measurements!['likeRed'], 0); + assert.strictEqual(appInsightsMock.events[0].measurements!['likeBlue'], 1); + assert.strictEqual(appInsightsMock.events[0].properties!['favoriteDate'], date.toISOString()); + assert.strictEqual(appInsightsMock.events[0].properties!['favoriteCars'], JSON.stringify(['bmw', 'audi', 'ford'])); + assert.strictEqual(appInsightsMock.events[0].measurements!['favoriteNumber'], 1); + }); + + test('Nested data', () => { + adapter.log('testEvent', { + window: { + title: 'some title', + measurements: { + width: 100, + height: 200 + } + }, + nestedObj: { + nestedObj2: { + nestedObj3: { + testProperty: 'test', + } + }, + testMeasurement: 1 + } + }); + + assert.strictEqual(appInsightsMock.events.length, 1); + assert.strictEqual(appInsightsMock.events[0].name, `${prefix}/testEvent`); + + assert.strictEqual(appInsightsMock.events[0].properties!['window.title'], 'some title'); + assert.strictEqual(appInsightsMock.events[0].measurements!['window.measurements.width'], 100); + assert.strictEqual(appInsightsMock.events[0].measurements!['window.measurements.height'], 200); + + assert.strictEqual(appInsightsMock.events[0].properties!['nestedObj.nestedObj2.nestedObj3'], JSON.stringify({ 'testProperty': 'test' })); + assert.strictEqual(appInsightsMock.events[0].measurements!['nestedObj.testMeasurement'], 1); + }); + +}); diff --git a/src/vs/platform/telemetry/test/electron-browser/1dsAppender.test.ts b/src/vs/platform/telemetry/test/electron-browser/1dsAppender.test.ts deleted file mode 100644 index 3b734414796..00000000000 --- a/src/vs/platform/telemetry/test/electron-browser/1dsAppender.test.ts +++ /dev/null @@ -1,132 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -import { AppInsightsCore } from '@microsoft/1ds-core-js'; -import * as assert from 'assert'; -import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender'; - -class AppInsightsCoreMock extends AppInsightsCore { - public override config: any; - public events: any[] = []; - public IsTrackingPageView: boolean = false; - public exceptions: any[] = []; - - constructor() { - super(); - } - - public override track(event: any) { - this.events.push(event.baseData); - } - - public override flush(options: any): void { - // called on dispose - } -} - -suite('AIAdapter', () => { - let appInsightsMock: AppInsightsCoreMock; - let adapter: OneDataSystemAppender; - const prefix = 'prefix'; - - - setup(() => { - appInsightsMock = new AppInsightsCoreMock(); - adapter = new OneDataSystemAppender(undefined, prefix, undefined!, () => appInsightsMock); - }); - - teardown(() => { - adapter.flush(); - }); - - test('Simple event', () => { - adapter.log('testEvent'); - - assert.strictEqual(appInsightsMock.events.length, 1); - assert.strictEqual(appInsightsMock.events[0].name, `${prefix}/testEvent`); - }); - - test('addional data', () => { - adapter = new OneDataSystemAppender(undefined, prefix, { first: '1st', second: 2, third: true }, () => appInsightsMock); - adapter.log('testEvent'); - - assert.strictEqual(appInsightsMock.events.length, 1); - const [first] = appInsightsMock.events; - assert.strictEqual(first.name, `${prefix}/testEvent`); - assert.strictEqual(first.properties!['first'], '1st'); - assert.strictEqual(first.measurements!['second'], 2); - assert.strictEqual(first.measurements!['third'], 1); - }); - - test('property limits', () => { - let reallyLongPropertyName = 'abcdefghijklmnopqrstuvwxyz'; - for (let i = 0; i < 6; i++) { - reallyLongPropertyName += 'abcdefghijklmnopqrstuvwxyz'; - } - assert(reallyLongPropertyName.length > 150); - - let reallyLongPropertyValue = 'abcdefghijklmnopqrstuvwxyz012345678901234567890123'; - for (let i = 0; i < 400; i++) { - reallyLongPropertyValue += 'abcdefghijklmnopqrstuvwxyz012345678901234567890123'; - } - assert(reallyLongPropertyValue.length > 8192); - - const data = Object.create(null); - data[reallyLongPropertyName] = '1234'; - data['reallyLongPropertyValue'] = reallyLongPropertyValue; - adapter.log('testEvent', data); - - assert.strictEqual(appInsightsMock.events.length, 1); - - for (const prop in appInsightsMock.events[0].properties!) { - assert(prop.length < 150); - assert(appInsightsMock.events[0].properties![prop].length < 8192); - } - }); - - test('Different data types', () => { - const date = new Date(); - adapter.log('testEvent', { favoriteDate: date, likeRed: false, likeBlue: true, favoriteNumber: 1, favoriteColor: 'blue', favoriteCars: ['bmw', 'audi', 'ford'] }); - - assert.strictEqual(appInsightsMock.events.length, 1); - assert.strictEqual(appInsightsMock.events[0].name, `${prefix}/testEvent`); - assert.strictEqual(appInsightsMock.events[0].properties!['favoriteColor'], 'blue'); - assert.strictEqual(appInsightsMock.events[0].measurements!['likeRed'], 0); - assert.strictEqual(appInsightsMock.events[0].measurements!['likeBlue'], 1); - assert.strictEqual(appInsightsMock.events[0].properties!['favoriteDate'], date.toISOString()); - assert.strictEqual(appInsightsMock.events[0].properties!['favoriteCars'], JSON.stringify(['bmw', 'audi', 'ford'])); - assert.strictEqual(appInsightsMock.events[0].measurements!['favoriteNumber'], 1); - }); - - test('Nested data', () => { - adapter.log('testEvent', { - window: { - title: 'some title', - measurements: { - width: 100, - height: 200 - } - }, - nestedObj: { - nestedObj2: { - nestedObj3: { - testProperty: 'test', - } - }, - testMeasurement: 1 - } - }); - - assert.strictEqual(appInsightsMock.events.length, 1); - assert.strictEqual(appInsightsMock.events[0].name, `${prefix}/testEvent`); - - assert.strictEqual(appInsightsMock.events[0].properties!['window.title'], 'some title'); - assert.strictEqual(appInsightsMock.events[0].measurements!['window.measurements.width'], 100); - assert.strictEqual(appInsightsMock.events[0].measurements!['window.measurements.height'], 200); - - assert.strictEqual(appInsightsMock.events[0].properties!['nestedObj.nestedObj2.nestedObj3'], JSON.stringify({ 'testProperty': 'test' })); - assert.strictEqual(appInsightsMock.events[0].measurements!['nestedObj.testMeasurement'], 1); - }); - -}); -- cgit v1.2.3 From 6701dd54d6d2f8e3a140551a28d1787387c158b0 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Mon, 11 Jul 2022 16:54:38 +0200 Subject: SCM - Commit action button accessibility improvements (#154817) Commit action button accessibility improvements --- src/vs/base/browser/ui/button/button.ts | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/vs') diff --git a/src/vs/base/browser/ui/button/button.ts b/src/vs/base/browser/ui/button/button.ts index 63833653b7c..e84fd5374a5 100644 --- a/src/vs/base/browser/ui/button/button.ts +++ b/src/vs/base/browser/ui/button/button.ts @@ -274,6 +274,8 @@ export class ButtonWithDropdown extends Disposable implements IButton { this.dropdownButton = this._register(new Button(this.element, { ...options, title: false, supportIcons: true })); this.dropdownButton.element.title = localize("button dropdown more actions", 'More Actions...'); + this.dropdownButton.element.setAttribute('aria-haspopup', 'true'); + this.dropdownButton.element.setAttribute('aria-expanded', 'false'); this.dropdownButton.element.classList.add('monaco-dropdown-button'); this.dropdownButton.icon = Codicon.dropDownButton; this._register(this.dropdownButton.onDidClick(e => { -- cgit v1.2.3 From ada844686bb002d3ff4003bba5748b608fec0219 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Mon, 11 Jul 2022 17:23:07 +0200 Subject: Button - Do no change the style on focus/blur if the button is disabled (#154253) Do no change the style on focus/blur if the button is disabled --- src/vs/base/browser/ui/button/button.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/base/browser/ui/button/button.ts b/src/vs/base/browser/ui/button/button.ts index e84fd5374a5..489425b6ce4 100644 --- a/src/vs/base/browser/ui/button/button.ts +++ b/src/vs/base/browser/ui/button/button.ts @@ -137,8 +137,8 @@ export class Button extends Disposable implements IButton { // Also set hover background when button is focused for feedback this.focusTracker = this._register(trackFocus(this._element)); - this._register(this.focusTracker.onDidFocus(() => this.setHoverBackground())); - this._register(this.focusTracker.onDidBlur(() => this.applyStyles())); // restore standard styles + this._register(this.focusTracker.onDidFocus(() => { if (this.enabled) { this.setHoverBackground(); } })); + this._register(this.focusTracker.onDidBlur(() => { if (this.enabled) { this.applyStyles(); } })); this.applyStyles(); } -- cgit v1.2.3 From ca5430942daf044b8f40545f6811d21173a84591 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 11 Jul 2022 17:53:08 +0200 Subject: broadcast profiles changes to other windows (#154782) * broadcast profiles changes to other windows * - add type to broadcast data - adopt in storage service --- src/vs/base/browser/broadcast.ts | 69 +++++++++++++++++ .../files/browser/indexedDBFileSystemProvider.ts | 90 +++------------------- .../userDataProfile/browser/userDataProfile.ts | 19 ++++- .../userDataProfile/common/userDataProfile.ts | 4 + .../services/storage/browser/storageService.ts | 21 ++--- 5 files changed, 109 insertions(+), 94 deletions(-) create mode 100644 src/vs/base/browser/broadcast.ts (limited to 'src/vs') diff --git a/src/vs/base/browser/broadcast.ts b/src/vs/base/browser/broadcast.ts new file mode 100644 index 00000000000..d7785f42ff8 --- /dev/null +++ b/src/vs/base/browser/broadcast.ts @@ -0,0 +1,69 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { getErrorMessage } from 'vs/base/common/errors'; +import { Emitter } from 'vs/base/common/event'; +import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; + +export class BroadcastDataChannel extends Disposable { + + private broadcastChannel: BroadcastChannel | undefined; + + private readonly _onDidReceiveData = this._register(new Emitter()); + readonly onDidReceiveData = this._onDidReceiveData.event; + + constructor(private readonly channelName: string) { + super(); + + // Use BroadcastChannel + if ('BroadcastChannel' in window) { + try { + this.broadcastChannel = new BroadcastChannel(channelName); + const listener = (event: MessageEvent) => { + this._onDidReceiveData.fire(event.data); + }; + this.broadcastChannel.addEventListener('message', listener); + this._register(toDisposable(() => { + if (this.broadcastChannel) { + this.broadcastChannel.removeEventListener('message', listener); + this.broadcastChannel.close(); + } + })); + } catch (error) { + console.warn('Error while creating broadcast channel. Falling back to localStorage.', getErrorMessage(error)); + } + } + + // BroadcastChannel is not supported. Use storage. + if (!this.broadcastChannel) { + this.channelName = `BroadcastDataChannel.${channelName}`; + this.createBroadcastChannel(); + } + } + + private createBroadcastChannel(): void { + const listener = (event: StorageEvent) => { + if (event.key === this.channelName && event.newValue) { + this._onDidReceiveData.fire(JSON.parse(event.newValue)); + } + }; + window.addEventListener('storage', listener); + this._register(toDisposable(() => window.removeEventListener('storage', listener))); + } + + /** + * Sends the data to other BroadcastChannel objects set up for this channel. Data can be structured objects, e.g. nested objects and arrays. + * @param data data to broadcast + */ + postData(data: T): void { + if (this.broadcastChannel) { + this.broadcastChannel.postMessage(data); + } else { + // remove previous changes so that event is triggered even if new changes are same as old changes + window.localStorage.removeItem(this.channelName); + window.localStorage.setItem(this.channelName, JSON.stringify(data)); + } + } +} diff --git a/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts b/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts index af4458fe1c0..660dd5cdcc1 100644 --- a/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts +++ b/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts @@ -5,15 +5,15 @@ import { Throttler } from 'vs/base/common/async'; import { VSBuffer } from 'vs/base/common/buffer'; -import { getErrorMessage } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; -import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { ExtUri } from 'vs/base/common/resources'; -import { isString } from 'vs/base/common/types'; -import { URI, UriComponents } from 'vs/base/common/uri'; +import { isString, UriDto } from 'vs/base/common/types'; +import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { createFileSystemProviderError, FileChangeType, IFileDeleteOptions, IFileOverwriteOptions, FileSystemProviderCapabilities, FileSystemProviderError, FileSystemProviderErrorCode, FileType, IFileWriteOptions, IFileChange, IFileSystemProviderWithFileReadWriteCapability, IStat, IWatchOptions } from 'vs/platform/files/common/files'; import { DBClosedError, IndexedDB } from 'vs/base/browser/indexedDB'; +import { BroadcastDataChannel } from 'vs/base/browser/broadcast'; export type IndexedDBFileSystemProviderErrorDataClassification = { owner: 'sandy081'; @@ -165,78 +165,6 @@ class IndexedDBFileSystemNode { } } -type FileChangeDto = { - readonly type: FileChangeType; - readonly resource: UriComponents; -}; - -class IndexedDBChangesBroadcastChannel extends Disposable { - - private broadcastChannel: BroadcastChannel | undefined; - - private readonly _onDidFileChanges = this._register(new Emitter()); - readonly onDidFileChanges: Event = this._onDidFileChanges.event; - - constructor(private readonly changesKey: string) { - super(); - - // Use BroadcastChannel - if ('BroadcastChannel' in window) { - try { - this.broadcastChannel = new BroadcastChannel(changesKey); - const listener = (event: MessageEvent) => { - if (isString(event.data)) { - this.onDidReceiveChanges(event.data); - } - }; - this.broadcastChannel.addEventListener('message', listener); - this._register(toDisposable(() => { - if (this.broadcastChannel) { - this.broadcastChannel.removeEventListener('message', listener); - this.broadcastChannel.close(); - } - })); - } catch (error) { - console.warn('Error while creating broadcast channel. Falling back to localStorage.', getErrorMessage(error)); - this.createStorageBroadcastChannel(changesKey); - } - } - - // BroadcastChannel is not supported. Use storage. - else { - this.createStorageBroadcastChannel(changesKey); - } - } - - private createStorageBroadcastChannel(changesKey: string): void { - const listener = (event: StorageEvent) => { - if (event.key === changesKey && event.newValue) { - this.onDidReceiveChanges(event.newValue); - } - }; - window.addEventListener('storage', listener); - this._register(toDisposable(() => window.removeEventListener('storage', listener))); - } - - private onDidReceiveChanges(data: string): void { - try { - const changesDto: FileChangeDto[] = JSON.parse(data); - this._onDidFileChanges.fire(changesDto.map(c => ({ type: c.type, resource: URI.revive(c.resource) }))); - } catch (error) {/* ignore*/ } - } - - postChanges(changes: IFileChange[]): void { - if (this.broadcastChannel) { - this.broadcastChannel.postMessage(JSON.stringify(changes)); - } else { - // remove previous changes so that event is triggered even if new changes are same as old changes - window.localStorage.removeItem(this.changesKey); - window.localStorage.setItem(this.changesKey, JSON.stringify(changes)); - } - } - -} - export class IndexedDBFileSystemProvider extends Disposable implements IFileSystemProviderWithFileReadWriteCapability { readonly capabilities: FileSystemProviderCapabilities = @@ -246,7 +174,7 @@ export class IndexedDBFileSystemProvider extends Disposable implements IFileSyst private readonly extUri = new ExtUri(() => false) /* Case Sensitive */; - private readonly changesBroadcastChannel: IndexedDBChangesBroadcastChannel | undefined; + private readonly changesBroadcastChannel: BroadcastDataChannel[]> | undefined; private readonly _onDidChangeFile = this._register(new Emitter()); readonly onDidChangeFile: Event = this._onDidChangeFile.event; @@ -263,8 +191,10 @@ export class IndexedDBFileSystemProvider extends Disposable implements IFileSyst this.writeManyThrottler = new Throttler(); if (watchCrossWindowChanges) { - this.changesBroadcastChannel = this._register(new IndexedDBChangesBroadcastChannel(`vscode.indexedDB.${scheme}.changes`)); - this._register(this.changesBroadcastChannel.onDidFileChanges(changes => this._onDidChangeFile.fire(changes))); + this.changesBroadcastChannel = this._register(new BroadcastDataChannel[]>(`vscode.indexedDB.${scheme}.changes`)); + this._register(this.changesBroadcastChannel.onDidReceiveData(changes => { + this._onDidChangeFile.fire(changes.map(c => ({ type: c.type, resource: URI.revive(c.resource) }))); + })); } } @@ -459,7 +389,7 @@ export class IndexedDBFileSystemProvider extends Disposable implements IFileSyst if (changes.length) { this._onDidChangeFile.fire(changes); - this.changesBroadcastChannel?.postChanges(changes); + this.changesBroadcastChannel?.postData(changes); } } diff --git a/src/vs/platform/userDataProfile/browser/userDataProfile.ts b/src/vs/platform/userDataProfile/browser/userDataProfile.ts index 56edfc09480..b00f89a92b7 100644 --- a/src/vs/platform/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/browser/userDataProfile.ts @@ -3,16 +3,21 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { BroadcastDataChannel } from 'vs/base/browser/broadcast'; import { revive } from 'vs/base/common/marshalling'; +import { UriDto } from 'vs/base/common/types'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; import { ILogService } from 'vs/platform/log/common/log'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { IUserDataProfilesService, PROFILES_ENABLEMENT_CONFIG, StoredProfileAssociations, StoredUserDataProfile, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; +import { DidChangeProfilesEvent, IUserDataProfile, IUserDataProfilesService, PROFILES_ENABLEMENT_CONFIG, reviveProfile, StoredProfileAssociations, StoredUserDataProfile, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; + +type BroadcastedProfileChanges = UriDto>; export class BrowserUserDataProfilesService extends UserDataProfilesService implements IUserDataProfilesService { protected override readonly defaultProfileShouldIncludeExtensionsResourceAlways: boolean = true; + private readonly changesBroadcastChannel: BroadcastDataChannel; constructor( @IEnvironmentService environmentService: IEnvironmentService, @@ -22,6 +27,13 @@ export class BrowserUserDataProfilesService extends UserDataProfilesService impl ) { super(environmentService, fileService, uriIdentityService, logService); super.setEnablement(window.localStorage.getItem(PROFILES_ENABLEMENT_CONFIG) === 'true'); + this.changesBroadcastChannel = this._register(new BroadcastDataChannel(`${UserDataProfilesService.PROFILES_KEY}.changes`)); + this._register(this.changesBroadcastChannel.onDidReceiveData(changes => { + try { + this._profilesObject = undefined; + this._onDidChangeProfiles.fire({ added: changes.added.map(p => reviveProfile(p, this.profilesHome.scheme)), removed: changes.removed.map(p => reviveProfile(p, this.profilesHome.scheme)), all: this.profiles }); + } catch (error) {/* ignore */ } + })); } override setEnablement(enabled: boolean): void { @@ -42,6 +54,11 @@ export class BrowserUserDataProfilesService extends UserDataProfilesService impl return []; } + protected override triggerProfilesChanges(added: IUserDataProfile[], removed: IUserDataProfile[]) { + super.triggerProfilesChanges(added, removed); + this.changesBroadcastChannel.postData({ added, removed }); + } + protected override saveStoredProfiles(storedProfiles: StoredUserDataProfile[]): void { window.localStorage.setItem(UserDataProfilesService.PROFILES_KEY, JSON.stringify(storedProfiles)); } diff --git a/src/vs/platform/userDataProfile/common/userDataProfile.ts b/src/vs/platform/userDataProfile/common/userDataProfile.ts index 53ab77f58ec..3bc2eb4ea3d 100644 --- a/src/vs/platform/userDataProfile/common/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/common/userDataProfile.ts @@ -338,6 +338,10 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf } this.saveStoredProfiles(storedProfiles); this._profilesObject = undefined; + this.triggerProfilesChanges(added, removed); + } + + protected triggerProfilesChanges(added: IUserDataProfile[], removed: IUserDataProfile[]) { this._onDidChangeProfiles.fire({ added, removed, all: this.profiles }); } diff --git a/src/vs/workbench/services/storage/browser/storageService.ts b/src/vs/workbench/services/storage/browser/storageService.ts index e267855723c..0266871f498 100644 --- a/src/vs/workbench/services/storage/browser/storageService.ts +++ b/src/vs/workbench/services/storage/browser/storageService.ts @@ -3,12 +3,13 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { BroadcastDataChannel } from 'vs/base/browser/broadcast'; import { isSafari } from 'vs/base/browser/browser'; import { IndexedDB } from 'vs/base/browser/indexedDB'; import { DeferredPromise, Promises } from 'vs/base/common/async'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { Emitter } from 'vs/base/common/event'; -import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { assertIsDefined } from 'vs/base/common/types'; import { InMemoryStorageDatabase, isStorageItemsChangeEvent, IStorage, IStorageDatabase, IStorageItemsChangeEvent, IUpdateRequest, Storage } from 'vs/base/parts/storage/common/storage'; import { ILogService } from 'vs/platform/log/common/log'; @@ -302,7 +303,7 @@ export class IndexedDBStorageDatabase extends Disposable implements IIndexedDBSt private readonly _onDidChangeItemsExternal = this._register(new Emitter()); readonly onDidChangeItemsExternal = this._onDidChangeItemsExternal.event; - private broadcastChannel: BroadcastChannel | undefined; + private broadcastChannel: BroadcastDataChannel | undefined; private pendingUpdate: Promise | undefined = undefined; get hasPendingUpdate(): boolean { return !!this.pendingUpdate; } @@ -317,7 +318,7 @@ export class IndexedDBStorageDatabase extends Disposable implements IIndexedDBSt super(); this.name = `${IndexedDBStorageDatabase.STORAGE_DATABASE_PREFIX}${options.id}`; - this.broadcastChannel = options.broadcastChanges && ('BroadcastChannel' in window) ? new BroadcastChannel(IndexedDBStorageDatabase.STORAGE_BROADCAST_CHANNEL) : undefined; + this.broadcastChannel = options.broadcastChanges ? this._register(new BroadcastDataChannel(IndexedDBStorageDatabase.STORAGE_BROADCAST_CHANNEL)) : undefined; this.whenConnected = this.connect(); @@ -329,16 +330,10 @@ export class IndexedDBStorageDatabase extends Disposable implements IIndexedDBSt // Check for storage change events from other // windows/tabs via `BroadcastChannel` mechanisms. if (this.broadcastChannel) { - const listener = (event: MessageEvent) => { - if (isStorageItemsChangeEvent(event.data)) { - this._onDidChangeItemsExternal.fire(event.data); + this._register(this.broadcastChannel.onDidReceiveData(data => { + if (isStorageItemsChangeEvent(data)) { + this._onDidChangeItemsExternal.fire(data); } - }; - - this.broadcastChannel.addEventListener('message', listener); - this._register(toDisposable(() => { - this.broadcastChannel?.removeEventListener('message', listener); - this.broadcastChannel?.close(); })); } } @@ -382,7 +377,7 @@ export class IndexedDBStorageDatabase extends Disposable implements IIndexedDBSt deleted: request.delete }; - this.broadcastChannel.postMessage(event); + this.broadcastChannel.postData(event); } } -- cgit v1.2.3 From c137fb2ef769f7d34e7a2f5b3ef94774ffdbb8f5 Mon Sep 17 00:00:00 2001 From: Idefix2020 Date: Mon, 11 Jul 2022 19:10:35 +0200 Subject: Better TypedArray type checking (#153929) Check if the object is an instance of any TypedArray (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#description) --- src/vs/base/common/types.ts | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'src/vs') diff --git a/src/vs/base/common/types.ts b/src/vs/base/common/types.ts index 50ac38cf407..3e1cb2a7354 100644 --- a/src/vs/base/common/types.ts +++ b/src/vs/base/common/types.ts @@ -47,18 +47,9 @@ export function isObject(obj: unknown): obj is Object { * @returns whether the provided parameter is of type `Buffer` or Uint8Array dervived type */ export function isTypedArray(obj: unknown): obj is Object { + const TypedArray = Object.getPrototypeOf(Uint8Array); return typeof obj === 'object' - && (obj instanceof Uint8Array || - obj instanceof Uint16Array || - obj instanceof Uint32Array || - obj instanceof Float32Array || - obj instanceof Float64Array || - obj instanceof Int8Array || - obj instanceof Int16Array || - obj instanceof Int32Array || - obj instanceof BigInt64Array || - obj instanceof BigUint64Array || - obj instanceof Uint8ClampedArray); + && obj instanceof TypedArray; } /** -- cgit v1.2.3 From 5b288e119180046a1e00003357293c8ee04a4782 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 11 Jul 2022 11:10:01 -0700 Subject: Improve tasks localized strings Part of #153743 --- src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 1a3261a3335..93cbe879116 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -2740,7 +2740,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } this._showQuickPick(tasks ? tasks : taskResult!.tasks, placeholder, { - label: nls.localize('TaskService.noEntryToRunSlow', '$(plus) Configure a Task'), + label: '$(plus) ' + nls.localize('TaskService.noEntryToRun', 'Configure a Task'), task: null }, true). @@ -2750,7 +2750,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } else { this._showTwoLevelQuickPick(placeholder, { - label: nls.localize('TaskService.noEntryToRun', '$(plus) Configure a Task'), + label: '$(plus) ' + nls.localize('TaskService.noEntryToRun', 'Configure a Task'), task: null }). then(pickThen); -- cgit v1.2.3 From 75bc124fe92fe08a31afb41cac0eed9135abbfde Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 11 Jul 2022 11:35:10 -0700 Subject: Remove todo --- src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts index 60277418746..a62e8b54d38 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -177,7 +177,6 @@ if (isWindows) { }); } -// TODO: This only works when shell integration is enabled - create shell integration enabled for active terminal context key // Map certain keybindings in pwsh to unused keys which get handled by PSReadLine handlers in the // shell integration script. This allows keystrokes that cannot be sent via VT sequences to work. // See https://github.com/microsoft/terminal/issues/879#issuecomment-497775007 -- cgit v1.2.3 From c6d40837c0620066bfce980c94e14e1176a04a24 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Mon, 11 Jul 2022 14:45:13 -0400 Subject: Fix incorrect common.version (#154825) --- src/vs/platform/telemetry/common/1dsAppender.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/telemetry/common/1dsAppender.ts b/src/vs/platform/telemetry/common/1dsAppender.ts index 7823821070f..5dd4975c9e1 100644 --- a/src/vs/platform/telemetry/common/1dsAppender.ts +++ b/src/vs/platform/telemetry/common/1dsAppender.ts @@ -115,15 +115,14 @@ export abstract class AbstractOneDataSystemAppender implements ITelemetryAppende data = validateTelemetryData(data); const name = this._eventPrefix + '/' + eventName; - if (data?.properties?.version) { - data.properties.pluginVersionString = data.properties.version; - } - try { - this._withAIClient((aiClient) => aiClient.track({ - name, - baseData: { name, properties: data?.properties, measurements: data?.measurements } - })); + this._withAIClient((aiClient) => { + aiClient.pluginVersionString = data?.properties.version ?? 'Unknown'; + aiClient.track({ + name, + baseData: { name, properties: data?.properties, measurements: data?.measurements } + }); + }); } catch { } } -- cgit v1.2.3 From 01afe20df1528a169144cbf33817281939f9c0b7 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Mon, 11 Jul 2022 12:00:50 -0700 Subject: fixes #154840 (#154841) --- src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts b/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts index cc6278c3a34..2b383111c09 100644 --- a/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts @@ -148,7 +148,7 @@ registerAction2(class extends Action2 { id: 'commandCenter.help', title: localize('all', "Show Search Modes..."), icon: Codicon.chevronDown, - menu: { id: MenuId.CommandCenter, order: 100 } + menu: { id: MenuId.CommandCenter, order: 101 } }); } run(accessor: ServicesAccessor): void { -- cgit v1.2.3 From 88f9806a976e9e77efa4e9d711cc0ecc07671ec9 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Mon, 11 Jul 2022 16:04:45 -0400 Subject: Add installation context to install extension command (#154846) * Add installation context to install extension command * Update src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts Co-authored-by: Joyce Er Co-authored-by: Joyce Er --- .../contrib/extensions/browser/extensions.contribution.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index 271fe4a1ec5..f53f6a7de8a 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -78,6 +78,7 @@ import { isWeb } from 'vs/base/common/platform'; import { ExtensionStorageService } from 'vs/platform/extensionManagement/common/extensionStorage'; import { IStorageService } from 'vs/platform/storage/common/storage'; import product from 'vs/platform/product/common/product'; +import { IStringDictionary } from 'vs/base/common/collections'; // Singletons registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService); @@ -316,13 +317,17 @@ CommandsRegistry.registerCommand({ 'type': 'boolean', 'description': localize('workbench.extensions.installExtension.option.donotSync', "When enabled, VS Code do not sync this extension when Settings Sync is on."), default: false + }, + 'context': { + 'type': 'object', + 'description': localize('workbench.extensions.installExtension.option.context', "Context for the installation. This is a JSON object that can be used to pass any information to the installation handlers. i.e. `{skipWalkthrough: true}` will skip opening the walkthrough upon install."), } } } } ] }, - handler: async (accessor, arg: string | UriComponents, options?: { installOnlyNewlyAddedFromExtensionPackVSIX?: boolean; installPreReleaseVersion?: boolean; donotSync?: boolean }) => { + handler: async (accessor, arg: string | UriComponents, options?: { installOnlyNewlyAddedFromExtensionPackVSIX?: boolean; installPreReleaseVersion?: boolean; donotSync?: boolean; context?: IStringDictionary }) => { const extensionsWorkbenchService = accessor.get(IExtensionsWorkbenchService); try { if (typeof arg === 'string') { @@ -332,7 +337,8 @@ CommandsRegistry.registerCommand({ const installOptions: InstallOptions = { isMachineScoped: options?.donotSync ? true : undefined, /* do not allow syncing extensions automatically while installing through the command */ installPreReleaseVersion: options?.installPreReleaseVersion, - installGivenVersion: !!version + installGivenVersion: !!version, + context: options?.context }; if (version) { await extensionsWorkbenchService.installVersion(extension, version, installOptions); -- cgit v1.2.3 From e7e987e3b3444d56fa19695da4dd81f7c1dbfb28 Mon Sep 17 00:00:00 2001 From: Robert Jin <20613660+jzyrobert@users.noreply.github.com> Date: Mon, 11 Jul 2022 21:30:13 +0100 Subject: Add Expand all button in explorer view (#153614) Add expand all button in explorer view to replace collapse all if all workspace root folders are collapsed --- .../contrib/files/browser/views/explorerView.ts | 78 +++++++++++++++++++--- src/vs/workbench/contrib/files/common/files.ts | 2 + 2 files changed, 71 insertions(+), 9 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index 1e2e605ec5e..6185a906efa 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -8,7 +8,7 @@ import { URI } from 'vs/base/common/uri'; import * as perf from 'vs/base/common/performance'; import { IAction, WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification } from 'vs/base/common/actions'; import { memoize } from 'vs/base/common/decorators'; -import { IFilesConfiguration, ExplorerFolderContext, FilesExplorerFocusedContext, ExplorerFocusedContext, ExplorerRootContext, ExplorerResourceReadonlyContext, ExplorerResourceCut, ExplorerResourceMoveableToTrash, ExplorerCompressedFocusContext, ExplorerCompressedFirstFocusContext, ExplorerCompressedLastFocusContext, ExplorerResourceAvailableEditorIdsContext, VIEW_ID, VIEWLET_ID, ExplorerResourceNotReadonlyContext } from 'vs/workbench/contrib/files/common/files'; +import { IFilesConfiguration, ExplorerFolderContext, FilesExplorerFocusedContext, ExplorerFocusedContext, ExplorerRootContext, ExplorerResourceReadonlyContext, ExplorerResourceCut, ExplorerResourceMoveableToTrash, ExplorerCompressedFocusContext, ExplorerCompressedFirstFocusContext, ExplorerCompressedLastFocusContext, ExplorerResourceAvailableEditorIdsContext, VIEW_ID, VIEWLET_ID, ExplorerResourceNotReadonlyContext, ViewHasSomeCollapsibleRootItemContext } from 'vs/workbench/contrib/files/common/files'; import { FileCopiedContext, NEW_FILE_COMMAND_ID, NEW_FOLDER_COMMAND_ID } from 'vs/workbench/contrib/files/browser/fileActions'; import * as DOM from 'vs/base/browser/dom'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; @@ -67,13 +67,19 @@ interface IExplorerViewStyles { listDropBackground?: Color; } -function hasExpandedRootChild(tree: WorkbenchCompressibleAsyncDataTree, treeInput: ExplorerItem[]): boolean { - for (const folder of treeInput) { - if (tree.hasNode(folder) && !tree.isCollapsed(folder)) { - for (const [, child] of folder.children.entries()) { - if (tree.hasNode(child) && tree.isCollapsible(child) && !tree.isCollapsed(child)) { - return true; - } +// Accepts a single or multiple workspace folders +function hasExpandedRootChild(tree: WorkbenchCompressibleAsyncDataTree, treeInput: ExplorerItem | ExplorerItem[]): boolean { + const inputsToCheck = []; + if (Array.isArray(treeInput)) { + inputsToCheck.push(...treeInput.filter(folder => tree.hasNode(folder) && !tree.isCollapsed(folder))); + } else { + inputsToCheck.push(treeInput); + } + + for (const folder of inputsToCheck) { + for (const [, child] of folder.children.entries()) { + if (tree.hasNode(child) && tree.isCollapsible(child) && !tree.isCollapsed(child)) { + return true; } } } @@ -161,6 +167,8 @@ export class ExplorerView extends ViewPane implements IExplorerView { private compressedFocusFirstContext: IContextKey; private compressedFocusLastContext: IContextKey; + private viewHasSomeCollapsibleRootItem: IContextKey; + private horizontalScrolling: boolean | undefined; private dragHandler!: DelayedDragHandler; @@ -207,6 +215,7 @@ export class ExplorerView extends ViewPane implements IExplorerView { this.compressedFocusContext = ExplorerCompressedFocusContext.bindTo(contextKeyService); this.compressedFocusFirstContext = ExplorerCompressedFirstFocusContext.bindTo(contextKeyService); this.compressedFocusLastContext = ExplorerCompressedLastFocusContext.bindTo(contextKeyService); + this.viewHasSomeCollapsibleRootItem = ViewHasSomeCollapsibleRootItemContext.bindTo(contextKeyService); this.explorerService.registerView(this); } @@ -493,6 +502,9 @@ export class ExplorerView extends ViewPane implements IExplorerView { } })); + this._register(this.tree.onDidChangeCollapseState(() => this.updateAnyCollapsedContext())); + this.updateAnyCollapsedContext(); + this._register(this.tree.onMouseDblClick(e => { if (e.element === null) { // click in empty area -> create a new file #116676 @@ -769,6 +781,23 @@ export class ExplorerView extends ViewPane implements IExplorerView { } } + expandAll(): void { + if (this.explorerService.isEditable(undefined)) { + this.tree.domFocus(); + } + + const treeInput = this.tree.getInput(); + if (Array.isArray(treeInput)) { + treeInput.forEach(folder => { + folder.children.forEach(child => this.tree.hasNode(child) && this.tree.expand(child, true)); + }); + + return; + } + + this.tree.expandAll(); + } + collapseAll(): void { if (this.explorerService.isEditable(undefined)) { this.tree.domFocus(); @@ -837,6 +866,14 @@ export class ExplorerView extends ViewPane implements IExplorerView { this.compressedFocusLastContext.set(controller.index === controller.count - 1); } + private updateAnyCollapsedContext(): void { + const treeInput = this.tree.getInput(); + if (treeInput === undefined) { + return; + } + this.viewHasSomeCollapsibleRootItem.set(hasExpandedRootChild(this.tree, treeInput)); + } + styleListDropBackground(styles: IExplorerViewStyles): void { const content: string[] = []; @@ -951,7 +988,7 @@ registerAction2(class extends Action2 { menu: { id: MenuId.ViewTitle, group: 'navigation', - when: ContextKeyExpr.equals('view', VIEW_ID), + when: ContextKeyExpr.and(ContextKeyExpr.equals('view', VIEW_ID), ViewHasSomeCollapsibleRootItemContext), order: 40 } }); @@ -963,3 +1000,26 @@ registerAction2(class extends Action2 { explorerView.collapseAll(); } }); + +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'workbench.files.action.expandExplorerFolders', + title: { value: nls.localize('expandExplorerFolders', "Expand Folders in Explorer"), original: 'Expand Folders in Explorer' }, + f1: true, + icon: Codicon.expandAll, + menu: { + id: MenuId.ViewTitle, + group: 'navigation', + when: ContextKeyExpr.and(ContextKeyExpr.equals('view', VIEW_ID), ViewHasSomeCollapsibleRootItemContext.toNegated()), + order: 40 + } + }); + } + + run(accessor: ServicesAccessor) { + const viewsService = accessor.get(IViewsService); + const explorerView = viewsService.getViewWithId(VIEW_ID) as ExplorerView; + explorerView.expandAll(); + } +}); diff --git a/src/vs/workbench/contrib/files/common/files.ts b/src/vs/workbench/contrib/files/common/files.ts index d903a67b219..b9500df93d9 100644 --- a/src/vs/workbench/contrib/files/common/files.ts +++ b/src/vs/workbench/contrib/files/common/files.ts @@ -56,6 +56,8 @@ export const ExplorerCompressedFocusContext = new RawContextKey('explor export const ExplorerCompressedFirstFocusContext = new RawContextKey('explorerViewletCompressedFirstFocus', true, { type: 'boolean', description: localize('explorerViewletCompressedFirstFocus', "True when the focus is inside a compact item's first part in the EXPLORER view.") }); export const ExplorerCompressedLastFocusContext = new RawContextKey('explorerViewletCompressedLastFocus', true, { type: 'boolean', description: localize('explorerViewletCompressedLastFocus', "True when the focus is inside a compact item's last part in the EXPLORER view.") }); +export const ViewHasSomeCollapsibleRootItemContext = new RawContextKey('viewHasSomeCollapsibleItem', false, { type: 'boolean', description: localize('viewHasSomeCollapsibleItem', "True when a workspace in the EXPLORER view has some collapsible root child.") }); + export const FilesExplorerFocusCondition = ContextKeyExpr.and(ExplorerViewletVisibleContext, FilesExplorerFocusedContext, ContextKeyExpr.not(InputFocusedContextKey)); export const ExplorerFocusCondition = ContextKeyExpr.and(ExplorerViewletVisibleContext, ExplorerFocusedContext, ContextKeyExpr.not(InputFocusedContextKey)); -- cgit v1.2.3 From 2638da77806dea39584c2fb824e68b2618f9f1b1 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 11 Jul 2022 22:36:47 +0200 Subject: do not scan web extensions in desktop (#154851) --- .../services/extensions/browser/extensionService.ts | 18 ++++++++++++++++-- .../extensions/common/abstractExtensionService.ts | 20 ++------------------ .../electron-sandbox/electronExtensionService.ts | 10 ++-------- src/vs/workbench/workbench.common.main.ts | 1 - src/vs/workbench/workbench.web.main.ts | 1 + 5 files changed, 21 insertions(+), 29 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts index 8c48d48d131..5662085250a 100644 --- a/src/vs/workbench/services/extensions/browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/browser/extensionService.ts @@ -31,6 +31,7 @@ import { IUserDataInitializationService } from 'vs/workbench/services/userData/b import { IAutomatedWindow } from 'vs/platform/log/browser/log'; import { ILogService } from 'vs/platform/log/common/log'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { dedupExtensions } from 'vs/workbench/services/extensions/common/extensionsUtil'; export class ExtensionService extends AbstractExtensionService implements IExtensionService { @@ -49,7 +50,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten @IWorkspaceContextService contextService: IWorkspaceContextService, @IConfigurationService configurationService: IConfigurationService, @IExtensionManifestPropertiesService extensionManifestPropertiesService: IExtensionManifestPropertiesService, - @IWebExtensionsScannerService webExtensionsScannerService: IWebExtensionsScannerService, + @IWebExtensionsScannerService private readonly _webExtensionsScannerService: IWebExtensionsScannerService, @ILogService logService: ILogService, @IRemoteAgentService remoteAgentService: IRemoteAgentService, @ILifecycleService lifecycleService: ILifecycleService, @@ -69,7 +70,6 @@ export class ExtensionService extends AbstractExtensionService implements IExten contextService, configurationService, extensionManifestPropertiesService, - webExtensionsScannerService, logService, remoteAgentService, lifecycleService, @@ -192,6 +192,20 @@ export class ExtensionService extends AbstractExtensionService implements IExten } } + private async _scanWebExtensions(): Promise { + const system: IExtensionDescription[] = [], user: IExtensionDescription[] = [], development: IExtensionDescription[] = []; + try { + await Promise.all([ + this._webExtensionsScannerService.scanSystemExtensions().then(extensions => system.push(...extensions.map(e => toExtensionDescription(e)))), + this._webExtensionsScannerService.scanUserExtensions(this._userDataProfileService.currentProfile.extensionsResource, { skipInvalidExtensions: true }).then(extensions => user.push(...extensions.map(e => toExtensionDescription(e)))), + this._webExtensionsScannerService.scanExtensionsUnderDevelopment().then(extensions => development.push(...extensions.map(e => toExtensionDescription(e, true)))) + ]); + } catch (error) { + this._logService.error(error); + } + return dedupExtensions(system, user, development, this._logService); + } + protected async _scanAndHandleExtensions(): Promise { // fetch the remote environment let [localExtensions, remoteEnv, remoteExtensions] = await Promise.all([ diff --git a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts index 057e5467ee9..61a3cfd5de2 100644 --- a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts @@ -11,11 +11,11 @@ import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle' import * as perf from 'vs/base/common/performance'; import { isEqualOrParent } from 'vs/base/common/resources'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; -import { IWebExtensionsScannerService, IWorkbenchExtensionEnablementService, IWorkbenchExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { IWorkbenchExtensionEnablementService, IWorkbenchExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { ActivationTimes, ExtensionPointContribution, IExtensionService, IExtensionsStatus, IMessage, IWillActivateEvent, IResponsiveStateChangeEvent, toExtension, IExtensionHost, ActivationKind, ExtensionHostKind, toExtensionDescription, ExtensionRunningLocation, extensionHostKindToString, ExtensionActivationReason, IInternalExtensionService, RemoteRunningLocation, LocalProcessRunningLocation, LocalWebWorkerRunningLocation } from 'vs/workbench/services/extensions/common/extensions'; +import { ActivationTimes, ExtensionPointContribution, IExtensionService, IExtensionsStatus, IMessage, IWillActivateEvent, IResponsiveStateChangeEvent, toExtension, IExtensionHost, ActivationKind, ExtensionHostKind, ExtensionRunningLocation, extensionHostKindToString, ExtensionActivationReason, IInternalExtensionService, RemoteRunningLocation, LocalProcessRunningLocation, LocalWebWorkerRunningLocation } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionMessageCollector, ExtensionPoint, ExtensionsRegistry, IExtensionPoint, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; import { ResponsiveState } from 'vs/workbench/services/extensions/common/rpcProtocol'; @@ -32,7 +32,6 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { Schemas } from 'vs/base/common/network'; import { URI } from 'vs/base/common/uri'; import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService'; -import { dedupExtensions } from 'vs/workbench/services/extensions/common/extensionsUtil'; import { ApiProposalName, allApiProposals } from 'vs/workbench/services/extensions/common/extensionsApiProposals'; import { ILogService } from 'vs/platform/log/common/log'; import { IExtensionHostExitInfo, IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; @@ -186,7 +185,6 @@ export abstract class AbstractExtensionService extends Disposable implements IEx @IWorkspaceContextService private readonly _contextService: IWorkspaceContextService, @IConfigurationService protected readonly _configurationService: IConfigurationService, @IExtensionManifestPropertiesService protected readonly _extensionManifestPropertiesService: IExtensionManifestPropertiesService, - @IWebExtensionsScannerService protected readonly _webExtensionsScannerService: IWebExtensionsScannerService, @ILogService protected readonly _logService: ILogService, @IRemoteAgentService protected readonly _remoteAgentService: IRemoteAgentService, @ILifecycleService private readonly _lifecycleService: ILifecycleService, @@ -1328,20 +1326,6 @@ export abstract class AbstractExtensionService extends Disposable implements IEx this._onDidChangeExtensionsStatus.fire([extensionId]); } - protected async _scanWebExtensions(): Promise { - const system: IExtensionDescription[] = [], user: IExtensionDescription[] = [], development: IExtensionDescription[] = []; - try { - await Promise.all([ - this._webExtensionsScannerService.scanSystemExtensions().then(extensions => system.push(...extensions.map(e => toExtensionDescription(e)))), - this._webExtensionsScannerService.scanUserExtensions(this._userDataProfileService.currentProfile.extensionsResource, { skipInvalidExtensions: true }).then(extensions => user.push(...extensions.map(e => toExtensionDescription(e)))), - this._webExtensionsScannerService.scanExtensionsUnderDevelopment().then(extensions => development.push(...extensions.map(e => toExtensionDescription(e, true)))) - ]); - } catch (error) { - this._logService.error(error); - } - return dedupExtensions(system, user, development, this._logService); - } - //#endregion protected abstract _createExtensionHost(runningLocation: ExtensionRunningLocation, isInitialStart: boolean): IExtensionHost | null; diff --git a/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts b/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts index 87e9f45b545..649e83699e8 100644 --- a/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts +++ b/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts @@ -9,7 +9,7 @@ import * as nls from 'vs/nls'; import { runWhenIdle } from 'vs/base/common/async'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { IWorkbenchExtensionEnablementService, EnablementState, IWebExtensionsScannerService, IWorkbenchExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { IWorkbenchExtensionEnablementService, EnablementState, IWorkbenchExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IRemoteExtensionHostDataProvider, RemoteExtensionHost, IRemoteExtensionHostInitData } from 'vs/workbench/services/extensions/common/remoteExtensionHost'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; @@ -26,7 +26,6 @@ import { ExtensionKind } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; import { PersistentConnectionEventType } from 'vs/platform/remote/common/remoteAgentConnection'; import { IProductService } from 'vs/platform/product/common/productService'; -import { flatten } from 'vs/base/common/arrays'; import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; import { IRemoteExplorerService } from 'vs/workbench/services/remote/common/remoteExplorerService'; import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; @@ -71,7 +70,6 @@ export abstract class ElectronExtensionService extends AbstractExtensionService @IWorkspaceContextService contextService: IWorkspaceContextService, @IConfigurationService configurationService: IConfigurationService, @IExtensionManifestPropertiesService extensionManifestPropertiesService: IExtensionManifestPropertiesService, - @IWebExtensionsScannerService webExtensionsScannerService: IWebExtensionsScannerService, @ILogService logService: ILogService, @IRemoteAgentService remoteAgentService: IRemoteAgentService, @ILifecycleService lifecycleService: ILifecycleService, @@ -95,7 +93,6 @@ export abstract class ElectronExtensionService extends AbstractExtensionService contextService, configurationService, extensionManifestPropertiesService, - webExtensionsScannerService, logService, remoteAgentService, lifecycleService, @@ -151,10 +148,7 @@ export abstract class ElectronExtensionService extends AbstractExtensionService } private async _scanAllLocalExtensions(): Promise { - return flatten(await Promise.all([ - this._extensionScanner.scannedExtensions, - this._scanWebExtensions(), - ])); + return this._extensionScanner.scannedExtensions; } protected _createLocalExtensionHostDataProvider(isInitialStart: boolean, desiredRunningLocation: ExtensionRunningLocation): ILocalProcessExtensionHostDataProvider & IWebWorkerExtensionHostDataProvider { diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index 14407f52692..21b25d82752 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -76,7 +76,6 @@ import 'vs/workbench/services/commands/common/commandService'; import 'vs/workbench/services/themes/browser/workbenchThemeService'; import 'vs/workbench/services/label/common/labelService'; import 'vs/workbench/services/extensions/common/extensionManifestPropertiesService'; -import 'vs/workbench/services/extensionManagement/browser/webExtensionsScannerService'; import 'vs/workbench/services/extensionManagement/browser/extensionEnablementService'; import 'vs/workbench/services/extensionManagement/browser/builtinExtensionsScannerService'; import 'vs/workbench/services/extensionRecommendations/common/extensionIgnoredRecommendationsService'; diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index f0833043d64..a71d4de98e3 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -40,6 +40,7 @@ import 'vs/workbench/services/search/browser/searchService'; import 'vs/workbench/services/textfile/browser/browserTextFileService'; import 'vs/workbench/services/keybinding/browser/keyboardLayoutService'; import 'vs/workbench/services/extensions/browser/extensionService'; +import 'vs/workbench/services/extensionManagement/browser/webExtensionsScannerService'; import 'vs/workbench/services/extensionManagement/common/extensionManagementServerService'; import 'vs/workbench/services/extensionManagement/browser/extensionUrlTrustService'; import 'vs/workbench/services/telemetry/browser/telemetryService'; -- cgit v1.2.3 From 1a7cae95fdfa8a44a6180bb93bde73d3f1e59ca8 Mon Sep 17 00:00:00 2001 From: David Dossett Date: Mon, 11 Jul 2022 14:43:40 -0700 Subject: Update codicons (#154859) --- src/vs/base/browser/ui/codicons/codicon/codicon.ttf | Bin 71980 -> 72116 bytes src/vs/base/common/codicons.ts | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/base/browser/ui/codicons/codicon/codicon.ttf b/src/vs/base/browser/ui/codicons/codicon/codicon.ttf index 13999090718..9d4627dfb64 100644 Binary files a/src/vs/base/browser/ui/codicons/codicon/codicon.ttf and b/src/vs/base/browser/ui/codicons/codicon/codicon.ttf differ diff --git a/src/vs/base/common/codicons.ts b/src/vs/base/common/codicons.ts index 9e696833141..e08e651d91e 100644 --- a/src/vs/base/common/codicons.ts +++ b/src/vs/base/common/codicons.ts @@ -558,7 +558,8 @@ export class Codicon implements CSSIcon { public static readonly mapFilled = new Codicon('map-filled', { fontCharacter: '\\ec06' }); public static readonly circleSmall = new Codicon('circle-small', { fontCharacter: '\\ec07' }); public static readonly bellSlash = new Codicon('bell-slash', { fontCharacter: '\\ec08' }); - public static readonly bellSlashDot = new Codicon('bell-slash-dot', { fontCharacter: '\\f101' }); + public static readonly bellSlashDot = new Codicon('bell-slash-dot', { fontCharacter: '\\ec09' }); + public static readonly commentUnresolved = new Codicon('comment-unresolved', { fontCharacter: '\\ec0a' }); // derived icons, that could become separate icons -- cgit v1.2.3 From 112b2d050c8398e74360fcb2219af76ad51e8aa5 Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Mon, 11 Jul 2022 20:55:20 -0400 Subject: Fix menu shortcuts not working after a webview is shown (#154648) Release notes, markdown preview, etc. use a web view. The web view uses `WindowIgnoreMenuShortcutsManager`/`allowMenuShortcuts` to disable menu shortcuts. However, `WindowIgnoreMenuShortcutsManager.didBlur` isn't being called when the editor is closed, so the menu shortcuts stay disabled. This seems to be a side effect of the fix for #82670. This does not solve using Cmd+M or Cmd+H while focused on a web view. I looked into detecting those keys and enabling menu shortcuts, but it seems like MacOS still won't detect them if you enable menu shortcuts after the key stroke is pressed but before the event is finished processing. --- .../workbench/contrib/webview/electron-sandbox/webviewElement.ts | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts index 692eeb591ba..c119358978c 100644 --- a/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts @@ -90,6 +90,13 @@ export class ElectronWebviewElement extends WebviewElement { } } + override dispose(): void { + // Make sure keyboard handler knows it closed (#71800) + this._webviewKeyboardHandler.didBlur(); + + super.dispose(); + } + protected override webviewContentEndpoint(iframeId: string): string { return `${Schemas.vscodeWebview}://${iframeId}`; } -- cgit v1.2.3 From 5a2c591b822fa4e5d4a15bb73786b4564e9825ec Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Jul 2022 07:12:25 +0200 Subject: update nls comment (#153743) (#154890) --- src/vs/workbench/contrib/files/browser/files.contribution.ts | 2 +- src/vs/workbench/contrib/search/browser/search.contribution.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/files/browser/files.contribution.ts b/src/vs/workbench/contrib/files/browser/files.contribution.ts index 0db2db173e1..1ebf70ce257 100644 --- a/src/vs/workbench/contrib/files/browser/files.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/files.contribution.ts @@ -159,7 +159,7 @@ configurationRegistry.registerConfiguration({ 'type': 'string', // expression ({ "**/*.js": { "when": "$(basename).js" } }) 'pattern': '\\w*\\$\\(basename\\)\\w*', 'default': '$(basename).ext', - 'markdownDescription': nls.localize('files.exclude.when', "Additional check on the siblings of a matching file. Use \\$(basename) as variable for the matching file name.") + 'markdownDescription': nls.localize({ key: 'files.exclude.when', comment: ['\\$(basename) should not be translated'] }, "Additional check on the siblings of a matching file. Use \\$(basename) as variable for the matching file name.") } } } diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index 54450eb71c4..099169c6ab3 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -844,7 +844,7 @@ configurationRegistry.registerConfiguration({ type: 'string', // expression ({ "**/*.js": { "when": "$(basename).js" } }) pattern: '\\w*\\$\\(basename\\)\\w*', default: '$(basename).ext', - markdownDescription: nls.localize('exclude.when', 'Additional check on the siblings of a matching file. Use \\$(basename) as variable for the matching file name.') + markdownDescription: nls.localize({ key: 'exclude.when', comment: ['\\$(basename) should not be translated'] }, 'Additional check on the siblings of a matching file. Use \\$(basename) as variable for the matching file name.') } } } -- cgit v1.2.3 From c71e78d3d6f53bde241dc9f3d5f4a1972bc5a75b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 12 Jul 2022 09:35:41 +0200 Subject: fix CSP for webWorkerExtHostIframe and also fix URL construction (#154899) --- .../services/extensions/worker/webWorkerExtensionHostIframe.html | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html b/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html index 92a1928112f..3e5b72d2b3b 100644 --- a/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html +++ b/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html @@ -4,7 +4,7 @@ @@ -66,11 +66,12 @@ function start() { try { - const workerUrl = new URL('../../../../base/worker/workerMain.js'); + let workerUrl = '../../../../base/worker/workerMain.js'; if(crossOriginIsolated) { - workerUrl.searchParams.set('vscode-coi', 2 /*COEP*/) + workerUrl += '?vscode-coi=2'; // COEP } - const worker = new Worker(workerUrl.toString(), { name }); + + const worker = new Worker(workerUrl, { name }); worker.postMessage('vs/workbench/api/worker/extensionHostWorker'); const nestedWorkers = new Map(); -- cgit v1.2.3 From f3528d481b366b24321c382d5e5849f4c7d65248 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 12 Jul 2022 10:47:40 +0200 Subject: safer check for `crossOriginIsolated` (#154907) --- .../services/extensions/worker/webWorkerExtensionHostIframe.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html b/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html index 3e5b72d2b3b..576bad14363 100644 --- a/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html +++ b/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html @@ -4,7 +4,7 @@ @@ -67,7 +67,7 @@ function start() { try { let workerUrl = '../../../../base/worker/workerMain.js'; - if(crossOriginIsolated) { + if(globalThis.crossOriginIsolated) { workerUrl += '?vscode-coi=2'; // COEP } -- cgit v1.2.3 From c9bf4393d5f953170503473e20a13a1ad65c40a5 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 12 Jul 2022 02:33:13 -0700 Subject: Rename drop API interface (#154876) Makes the names more consistent --- src/vs/workbench/api/common/extHost.api.impl.ts | 2 +- src/vs/workbench/api/common/extHostLanguageFeatures.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 6f411f31a82..efc0940e7ad 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -576,7 +576,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I createLanguageStatusItem(id: string, selector: vscode.DocumentSelector): vscode.LanguageStatusItem { return extHostLanguages.createLanguageStatusItem(extension, id, selector); }, - registerDocumentOnDropEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentOnDropEditProvider): vscode.Disposable { + registerDocumentDropEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentDropEditProvider): vscode.Disposable { checkProposedApiEnabled(extension, 'textEditorDrop'); return extHostLanguageFeatures.registerDocumentOnDropEditProvider(extension, selector, provider); } diff --git a/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/src/vs/workbench/api/common/extHostLanguageFeatures.ts index 4c70e92c5e6..809b7609426 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatures.ts @@ -1791,7 +1791,7 @@ class DocumentOnDropEditAdapter { constructor( private readonly _proxy: extHostProtocol.MainThreadLanguageFeaturesShape, private readonly _documents: ExtHostDocuments, - private readonly _provider: vscode.DocumentOnDropEditProvider, + private readonly _provider: vscode.DocumentDropEditProvider, private readonly _handle: number, ) { } @@ -1802,7 +1802,7 @@ class DocumentOnDropEditAdapter { return (await this._proxy.$resolveDocumentOnDropFileData(this._handle, requestId, index)).buffer; }); - const edit = await this._provider.provideDocumentOnDropEdits(doc, pos, dataTransfer, token); + const edit = await this._provider.provideDocumentDropEdits(doc, pos, dataTransfer, token); if (!edit) { return undefined; } @@ -2446,7 +2446,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF // --- Document on drop - registerDocumentOnDropEditProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentOnDropEditProvider) { + registerDocumentOnDropEditProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentDropEditProvider) { const handle = this._nextHandle(); this._adapter.set(handle, new AdapterData(new DocumentOnDropEditAdapter(this._proxy, this._documents, provider, handle), extension)); this._proxy.$registerDocumentOnDropEditProvider(handle, this._transformDocumentSelector(selector)); -- cgit v1.2.3 From 51507ba87a14205209cfd202bfcb2abe2d249fa6 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 12 Jul 2022 11:35:25 +0200 Subject: make sure to pass the right height to editors, (#154900) fixes https://github.com/microsoft/vscode/issues/154765 --- .../contrib/mergeEditor/browser/view/editors/codeEditorView.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts index f6a409656f8..321d1594dd5 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts @@ -24,7 +24,7 @@ export abstract class CodeEditorView extends Disposable { readonly model = this._viewModel.map(m => /** @description model */ m?.model); protected readonly htmlElements = h('div.code-view', [ - h('div.title', [ + h('div.title', { $: 'header' }, [ h('span.title', { $: 'title' }), h('span.description', { $: 'description' }), h('span.detail', { $: 'detail' }), @@ -48,7 +48,7 @@ export abstract class CodeEditorView extends Disposable { setStyle(this.htmlElements.root, { width, height, top, left }); this.editor.layout({ width: width - this.htmlElements.gutterDiv.clientWidth, - height: height - this.htmlElements.title.clientHeight, + height: height - this.htmlElements.header.clientHeight, }); } // preferredWidth?: number | undefined; -- cgit v1.2.3 From 04b95fcebbda869fc2097fb967e647b0138a10d9 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Tue, 12 Jul 2022 11:36:41 +0200 Subject: Commit Action button polish (#154908) More Commit Action button tweaks --- src/vs/base/browser/ui/button/button.css | 1 + src/vs/workbench/contrib/scm/browser/scmViewPane.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/base/browser/ui/button/button.css b/src/vs/base/browser/ui/button/button.css index 6c9a07a30c2..cade1d85c64 100644 --- a/src/vs/base/browser/ui/button/button.css +++ b/src/vs/base/browser/ui/button/button.css @@ -52,6 +52,7 @@ .monaco-button-dropdown .monaco-button-dropdown-separator { padding: 4px 0; + cursor: default; } .monaco-button-dropdown .monaco-button-dropdown-separator > div { diff --git a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts index 41cce292993..9af7e3e8a77 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts @@ -2668,6 +2668,7 @@ export class SCMActionButton implements IDisposable { actions: actions, addPrimaryActionToDropdown: false, contextMenuProvider: this.contextMenuService, + title: button.command.tooltip, supportIcons: true }); } else if (button.description) { @@ -2681,7 +2682,6 @@ export class SCMActionButton implements IDisposable { this.button.enabled = button.enabled; this.button.label = button.command.title; - this.button.element.title = button.command.tooltip ?? ''; this.button.onDidClick(async () => await executeButtonAction(button.command.id, ...(button.command.arguments || [])), null, this.disposables.value); this.disposables.value!.add(this.button); -- cgit v1.2.3 From d4bb7e3ebdaf6d52df5e7bc06c9cc3e82f55793a Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Tue, 12 Jul 2022 03:00:52 -0700 Subject: deprecate observableValue in favor of IObservable (#154279) --- src/vs/base/common/observableValue.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/vs') diff --git a/src/vs/base/common/observableValue.ts b/src/vs/base/common/observableValue.ts index 7bdcbae66cb..e1f207c0841 100644 --- a/src/vs/base/common/observableValue.ts +++ b/src/vs/base/common/observableValue.ts @@ -5,17 +5,28 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; +//@ts-ignore +import type { IObservable } from 'vs/base/common/observable'; +/** + * @deprecated Use {@link IObservable} instead. + */ export interface IObservableValue { onDidChange: Event; readonly value: T; } +/** + * @deprecated Use {@link IObservable} instead. + */ export const staticObservableValue = (value: T): IObservableValue => ({ onDidChange: Event.None, value, }); +/** + * @deprecated Use {@link IObservable} instead. + */ export class MutableObservableValue extends Disposable implements IObservableValue { private readonly changeEmitter = this._register(new Emitter()); -- cgit v1.2.3 From 261e65f44e2be5a8ba5719e66e6499e6ab26d886 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 12 Jul 2022 13:55:10 +0200 Subject: joh/issue154804 (#154909) * add action to reset menu hidden states, add actions.contribution file for service and command registration * some :lipstick: --- .../actions/common/actions.contribution.ts | 14 +++++++++++ src/vs/platform/actions/common/actions.ts | 19 +++++++++++--- src/vs/platform/actions/common/menuResetAction.ts | 29 ++++++++++++++++++++++ src/vs/platform/actions/common/menuService.ts | 18 ++++++++------ .../test/browser/workbenchTestServices.ts | 4 +++ src/vs/workbench/workbench.common.main.ts | 4 +-- 6 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 src/vs/platform/actions/common/actions.contribution.ts create mode 100644 src/vs/platform/actions/common/menuResetAction.ts (limited to 'src/vs') diff --git a/src/vs/platform/actions/common/actions.contribution.ts b/src/vs/platform/actions/common/actions.contribution.ts new file mode 100644 index 00000000000..6dfb3c99aaf --- /dev/null +++ b/src/vs/platform/actions/common/actions.contribution.ts @@ -0,0 +1,14 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IMenuService, registerAction2 } from 'vs/platform/actions/common/actions'; +import { MenuHiddenStatesReset } from 'vs/platform/actions/common/menuResetAction'; +import { MenuService } from 'vs/platform/actions/common/menuService'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; + + +registerSingleton(IMenuService, MenuService, true); + +registerAction2(MenuHiddenStatesReset); diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index 17d74df8b6f..0b4a4ea32db 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -196,7 +196,18 @@ export interface IMenuService { readonly _serviceBrand: undefined; + /** + * Create a new menu for the given menu identifier. A menu sends events when it's entries + * have changed (placement, enablement, checked-state). By default it does not send events for + * submenu entries. That is more expensive and must be explicitly enabled with the + * `emitEventsForSubmenuChanges` flag. + */ createMenu(id: MenuId, contextKeyService: IContextKeyService, options?: IMenuCreateOptions): IMenu; + + /** + * Reset **all** menu item hidden states. + */ + resetHiddenStates(): void; } export type ICommandsMap = Map; @@ -355,13 +366,13 @@ export class SubmenuItemAction extends SubmenuAction { export class MenuItemActionManageActions { constructor( - private readonly _hideThis: IAction, - private readonly _toggleAny: IAction[][], + readonly hideThis: IAction, + readonly toggleAny: readonly IAction[][], ) { } asList(): IAction[] { - let result: IAction[] = [this._hideThis]; - for (const n of this._toggleAny) { + let result: IAction[] = [this.hideThis]; + for (const n of this.toggleAny) { result.push(new Separator()); result = result.concat(n); } diff --git a/src/vs/platform/actions/common/menuResetAction.ts b/src/vs/platform/actions/common/menuResetAction.ts new file mode 100644 index 00000000000..84ee76e2b91 --- /dev/null +++ b/src/vs/platform/actions/common/menuResetAction.ts @@ -0,0 +1,29 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize } from 'vs/nls'; +import { Action2, IMenuService } from 'vs/platform/actions/common/actions'; +import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { ILogService } from 'vs/platform/log/common/log'; + +export class MenuHiddenStatesReset extends Action2 { + + constructor() { + super({ + id: 'menu.resetHiddenStates', + title: { + value: localize('title', 'Reset Hidden Menus'), + original: 'Reset Hidden Menus' + }, + category: localize('cat', 'View'), + f1: true + }); + } + + run(accessor: ServicesAccessor): void { + accessor.get(IMenuService).resetHiddenStates(); + accessor.get(ILogService).info('did RESET all menu hidden states'); + } +} diff --git a/src/vs/platform/actions/common/menuService.ts b/src/vs/platform/actions/common/menuService.ts index 0e596777725..5d2092cc1c5 100644 --- a/src/vs/platform/actions/common/menuService.ts +++ b/src/vs/platform/actions/common/menuService.ts @@ -28,15 +28,13 @@ export class MenuService implements IMenuService { this._hiddenStates = new PersistedMenuHideState(storageService); } - /** - * Create a new menu for the given menu identifier. A menu sends events when it's entries - * have changed (placement, enablement, checked-state). By default it does not send events for - * submenu entries. That is more expensive and must be explicitly enabled with the - * `emitEventsForSubmenuChanges` flag. - */ createMenu(id: MenuId, contextKeyService: IContextKeyService, options?: IMenuCreateOptions): IMenu { return new Menu(id, this._hiddenStates, { emitEventsForSubmenuChanges: false, eventDebounceDelay: 50, ...options }, this._commandService, contextKeyService, this); } + + resetHiddenStates(): void { + this._hiddenStates.reset(); + } } class PersistedMenuHideState { @@ -110,6 +108,11 @@ class PersistedMenuHideState { this._persist(); } + reset(): void { + this._data = Object.create(null); + this._persist(); + } + private _persist(): void { try { this._ignoreChangeEvent = true; @@ -264,9 +267,8 @@ class Menu implements IMenu { action.dispose(); action = undefined; } - // add toggle submenu + // add toggle submenu - this re-creates ToggleMenuItemAction-instances for submenus but that's OK... if (action) { - // todo@jrieken this isn't good and O(n2) because this recurses for each submenu... const makeToggleCommand = (id: MenuId, action: IAction): IAction => { if (action instanceof SubmenuItemAction) { return new SubmenuAction(action.id, action.label, action.actions.map(a => makeToggleCommand(action.item.submenu, a))); diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index 9b0dc8d9c43..b910e0408c4 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -519,6 +519,10 @@ export class TestMenuService implements IMenuService { getActions: () => [] }; } + + resetHiddenStates(): void { + // nothing + } } export class TestHistoryService implements IHistoryService { diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index 21b25d82752..f3deec51ef4 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -52,6 +52,7 @@ import 'vs/workbench/browser/parts/views/viewsService'; //#region --- workbench services +import 'vs/platform/actions/common/actions.contribution'; import 'vs/platform/undoRedo/common/undoRedoService'; import 'vs/workbench/services/extensions/browser/extensionUrlHandler'; import 'vs/workbench/services/keybinding/common/keybindingEditing'; @@ -116,8 +117,6 @@ import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyServ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration'; import { TextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfigurationService'; -import { IMenuService } from 'vs/platform/actions/common/actions'; -import { MenuService } from 'vs/platform/actions/common/menuService'; import { IDownloadService } from 'vs/platform/download/common/download'; import { DownloadService } from 'vs/platform/download/common/downloadService'; import { OpenerService } from 'vs/editor/browser/services/openerService'; @@ -140,7 +139,6 @@ registerSingleton(IMarkerDecorationsService, MarkerDecorationsService); registerSingleton(IMarkerService, MarkerService, true); registerSingleton(IContextKeyService, ContextKeyService); registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationService); -registerSingleton(IMenuService, MenuService, true); registerSingleton(IDownloadService, DownloadService, true); registerSingleton(IOpenerService, OpenerService, true); registerSingleton(IExtensionsProfileScannerService, ExtensionsProfileScannerService); -- cgit v1.2.3 From 725f83e64094c6952a1109479d5bef533bf50f50 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 12 Jul 2022 14:38:42 +0200 Subject: show set display language action for lang pack extensions --- .../platform/languagePacks/common/languagePacks.ts | 7 ++- .../contrib/extensions/browser/extensionEditor.ts | 3 +- .../extensions/browser/extensionsActions.ts | 61 +++++++++++++++++++--- .../contrib/extensions/browser/extensionsList.ts | 22 +++++--- .../browser/extensionsWorkbenchService.ts | 34 +++++++++++- .../contrib/extensions/common/extensions.ts | 2 + 6 files changed, 114 insertions(+), 15 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/languagePacks/common/languagePacks.ts b/src/vs/platform/languagePacks/common/languagePacks.ts index 146cbce7401..098cbe3a471 100644 --- a/src/vs/platform/languagePacks/common/languagePacks.ts +++ b/src/vs/platform/languagePacks/common/languagePacks.ts @@ -22,6 +22,7 @@ export interface ILanguagePackService { readonly _serviceBrand: undefined; getAvailableLanguages(): Promise>; getInstalledLanguages(): Promise>; + getLocale(extension: IGalleryExtension): string | undefined; } export abstract class LanguagePackBaseService extends Disposable implements ILanguagePackService { @@ -51,7 +52,7 @@ export abstract class LanguagePackBaseService extends Disposable implements ILan const languagePackExtensions = result.firstPage.filter(e => e.properties.localizedLanguages?.length && e.tags.some(t => t.startsWith('lp-'))); const allFromMarketplace: ILanguagePackItem[] = languagePackExtensions.map(lp => { const languageName = lp.properties.localizedLanguages?.[0]; - const locale = lp.tags.find(t => t.startsWith('lp-'))!.split('lp-')[1]; + const locale = this.getLocale(lp)!; const baseQuickPick = this.createQuickPickItem({ locale, label: languageName }); return { ...baseQuickPick, @@ -68,6 +69,10 @@ export abstract class LanguagePackBaseService extends Disposable implements ILan return allFromMarketplace; } + getLocale(extension: IGalleryExtension): string | undefined { + return extension.tags.find(t => t.startsWith('lp-'))?.split('lp-')[1]; + } + protected createQuickPickItem(languageItem: { locale: string; label?: string | undefined }): IQuickPickItem { const label = languageItem.label ?? languageItem.locale; let description: string | undefined = languageItem.locale !== languageItem.label ? languageItem.locale : undefined; diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index 381096c914f..c8632a19ecb 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -29,7 +29,7 @@ import { UpdateAction, ReloadAction, EnableDropDownAction, DisableDropDownAction, ExtensionStatusLabelAction, SetFileIconThemeAction, SetColorThemeAction, RemoteInstallAction, ExtensionStatusAction, LocalInstallAction, ToggleSyncExtensionAction, SetProductIconThemeAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, UninstallAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction, - InstallAnotherVersionAction, ExtensionEditorManageExtensionAction, WebInstallAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction, MigrateDeprecatedExtensionAction + InstallAnotherVersionAction, ExtensionEditorManageExtensionAction, WebInstallAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction, MigrateDeprecatedExtensionAction, SetLanguageAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; @@ -329,6 +329,7 @@ export class ExtensionEditor extends EditorPane { this.instantiationService.createInstance(EnableDropDownAction), this.instantiationService.createInstance(DisableDropDownAction), + this.instantiationService.createInstance(SetLanguageAction), this.instantiationService.createInstance(RemoteInstallAction, false), this.instantiationService.createInstance(LocalInstallAction), this.instantiationService.createInstance(WebInstallAction), diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index c6d34dc012f..ff05091ffb0 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -56,7 +56,7 @@ import { IContextMenuProvider } from 'vs/base/browser/contextmenu'; import { ILogService } from 'vs/platform/log/common/log'; import * as Constants from 'vs/workbench/contrib/logs/common/logConstants'; import { errorIcon, infoIcon, manageExtensionIcon, preReleaseIcon, syncEnabledIcon, syncIgnoredIcon, trustIcon, warningIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons'; -import { isIOS, isWeb } from 'vs/base/common/platform'; +import { isIOS, isWeb, language } from 'vs/base/common/platform'; import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService'; import { IWorkspaceTrustEnablementService, IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust'; import { isVirtualWorkspace } from 'vs/platform/workspace/common/virtualWorkspace'; @@ -66,6 +66,7 @@ import { ViewContainerLocation } from 'vs/workbench/common/views'; import { flatten } from 'vs/base/common/arrays'; import { fromNow } from 'vs/base/common/date'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; +import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks'; export class PromptExtensionInstallFailureAction extends Action { @@ -264,11 +265,18 @@ export abstract class AbstractInstallAction extends ExtensionAction { protected async computeAndUpdateEnablement(): Promise { this.enabled = false; - if (this.extension && !this.extension.isBuiltin) { - if (this.extension.state === ExtensionState.Uninstalled && await this.extensionsWorkbenchService.canInstall(this.extension)) { - this.enabled = this.installPreReleaseVersion ? this.extension.hasPreReleaseVersion : this.extension.hasReleaseVersion; - this.updateLabel(); - } + if (!this.extension) { + return; + } + if (this.extension.isBuiltin) { + return; + } + if (this.extensionsWorkbenchService.canSetLanguage(this.extension)) { + return; + } + if (this.extension.state === ExtensionState.Uninstalled && await this.extensionsWorkbenchService.canInstall(this.extension)) { + this.enabled = this.installPreReleaseVersion ? this.extension.hasPreReleaseVersion : this.extension.hasReleaseVersion; + this.updateLabel(); } } @@ -1767,6 +1775,43 @@ export class SetProductIconThemeAction extends ExtensionAction { } } +export class SetLanguageAction extends ExtensionAction { + + static readonly ID = 'workbench.extensions.action.setLanguageTheme'; + static readonly TITLE = { value: localize('workbench.extensions.action.setLanguageTheme', "Set Display Language"), original: 'Set Display Language' }; + + private static readonly EnabledClass = `${ExtensionAction.LABEL_ACTION_CLASS} theme`; + private static readonly DisabledClass = `${SetLanguageAction.EnabledClass} disabled`; + + constructor( + @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, + @ILanguagePackService private readonly languagePackService: ILanguagePackService, + ) { + super(SetLanguageAction.ID, SetLanguageAction.TITLE.value, SetLanguageAction.DisabledClass, false); + this.update(); + } + + update(): void { + this.enabled = false; + this.class = SetLanguageAction.DisabledClass; + if (!this.extension) { + return; + } + if (!this.extensionsWorkbenchService.canSetLanguage(this.extension)) { + return; + } + if (this.extension.gallery && language === this.languagePackService.getLocale(this.extension.gallery)) { + return; + } + this.enabled = true; + this.class = SetLanguageAction.EnabledClass; + } + + override async run(): Promise { + return this.extension && this.extensionsWorkbenchService.setLanguage(this.extension); + } +} + export class ShowRecommendedExtensionAction extends Action { static readonly ID = 'workbench.extensions.action.showRecommendedExtension'; @@ -2259,6 +2304,10 @@ export class ExtensionStatusAction extends ExtensionAction { return; } + if (this.extensionsWorkbenchService.canSetLanguage(this.extension)) { + return; + } + if (this.extension.gallery && this.extension.state === ExtensionState.Uninstalled && !await this.extensionsWorkbenchService.canInstall(this.extension)) { if (this.extensionManagementServerService.localExtensionManagementServer || this.extensionManagementServerService.remoteExtensionManagementServer) { const targetPlatform = await (this.extensionManagementServerService.localExtensionManagementServer ? this.extensionManagementServerService.localExtensionManagementServer!.extensionManagementService.getTargetPlatform() : this.extensionManagementServerService.remoteExtensionManagementServer!.extensionManagementService.getTargetPlatform()); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsList.ts b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts index 1754e2233ab..84eaa15be18 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsList.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts @@ -13,7 +13,7 @@ import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging'; import { Event } from 'vs/base/common/event'; import { IExtension, ExtensionContainers, ExtensionState, IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions'; -import { UpdateAction, ManageExtensionAction, ReloadAction, ExtensionStatusLabelAction, RemoteInstallAction, ExtensionStatusAction, LocalInstallAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction, WebInstallAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction, MigrateDeprecatedExtensionAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; +import { UpdateAction, ManageExtensionAction, ReloadAction, ExtensionStatusLabelAction, RemoteInstallAction, ExtensionStatusAction, LocalInstallAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction, WebInstallAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction, MigrateDeprecatedExtensionAction, SetLanguageAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { RatingsWidget, InstallCountWidget, RecommendationWidget, RemoteBadgeWidget, ExtensionPackCountWidget as ExtensionPackBadgeWidget, SyncIgnoredWidget, ExtensionHoverWidget, ExtensionActivationStatusWidget, PreReleaseBookmarkWidget, extensionVerifiedPublisherIconColor } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets'; import { IExtensionService, toExtension } from 'vs/workbench/services/extensions/common/extensions'; @@ -123,6 +123,7 @@ export class Renderer implements IPagedRenderer { reloadAction, this.instantiationService.createInstance(InstallDropdownAction), this.instantiationService.createInstance(InstallingLabelAction), + this.instantiationService.createInstance(SetLanguageAction), this.instantiationService.createInstance(RemoteInstallAction, false), this.instantiationService.createInstance(LocalInstallAction), this.instantiationService.createInstance(WebInstallAction), @@ -186,16 +187,25 @@ export class Renderer implements IPagedRenderer { data.extensionDisposables = dispose(data.extensionDisposables); - const updateEnablement = async () => { - let disabled = false; - const deprecated = !!extension.deprecationInfo; + const computeEnablement = async () => { if (extension.state === ExtensionState.Uninstalled) { - disabled = deprecated || !(await this.extensionsWorkbenchService.canInstall(extension)); + if (!!extension.deprecationInfo) { + return true; + } + if (this.extensionsWorkbenchService.canSetLanguage(extension)) { + return false; + } + return !(await this.extensionsWorkbenchService.canInstall(extension)); } else if (extension.local && !isLanguagePackExtension(extension.local.manifest)) { const runningExtensions = await this.extensionService.getExtensions(); const runningExtension = runningExtensions.filter(e => areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, extension.identifier))[0]; - disabled = !(runningExtension && extension.server === this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension))); + return !(runningExtension && extension.server === this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension))); } + return false; + }; + const updateEnablement = async () => { + const disabled = await computeEnablement(); + const deprecated = !!extension.deprecationInfo; data.element.classList.toggle('deprecated', deprecated); data.root.classList.toggle('disabled', disabled); }; diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index a533f0ad244..6cf90434c7b 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -45,8 +45,10 @@ import { isBoolean, isUndefined } from 'vs/base/common/types'; import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService'; import { IExtensionService, IExtensionsStatus } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionEditor } from 'vs/workbench/contrib/extensions/browser/extensionEditor'; -import { isWeb } from 'vs/base/common/platform'; +import { isWeb, language } from 'vs/base/common/platform'; import { GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; +import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks'; +import { ILocaleService } from 'vs/workbench/contrib/localization/common/locale'; interface IExtensionStateProvider { (extension: Extension): T; @@ -710,6 +712,8 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension @IExtensionManifestPropertiesService private readonly extensionManifestPropertiesService: IExtensionManifestPropertiesService, @ILogService private readonly logService: ILogService, @IExtensionService private readonly extensionService: IExtensionService, + @ILanguagePackService private readonly languagePackService: ILanguagePackService, + @ILocaleService private readonly localeService: ILocaleService, ) { super(); const preferPreReleasesValue = configurationService.getValue('_extensions.preferPreReleases'); @@ -1248,6 +1252,34 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension return this.installWithProgress(() => this.installFromGallery(extension, gallery, installOptions), gallery.displayName, progressLocation); } + canSetLanguage(extension: IExtension): boolean { + if (!isWeb) { + return false; + } + + if (!extension.gallery) { + return false; + } + + const locale = this.languagePackService.getLocale(extension.gallery); + if (!locale) { + return false; + } + + return true; + } + + async setLanguage(extension: IExtension): Promise { + if (!this.canSetLanguage(extension)) { + throw new Error('Can not set language'); + } + const locale = this.languagePackService.getLocale(extension.gallery!); + if (locale === language) { + return; + } + return this.localeService.setLocale({ id: locale, galleryExtension: extension.gallery, extensionId: extension.identifier.id, label: extension.displayName }); + } + setEnablement(extensions: IExtension | IExtension[], enablementState: EnablementState): Promise { extensions = Array.isArray(extensions) ? extensions : [extensions]; return this.promptAndSetEnablement(extensions, enablementState); diff --git a/src/vs/workbench/contrib/extensions/common/extensions.ts b/src/vs/workbench/contrib/extensions/common/extensions.ts index 60c5b415c54..ca1a3a5ff3f 100644 --- a/src/vs/workbench/contrib/extensions/common/extensions.ts +++ b/src/vs/workbench/contrib/extensions/common/extensions.ts @@ -107,6 +107,8 @@ export interface IExtensionsWorkbenchService { uninstall(extension: IExtension): Promise; installVersion(extension: IExtension, version: string, installOptions?: InstallOptions): Promise; reinstall(extension: IExtension): Promise; + canSetLanguage(extension: IExtension): boolean; + setLanguage(extension: IExtension): Promise; setEnablement(extensions: IExtension | IExtension[], enablementState: EnablementState): Promise; open(extension: IExtension, options?: IExtensionEditorOptions): Promise; checkForUpdates(): Promise; -- cgit v1.2.3 From 405b8fdbc3f376ef6603723feacfc3faeb544da1 Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 12 Jul 2022 15:18:19 +0200 Subject: add `vscode-coi` query when loading webview contents related to https://github.com/microsoft/vscode/issues/137884 --- src/vs/workbench/contrib/webview/browser/webviewElement.ts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index 77aaf6683f9..092d2f13707 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -508,6 +508,10 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD params.purpose = options.purpose; } + if (globalThis.crossOriginIsolated) { + params['vscode-coi'] = '3'; /*COOP+COEP*/ + } + const queryString = new URLSearchParams(params).toString(); // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=1754872 -- cgit v1.2.3 From 9ccb9add3f20a4111971483d9e49e8ec244986b6 Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 12 Jul 2022 15:28:00 +0200 Subject: make sure to allow COI on webview iframe --- src/vs/workbench/contrib/webview/browser/webviewElement.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index 092d2f13707..a6386ed1d6e 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -475,7 +475,9 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD element.className = `webview ${options.customClasses || ''}`; element.sandbox.add('allow-scripts', 'allow-same-origin', 'allow-forms', 'allow-pointer-lock', 'allow-downloads'); if (!isFirefox) { - element.setAttribute('allow', 'clipboard-read; clipboard-write;'); + element.setAttribute('allow', 'clipboard-read; clipboard-write; cross-origin-isolated;'); + } else { + element.setAttribute('allow', 'cross-origin-isolated;'); } element.style.border = 'none'; element.style.width = '100%'; -- cgit v1.2.3 From cb67591f254d0700991a49d4fb13aa4edea6e640 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 12 Jul 2022 15:51:31 +0200 Subject: `Marked as resolved` marking has poor visibility with high contrast color themes (#154921) Fixes #149464 --- .../contrib/comments/browser/commentsTreeViewer.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts b/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts index 3166fd47195..020ef7eb4d1 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts @@ -188,9 +188,21 @@ export class CommentNodeRenderer implements IListRenderer return renderedComment; } + private getIcon(commentCount: number, threadState?: CommentThreadState): Codicon { + if (threadState === CommentThreadState.Unresolved) { + return Codicon.commentUnresolved; + } else if (commentCount === 1) { + return Codicon.comment; + } else { + return Codicon.commentDiscussion; + } + } + renderElement(node: ITreeNode, index: number, templateData: ICommentThreadTemplateData, height: number | undefined): void { const commentCount = node.element.replies.length + 1; - templateData.threadMetadata.icon?.classList.add(...ThemeIcon.asClassNameArray((commentCount === 1) ? Codicon.comment : Codicon.commentDiscussion)); + templateData.threadMetadata.icon.classList.remove(...Array.from(templateData.threadMetadata.icon.classList.values()) + .filter(value => value.startsWith('codicon'))); + templateData.threadMetadata.icon.classList.add(...ThemeIcon.asClassNameArray(this.getIcon(commentCount, node.element.threadState))); if (node.element.threadState !== undefined) { const color = this.getCommentThreadWidgetStateColor(node.element.threadState, this.themeService.getColorTheme()); templateData.threadMetadata.icon.style.setProperty(commentViewThreadStateColorVar, `${color}`); -- cgit v1.2.3 From 6e174529bb92ed514822491559951b34e7d87c5a Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 12 Jul 2022 15:52:08 +0200 Subject: tweak allow rules --- src/vs/workbench/contrib/webview/browser/webviewElement.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index a6386ed1d6e..fcc0777e76a 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -474,11 +474,14 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD element.name = this.id; element.className = `webview ${options.customClasses || ''}`; element.sandbox.add('allow-scripts', 'allow-same-origin', 'allow-forms', 'allow-pointer-lock', 'allow-downloads'); + + const allowRules = ['cross-origin-isolated;']; if (!isFirefox) { + allowRules.push('clipboard-read;', 'clipboard-write;'); element.setAttribute('allow', 'clipboard-read; clipboard-write; cross-origin-isolated;'); - } else { - element.setAttribute('allow', 'cross-origin-isolated;'); } + element.setAttribute('allow', allowRules.join(' ')); + element.style.border = 'none'; element.style.width = '100%'; element.style.height = '100%'; -- cgit v1.2.3 From 28e5d3a4b675077904a4c5679d106f978a6788c0 Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 12 Jul 2022 15:53:27 +0200 Subject: add `vscode-coi` argument for nested iframe, add COI allow attribute for nested iframe --- .../contrib/webview/browser/pre/index-no-csp.html | 13 ++++++++++--- src/vs/workbench/contrib/webview/browser/pre/index.html | 15 +++++++++++---- 2 files changed, 21 insertions(+), 7 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html b/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html index ec2b7281a65..6469cf31e74 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html +++ b/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html @@ -919,14 +919,21 @@ sandboxRules.add('allow-forms'); } newFrame.setAttribute('sandbox', Array.from(sandboxRules).join(' ')); - if (!isFirefox) { - newFrame.setAttribute('allow', options.allowScripts ? 'clipboard-read; clipboard-write;' : ''); + + const allowRules = ['cross-origin-isolated;'] + if(!isFirefox && options.allowScripts) { + allowRules.push('clipboard-read;','clipboard-write;') } + newFrame.setAttribute('allow', allowRules.join(' ')); // We should just be able to use srcdoc, but I wasn't // seeing the service worker applying properly. // Fake load an empty on the correct origin and then write real html // into it to get around this. - newFrame.src = `./fake.html?id=${ID}`; + const fakeUrlParams = new URLSearchParams({id: ID}); + if(globalThis.crossOriginIsolated) { + fakeUrlParams.set('vscode-coi', '3') /*COOP+COEP*/ + } + newFrame.src = `./fake.html?${fakeUrlParams.toString()}`; newFrame.style.cssText = 'display: block; margin: 0; overflow: hidden; position: absolute; width: 100%; height: 100%; visibility: hidden'; document.body.appendChild(newFrame); diff --git a/src/vs/workbench/contrib/webview/browser/pre/index.html b/src/vs/workbench/contrib/webview/browser/pre/index.html index 326a076c677..965b90ace22 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/index.html +++ b/src/vs/workbench/contrib/webview/browser/pre/index.html @@ -5,7 +5,7 @@ + content="default-src 'none'; script-src 'sha256-vGloSX/Mg/JYMjFOA5bYxbKTao1iYLW/tlq9ME/cEOo=' 'self'; frame-src 'self'; style-src 'unsafe-inline';"> Date: Tue, 12 Jul 2022 16:30:19 +0200 Subject: Fix #151921 (#154936) --- .../extensions/browser/extensionsActions.ts | 42 ++++++++++++++-------- 1 file changed, 28 insertions(+), 14 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index c6d34dc012f..2ec6eb12140 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -14,7 +14,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView import { dispose } from 'vs/base/common/lifecycle'; import { IExtension, ExtensionState, IExtensionsWorkbenchService, VIEWLET_ID, IExtensionsViewPaneContainer, IExtensionContainer, TOGGLE_IGNORE_EXTENSION_ACTION_ID, SELECT_INSTALL_VSIX_EXTENSION_COMMAND_ID, THEME_ACTIONS_GROUP, INSTALL_ACTIONS_GROUP } from 'vs/workbench/contrib/extensions/common/extensions'; import { ExtensionsConfigurationInitialContent } from 'vs/workbench/contrib/extensions/common/extensionsFileTemplate'; -import { IGalleryExtension, IExtensionGalleryService, ILocalExtension, InstallOptions, InstallOperation, TargetPlatformToString, ExtensionManagementErrorCode } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IGalleryExtension, IExtensionGalleryService, ILocalExtension, InstallOptions, InstallOperation, TargetPlatformToString, ExtensionManagementErrorCode, isTargetPlatformCompatible } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IWorkbenchExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { ExtensionRecommendationReason, IExtensionIgnoredRecommendationsService, IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations'; import { areSameExtensions, getExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; @@ -561,6 +561,7 @@ export abstract class InstallInOtherServerAction extends ExtensionAction { @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionManagementServerService protected readonly extensionManagementServerService: IExtensionManagementServerService, @IExtensionManifestPropertiesService private readonly extensionManifestPropertiesService: IExtensionManifestPropertiesService, + @IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService, ) { super(id, InstallInOtherServerAction.INSTALL_LABEL, InstallInOtherServerAction.Class, false); this.update(); @@ -635,19 +636,29 @@ export abstract class InstallInOtherServerAction extends ExtensionAction { } override async run(): Promise { - if (!this.extension) { + if (!this.extension?.local) { return; } - if (this.server) { - this.extensionsWorkbenchService.open(this.extension); - alert(localize('installExtensionStart', "Installing extension {0} started. An editor is now open with more details on this extension", this.extension.displayName)); - if (this.extension.gallery) { - await this.server.extensionManagementService.installFromGallery(this.extension.gallery, { installPreReleaseVersion: this.extension.local?.preRelease }); - } else { - const vsix = await this.extension.server!.extensionManagementService.zip(this.extension.local!); - await this.server.extensionManagementService.install(vsix); - } + if (!this.extension?.server) { + return; + } + if (!this.server) { + return; + } + this.extensionsWorkbenchService.open(this.extension); + alert(localize('installExtensionStart', "Installing extension {0} started. An editor is now open with more details on this extension", this.extension.displayName)); + + const gallery = this.extension.gallery ?? (this.extensionGalleryService.isEnabled() && (await this.extensionGalleryService.getExtensions([this.extension.identifier], CancellationToken.None))[0]); + if (gallery) { + await this.server.extensionManagementService.installFromGallery(gallery, { installPreReleaseVersion: this.extension.local.preRelease }); + return; + } + const targetPlatform = await this.server.extensionManagementService.getTargetPlatform(); + if (!isTargetPlatformCompatible(this.extension.local.targetPlatform, [this.extension.local.targetPlatform], targetPlatform)) { + throw new Error(localize('incompatible', "Can't install '{0}' extension because it is not compatible.", this.extension.identifier.id)); } + const vsix = await this.extension.server.extensionManagementService.zip(this.extension.local); + await this.server.extensionManagementService.install(vsix); } protected abstract getInstallLabel(): string; @@ -660,8 +671,9 @@ export class RemoteInstallAction extends InstallInOtherServerAction { @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService, @IExtensionManifestPropertiesService extensionManifestPropertiesService: IExtensionManifestPropertiesService, + @IExtensionGalleryService extensionGalleryService: IExtensionGalleryService, ) { - super(`extensions.remoteinstall`, extensionManagementServerService.remoteExtensionManagementServer, canInstallAnyWhere, extensionsWorkbenchService, extensionManagementServerService, extensionManifestPropertiesService); + super(`extensions.remoteinstall`, extensionManagementServerService.remoteExtensionManagementServer, canInstallAnyWhere, extensionsWorkbenchService, extensionManagementServerService, extensionManifestPropertiesService, extensionGalleryService); } protected getInstallLabel(): string { @@ -678,8 +690,9 @@ export class LocalInstallAction extends InstallInOtherServerAction { @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService, @IExtensionManifestPropertiesService extensionManifestPropertiesService: IExtensionManifestPropertiesService, + @IExtensionGalleryService extensionGalleryService: IExtensionGalleryService, ) { - super(`extensions.localinstall`, extensionManagementServerService.localExtensionManagementServer, false, extensionsWorkbenchService, extensionManagementServerService, extensionManifestPropertiesService); + super(`extensions.localinstall`, extensionManagementServerService.localExtensionManagementServer, false, extensionsWorkbenchService, extensionManagementServerService, extensionManifestPropertiesService, extensionGalleryService); } protected getInstallLabel(): string { @@ -694,8 +707,9 @@ export class WebInstallAction extends InstallInOtherServerAction { @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService, @IExtensionManifestPropertiesService extensionManifestPropertiesService: IExtensionManifestPropertiesService, + @IExtensionGalleryService extensionGalleryService: IExtensionGalleryService, ) { - super(`extensions.webInstall`, extensionManagementServerService.webExtensionManagementServer, false, extensionsWorkbenchService, extensionManagementServerService, extensionManifestPropertiesService); + super(`extensions.webInstall`, extensionManagementServerService.webExtensionManagementServer, false, extensionsWorkbenchService, extensionManagementServerService, extensionManifestPropertiesService, extensionGalleryService); } protected getInstallLabel(): string { -- cgit v1.2.3 From c7c0acd2ce4e0e541554fe8958922170a0fc53dc Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Tue, 12 Jul 2022 17:06:16 +0200 Subject: Git - Commit action button extension api (#154555) --- src/vs/workbench/contrib/scm/browser/scmViewPane.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts index 9af7e3e8a77..56be4b4065f 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts @@ -2644,19 +2644,11 @@ export class SCMActionButton implements IDisposable { return; } - const executeButtonAction = async (commandId: string, ...args: any[]) => { - try { - await this.commandService.executeCommand(commandId, ...args); - } catch (ex) { - this.notificationService.error(ex); - } - }; - if (button.secondaryCommands?.length) { const actions: IAction[] = []; for (let index = 0; index < button.secondaryCommands.length; index++) { for (const command of button.secondaryCommands[index]) { - actions.push(new Action(command.id, command.title, undefined, true, async () => await executeButtonAction(command.id, ...(command.arguments || [])))); + actions.push(new Action(command.id, command.title, undefined, true, async () => await this.executeCommand(command.id, ...(command.arguments || [])))); } if (index !== button.secondaryCommands.length - 1) { actions.push(new Separator()); @@ -2682,7 +2674,7 @@ export class SCMActionButton implements IDisposable { this.button.enabled = button.enabled; this.button.label = button.command.title; - this.button.onDidClick(async () => await executeButtonAction(button.command.id, ...(button.command.arguments || [])), null, this.disposables.value); + this.button.onDidClick(async () => await this.executeCommand(button.command.id, ...(button.command.arguments || [])), null, this.disposables.value); this.disposables.value!.add(this.button); this.disposables.value!.add(attachButtonStyler(this.button, this.themeService)); @@ -2697,4 +2689,12 @@ export class SCMActionButton implements IDisposable { this.button = undefined; clearNode(this.container); } + + private async executeCommand(commandId: string, ...args: any[]): Promise { + try { + await this.commandService.executeCommand(commandId, ...args); + } catch (ex) { + this.notificationService.error(ex); + } + } } -- cgit v1.2.3 From 56ae202f830e1c98221e2842d189c18434d75e45 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 12 Jul 2022 17:52:43 +0200 Subject: TypeError: Cannot read properties of null (reading 'value') (#154944) Fixes #154757 --- src/vs/workbench/api/common/extHostTreeViews.ts | 11 ++++- src/vs/workbench/api/common/extHostTypes.ts | 53 ++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 3 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/api/common/extHostTreeViews.ts b/src/vs/workbench/api/common/extHostTreeViews.ts index fdbb535e422..7eea30b6513 100644 --- a/src/vs/workbench/api/common/extHostTreeViews.ts +++ b/src/vs/workbench/api/common/extHostTreeViews.ts @@ -14,7 +14,7 @@ import { DataTransferDTO, ExtHostTreeViewsShape, MainThreadTreeViewsShape } from import { ITreeItem, TreeViewItemHandleArg, ITreeItemLabel, IRevealOptions } from 'vs/workbench/common/views'; import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/common/extHostCommands'; import { asPromise } from 'vs/base/common/async'; -import { TreeItemCollapsibleState, ThemeIcon, MarkdownString as MarkdownStringType } from 'vs/workbench/api/common/extHostTypes'; +import { TreeItemCollapsibleState, ThemeIcon, MarkdownString as MarkdownStringType, TreeItem } from 'vs/workbench/api/common/extHostTypes'; import { isUndefinedOrNull, isString } from 'vs/base/common/types'; import { equals, coalesce } from 'vs/base/common/arrays'; import { ILogService } from 'vs/platform/log/common/log'; @@ -500,6 +500,7 @@ class ExtHostTreeView extends Disposable { const node = this.nodes.get(element); if (node) { const resolve = await this.dataProvider.resolveTreeItem(node.extensionItem, element, token) ?? node.extensionItem; + this.validateTreeItem(resolve); // Resolvable elements. Currently only tooltip and command. node.item.tooltip = this.getTooltip(resolve.tooltip); node.item.command = this.getCommand(node.disposableStore, resolve.command); @@ -699,7 +700,15 @@ class ExtHostTreeView extends Disposable { return command ? this.commands.toInternal(command, disposable) : undefined; } + private validateTreeItem(extensionTreeItem: vscode.TreeItem) { + if (!TreeItem.isTreeItem(extensionTreeItem)) { + // TODO: #154757 we should consider throwing, but let's wait and see if there are tons of reports of this first. + console.log(`Extension ${this.extension.identifier.value} has provided an invalid tree item.`); + } + } + private createTreeNode(element: T, extensionTreeItem: vscode.TreeItem, parent: TreeNode | Root): TreeNode { + this.validateTreeItem(extensionTreeItem); const disposableStore = new DisposableStore(); const handle = this.createHandle(element, extensionTreeItem, parent); const icon = this.getLightIconPath(extensionTreeItem); diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 2cbff63ec7d..abeae060e2b 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -10,7 +10,7 @@ import { MarkdownString as BaseMarkdownString } from 'vs/base/common/htmlContent import { ResourceMap } from 'vs/base/common/map'; import { Mimes, normalizeMimeType } from 'vs/base/common/mime'; import { nextCharLength } from 'vs/base/common/strings'; -import { isArray, isStringArray } from 'vs/base/common/types'; +import { isArray, isString, isStringArray } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { generateUuid } from 'vs/base/common/uuid'; import { FileSystemProviderErrorCode, markAsFileSystemProviderError } from 'vs/platform/files/common/files'; @@ -2374,11 +2374,60 @@ export class TreeItem { label?: string | vscode.TreeItemLabel; resourceUri?: URI; - iconPath?: string | URI | { light: string | URI; dark: string | URI }; + iconPath?: string | URI | { light: string | URI; dark: string | URI } | ThemeIcon; command?: vscode.Command; contextValue?: string; tooltip?: string | vscode.MarkdownString; + static isTreeItem(thing: any): thing is TreeItem { + if (thing instanceof TreeItem) { + return true; + } + const treeItemThing = thing as vscode.TreeItem; + if (treeItemThing.label !== undefined && !isString(treeItemThing.label) && !(treeItemThing.label.label)) { + console.log('INVALID tree item, invalid label', treeItemThing.label); + return false; + } + if ((treeItemThing.id !== undefined) && !isString(treeItemThing.id)) { + console.log('INVALID tree item, invalid id', treeItemThing.id); + return false; + } + if ((treeItemThing.iconPath !== undefined) && !isString(treeItemThing.iconPath) && !URI.isUri(treeItemThing.iconPath) && !isString((treeItemThing.iconPath as vscode.ThemeIcon).id)) { + console.log('INVALID tree item, invalid iconPath', treeItemThing.iconPath); + return false; + } + if ((treeItemThing.description !== undefined) && !isString(treeItemThing.description) && (typeof treeItemThing.description !== 'boolean')) { + console.log('INVALID tree item, invalid description', treeItemThing.description); + return false; + } + if ((treeItemThing.resourceUri !== undefined) && !URI.isUri(treeItemThing.resourceUri)) { + console.log('INVALID tree item, invalid resourceUri', treeItemThing.resourceUri); + return false; + } + if ((treeItemThing.tooltip !== undefined) && !isString(treeItemThing.tooltip) && !(treeItemThing.tooltip instanceof MarkdownString)) { + console.log('INVALID tree item, invalid tooltip', treeItemThing.tooltip); + return false; + } + if ((treeItemThing.command !== undefined) && !treeItemThing.command.command) { + console.log('INVALID tree item, invalid command', treeItemThing.command); + return false; + } + if ((treeItemThing.collapsibleState !== undefined) && (treeItemThing.collapsibleState < TreeItemCollapsibleState.None) && (treeItemThing.collapsibleState > TreeItemCollapsibleState.Expanded)) { + console.log('INVALID tree item, invalid collapsibleState', treeItemThing.collapsibleState); + return false; + } + if ((treeItemThing.contextValue !== undefined) && !isString(treeItemThing.contextValue)) { + console.log('INVALID tree item, invalid contextValue', treeItemThing.contextValue); + return false; + } + if ((treeItemThing.accessibilityInformation !== undefined) && !treeItemThing.accessibilityInformation.label) { + console.log('INVALID tree item, invalid accessibilityInformation', treeItemThing.accessibilityInformation); + return false; + } + + return true; + } + constructor(label: string | vscode.TreeItemLabel, collapsibleState?: vscode.TreeItemCollapsibleState); constructor(resourceUri: URI, collapsibleState?: vscode.TreeItemCollapsibleState); constructor(arg1: string | vscode.TreeItemLabel | URI, public collapsibleState: vscode.TreeItemCollapsibleState = TreeItemCollapsibleState.None) { -- cgit v1.2.3 From 994ebb3488bdb8cc4c66dce6f6967356eb96f6ff Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 12 Jul 2022 10:16:36 -0700 Subject: Remove bracketed paste mode from sendText This has to be optionally applied to fix #153592 properly, probably with new API and command args. Fixes #154863 --- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 8a1810809f5..1f8a4970e50 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1487,12 +1487,6 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } async sendText(text: string, addNewLine: boolean): Promise { - // Apply bracketed paste sequences if the terminal has the mode enabled, this will prevent - // the text from triggering keybindings https://github.com/microsoft/vscode/issues/153592 - if (this.xterm?.raw.modes.bracketedPasteMode) { - text = `\x1b[200~${text}\x1b[201~`; - } - // Normalize line endings to 'enter' press. text = text.replace(/\r?\n/g, '\r'); if (addNewLine && text[text.length - 1] !== '\r') { -- cgit v1.2.3 From f86174be34131aaf3d118da10b3be5c59bae8375 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 12 Jul 2022 11:01:47 -0700 Subject: Export Interactive Window tab input (#154864) * Export Interactive Window tab input. * Update inputBoxUri. * remove inputBoxUri from API --- src/vs/workbench/api/browser/mainThreadEditorTabs.ts | 8 ++++++++ src/vs/workbench/api/common/extHost.api.impl.ts | 1 + src/vs/workbench/api/common/extHost.protocol.ts | 10 ++++++++-- src/vs/workbench/api/common/extHostEditorTabs.ts | 6 ++++-- src/vs/workbench/api/common/extHostTypes.ts | 3 +++ .../contrib/interactive/browser/interactiveEditorInput.ts | 9 +++++---- .../services/extensions/common/extensionsApiProposals.ts | 1 + 7 files changed, 30 insertions(+), 8 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/api/browser/mainThreadEditorTabs.ts b/src/vs/workbench/api/browser/mainThreadEditorTabs.ts index 2bcb34d00d1..22e06365994 100644 --- a/src/vs/workbench/api/browser/mainThreadEditorTabs.ts +++ b/src/vs/workbench/api/browser/mainThreadEditorTabs.ts @@ -22,6 +22,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput'; import { isEqual } from 'vs/base/common/resources'; import { isGroupEditorMoveEvent } from 'vs/workbench/common/editor/editorGroupModel'; +import { InteractiveEditorInput } from 'vs/workbench/contrib/interactive/browser/interactiveEditorInput'; interface TabInfo { tab: IEditorTabDto; @@ -162,6 +163,13 @@ export class MainThreadEditorTabs implements MainThreadEditorTabsShape { } } + if (editor instanceof InteractiveEditorInput) { + return { + kind: TabInputKind.InteractiveEditorInput, + uri: editor.resource + }; + } + return { kind: TabInputKind.UnknownInput }; } diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index efc0940e7ad..82f4a40688d 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1348,6 +1348,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I TabInputNotebookDiff: extHostTypes.NotebookDiffEditorTabInput, TabInputWebview: extHostTypes.WebviewEditorTabInput, TabInputTerminal: extHostTypes.TerminalEditorTabInput, + TabInputInteractiveWindow: extHostTypes.InteractiveWindowInput, TerminalExitReason: extHostTypes.TerminalExitReason }; }; diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 492e95a1b97..ccfed3c49c9 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -624,7 +624,8 @@ export const enum TabInputKind { NotebookDiffInput, CustomEditorInput, WebviewEditorInput, - TerminalEditorInput + TerminalEditorInput, + InteractiveEditorInput, } export const enum TabModelOperationKind { @@ -673,11 +674,16 @@ export interface WebviewInputDto { viewType: string; } +export interface InteractiveEditorInputDto { + kind: TabInputKind.InteractiveEditorInput; + uri: UriComponents; +} + export interface TabInputDto { kind: TabInputKind.TerminalEditorInput; } -export type AnyInputDto = UnknownInputDto | TextInputDto | TextDiffInputDto | NotebookInputDto | NotebookDiffInputDto | CustomInputDto | WebviewInputDto | TabInputDto; +export type AnyInputDto = UnknownInputDto | TextInputDto | TextDiffInputDto | NotebookInputDto | NotebookDiffInputDto | CustomInputDto | WebviewInputDto | InteractiveEditorInputDto | TabInputDto; export interface MainThreadEditorTabsShape extends IDisposable { // manage tabs: move, close, rearrange etc diff --git a/src/vs/workbench/api/common/extHostEditorTabs.ts b/src/vs/workbench/api/common/extHostEditorTabs.ts index 21a42adb1e4..f261df42feb 100644 --- a/src/vs/workbench/api/common/extHostEditorTabs.ts +++ b/src/vs/workbench/api/common/extHostEditorTabs.ts @@ -9,7 +9,7 @@ import { IEditorTabDto, IEditorTabGroupDto, IExtHostEditorTabsShape, MainContext import { URI } from 'vs/base/common/uri'; import { Emitter } from 'vs/base/common/event'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { CustomEditorTabInput, NotebookDiffEditorTabInput, NotebookEditorTabInput, TerminalEditorTabInput, TextDiffTabInput, TextTabInput, WebviewEditorTabInput } from 'vs/workbench/api/common/extHostTypes'; +import { CustomEditorTabInput, InteractiveWindowInput, NotebookDiffEditorTabInput, NotebookEditorTabInput, TerminalEditorTabInput, TextDiffTabInput, TextTabInput, WebviewEditorTabInput } from 'vs/workbench/api/common/extHostTypes'; import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { assertIsDefined } from 'vs/base/common/types'; import { diffSets } from 'vs/base/common/collections'; @@ -21,7 +21,7 @@ export interface IExtHostEditorTabs extends IExtHostEditorTabsShape { export const IExtHostEditorTabs = createDecorator('IExtHostEditorTabs'); -type AnyTabInput = TextTabInput | TextDiffTabInput | CustomEditorTabInput | NotebookEditorTabInput | NotebookDiffEditorTabInput | WebviewEditorTabInput | TerminalEditorTabInput; +type AnyTabInput = TextTabInput | TextDiffTabInput | CustomEditorTabInput | NotebookEditorTabInput | NotebookDiffEditorTabInput | WebviewEditorTabInput | TerminalEditorTabInput | InteractiveWindowInput; class ExtHostEditorTab { private _apiObject: vscode.Tab | undefined; @@ -94,6 +94,8 @@ class ExtHostEditorTab { return new NotebookDiffEditorTabInput(URI.revive(this._dto.input.original), URI.revive(this._dto.input.modified), this._dto.input.notebookType); case TabInputKind.TerminalEditorInput: return new TerminalEditorTabInput(); + case TabInputKind.InteractiveEditorInput: + return new InteractiveWindowInput(URI.revive(this._dto.input.uri)); default: return undefined; } diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index abeae060e2b..ec83bb937ae 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -3728,4 +3728,7 @@ export class NotebookDiffEditorTabInput { export class TerminalEditorTabInput { constructor() { } } +export class InteractiveWindowInput { + constructor(readonly uri: URI) { } +} //#endregion diff --git a/src/vs/workbench/contrib/interactive/browser/interactiveEditorInput.ts b/src/vs/workbench/contrib/interactive/browser/interactiveEditorInput.ts index 17d8eaa03cf..b814db12b5b 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactiveEditorInput.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactiveEditorInput.ts @@ -8,7 +8,6 @@ import { IReference } from 'vs/base/common/lifecycle'; import * as paths from 'vs/base/common/path'; import { isEqual } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; -import { IModelService } from 'vs/editor/common/services/model'; import { IResolvedTextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IUntypedEditorInput } from 'vs/workbench/common/editor'; @@ -44,8 +43,10 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot return [this._notebookEditorInput]; } - override get resource() { - return this.primary.resource; + private _resource: URI; + + override get resource(): URI { + return this._resource; } private _inputResource: URI; @@ -71,7 +72,6 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot inputResource: URI, title: string | undefined, @IInstantiationService instantiationService: IInstantiationService, - @IModelService modelService: IModelService, @ITextModelService textModelService: ITextModelService, @IInteractiveDocumentService interactiveDocumentService: IInteractiveDocumentService, @@ -82,6 +82,7 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot this._notebookEditorInput = input; this._register(this._notebookEditorInput); this._initTitle = title; + this._resource = resource; this._inputResource = inputResource; this._inputResolver = null; this._editorModelReference = null; diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index 3b024a26e63..17ab37e841f 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -31,6 +31,7 @@ export const allApiProposals = Object.freeze({ idToken: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.idToken.d.ts', inlineCompletionsAdditions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.inlineCompletionsAdditions.d.ts', inlineCompletionsNew: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.inlineCompletionsNew.d.ts', + interactiveWindow: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.interactiveWindow.d.ts', ipc: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.ipc.d.ts', notebookCellExecutionState: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookCellExecutionState.d.ts', notebookContentProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookContentProvider.d.ts', -- cgit v1.2.3 From 54927b0c5a5c2612876f2e71a6b038c4fac799e4 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 12 Jul 2022 12:11:00 -0700 Subject: Update notebook events comments (#154952) * Update notebook events comments * Update src/vs/workbench/contrib/notebook/browser/notebookEditor.ts Co-authored-by: Joyce Er Co-authored-by: Joyce Er --- src/vs/workbench/browser/parts/editor/editorCommands.ts | 1 + src/vs/workbench/contrib/notebook/browser/notebookEditor.ts | 1 + src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts | 1 + 3 files changed, 3 insertions(+) (limited to 'src/vs') diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index 717d7b138c1..6abeeef5019 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -969,6 +969,7 @@ function registerCloseEditorCommands() { type WorkbenchEditorReopenClassification = { owner: 'rebornix'; + comment: 'Identify how a document is reopened'; scheme: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' }; ext: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' }; from: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' }; diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts index 367c1f80e41..99d1d8de1f0 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts @@ -244,6 +244,7 @@ export class NotebookEditor extends EditorPane implements IEditorPaneWithSelecti type WorkbenchNotebookOpenClassification = { owner: 'rebornix'; + comment: 'The notebook file open metrics. Used to get a better understanding of the performance of notebook file opening'; scheme: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' }; ext: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' }; viewType: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' }; diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index 6047d713272..dc1e9554840 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -1100,6 +1100,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD } type WorkbenchNotebookOpenClassification = { owner: 'rebornix'; + comment: 'Identify the notebook editor view type'; scheme: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' }; ext: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' }; viewType: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' }; -- cgit v1.2.3 From ec72b669e08fd6e64b605ff7c4fd18a4194273a2 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 12 Jul 2022 12:50:01 -0700 Subject: Expose inputBoxUri and make IW Tab ctor private (#154979) --- src/vs/workbench/api/browser/mainThreadEditorTabs.ts | 3 ++- src/vs/workbench/api/common/extHost.protocol.ts | 1 + src/vs/workbench/api/common/extHostEditorTabs.ts | 2 +- src/vs/workbench/api/common/extHostTypes.ts | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/api/browser/mainThreadEditorTabs.ts b/src/vs/workbench/api/browser/mainThreadEditorTabs.ts index 22e06365994..c410ad77dc0 100644 --- a/src/vs/workbench/api/browser/mainThreadEditorTabs.ts +++ b/src/vs/workbench/api/browser/mainThreadEditorTabs.ts @@ -166,7 +166,8 @@ export class MainThreadEditorTabs implements MainThreadEditorTabsShape { if (editor instanceof InteractiveEditorInput) { return { kind: TabInputKind.InteractiveEditorInput, - uri: editor.resource + uri: editor.resource, + inputBoxUri: editor.inputResource }; } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index ccfed3c49c9..8df19f84b76 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -677,6 +677,7 @@ export interface WebviewInputDto { export interface InteractiveEditorInputDto { kind: TabInputKind.InteractiveEditorInput; uri: UriComponents; + inputBoxUri: UriComponents; } export interface TabInputDto { diff --git a/src/vs/workbench/api/common/extHostEditorTabs.ts b/src/vs/workbench/api/common/extHostEditorTabs.ts index f261df42feb..1df76fd88c7 100644 --- a/src/vs/workbench/api/common/extHostEditorTabs.ts +++ b/src/vs/workbench/api/common/extHostEditorTabs.ts @@ -95,7 +95,7 @@ class ExtHostEditorTab { case TabInputKind.TerminalEditorInput: return new TerminalEditorTabInput(); case TabInputKind.InteractiveEditorInput: - return new InteractiveWindowInput(URI.revive(this._dto.input.uri)); + return new InteractiveWindowInput(URI.revive(this._dto.input.uri), URI.revive(this._dto.input.inputBoxUri)); default: return undefined; } diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index ec83bb937ae..e50faecd595 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -3729,6 +3729,6 @@ export class TerminalEditorTabInput { constructor() { } } export class InteractiveWindowInput { - constructor(readonly uri: URI) { } + constructor(readonly uri: URI, readonly inputBoxUri: URI) { } } //#endregion -- cgit v1.2.3 From c5ca63370a159fba8f389f1a8a25322ff11e744a Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Tue, 12 Jul 2022 15:26:46 -0700 Subject: grab message from originalMessage as well as localized (#154989) grab message from originalMessage --- .../common/extensionsScannerService.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/extensionManagement/common/extensionsScannerService.ts b/src/vs/platform/extensionManagement/common/extensionsScannerService.ts index 194ff9965ae..115348c255f 100644 --- a/src/vs/platform/extensionManagement/common/extensionsScannerService.ts +++ b/src/vs/platform/extensionManagement/common/extensionsScannerService.ts @@ -35,6 +35,7 @@ import { revive } from 'vs/base/common/marshalling'; import { IExtensionsProfileScannerService, IScannedProfileExtension } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { ILocalizedString } from 'vs/platform/action/common/action'; export type IScannedExtensionManifest = IRelaxedExtensionManifest & { __metadata?: Metadata }; @@ -793,13 +794,23 @@ class ExtensionsScanner extends Disposable { if (translated === undefined && originalMessages) { translated = originalMessages[messageKey]; } - let message: string | undefined = typeof translated === 'string' ? translated : (typeof translated?.message === 'string' ? translated.message : undefined); + let message: string | undefined = typeof translated === 'string' ? translated : translated.message; if (message !== undefined) { if (pseudo) { // FF3B and FF3D is the Unicode zenkaku representation for [ and ] message = '\uFF3B' + message.replace(/[aouei]/g, '$&$&') + '\uFF3D'; } - obj[key] = command && (key === 'title' || key === 'category') && originalMessages ? { value: message, original: originalMessages[messageKey] } : message; + // This branch returns ILocalizedString's instead of Strings so that the Command Palette can contain both the localized and the original value. + if (command && originalMessages && (key === 'title' || key === 'category')) { + const originalMessage = originalMessages[messageKey]; + const localizedString: ILocalizedString = { + value: message, + original: typeof originalMessage === 'string' ? originalMessage : originalMessage?.message + }; + obj[key] = localizedString; + } else { + obj[key] = message; + } } else { this.logService.warn(this.formatMessage(extensionLocation, localize('missingNLSKey', "Couldn't find message for key {0}.", messageKey))); } -- cgit v1.2.3 From 0a26ed801edc07c6cd82c4d532f9c4f50e1fbdb3 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Wed, 13 Jul 2022 00:53:11 +0200 Subject: Expand isButton to catch ButtonWithDropdown as well (#154987) --- src/vs/base/browser/ui/list/listWidget.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index d97fe00bbf2..db0a0b718dc 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -259,7 +259,8 @@ export function isMonacoEditor(e: HTMLElement): boolean { } export function isButton(e: HTMLElement): boolean { - if (e.tagName === 'A' && e.classList.contains('monaco-button')) { + if ((e.tagName === 'A' && e.classList.contains('monaco-button')) || + (e.tagName === 'DIV' && e.classList.contains('monaco-button-dropdown'))) { return true; } -- cgit v1.2.3 From 66d8947f84b6dba315d577983ea1968c70718c74 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Tue, 12 Jul 2022 18:54:32 -0400 Subject: Fix #154963 (#154975) --- .../contrib/welcomeGettingStarted/browser/gettingStarted.ts | 5 +++-- .../contrib/welcomeGettingStarted/browser/media/gettingStarted.css | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts index f119f79c69d..497dfb1165c 100644 --- a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts +++ b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts @@ -70,6 +70,7 @@ import { Codicon } from 'vs/base/common/codicons'; import { restoreWalkthroughsConfigurationKey, RestoreWalkthroughsConfigurationValue } from 'vs/workbench/contrib/welcomeGettingStarted/browser/startupPage'; import { GettingStartedDetailsRenderer } from 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedDetailsRenderer'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; +import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels'; const SLIDE_TRANSITION_TIME_MS = 250; const configurationKey = 'workbench.startupEditor'; @@ -968,7 +969,7 @@ export class GettingStartedPage extends EditorPane { if (category.isFeatured) { reset(featuredBadge, $('.featured', {}, $('span.featured-icon.codicon.codicon-star-empty'))); - reset(descriptionContent, category.description); + reset(descriptionContent, ...renderLabelWithIcons(category.description)); } return $('button.getting-started-category' + (category.isFeatured ? '.featured' : ''), @@ -1237,7 +1238,7 @@ export class GettingStartedPage extends EditorPane { this.iconWidgetFor(category), $('.category-description-container', {}, $('h2.category-title.max-lines-3', { 'x-category-title-for': category.id }, category.title), - $('.category-description.description.max-lines-3', { 'x-category-description-for': category.id }, category.description))); + $('.category-description.description.max-lines-3', { 'x-category-description-for': category.id }, ...renderLabelWithIcons(category.description)))); const stepListContainer = $('.step-list-container'); diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css b/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css index eb269e524fe..60016371f6d 100644 --- a/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css +++ b/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css @@ -284,6 +284,11 @@ margin-left: 28px; } +.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .description-content > .codicon { + padding-right: 1px; + font-size: 16px; +} + .monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .description-content:not(:empty){ margin-bottom: 8px; } @@ -368,7 +373,7 @@ flex: 150px 1 1000 } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-category .codicon { +.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent>.getting-started-category>.codicon-getting-started-setup { margin-right: 8px; font-size: 28px; } -- cgit v1.2.3 From 18d44051cd7d0b15097c6c9afd9af16add88f56c Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 12 Jul 2022 17:01:20 -0700 Subject: Fix #151981. Avoid re-focus output when output already has focus. (#154991) --- .../contrib/notebook/browser/view/renderers/webviewPreloads.ts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index 0ce36982b24..f0eb46d08bb 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -400,6 +400,10 @@ async function webviewPreloads(ctx: PreloadContext) { function focusFirstFocusableInCell(cellId: string) { const cellOutputContainer = document.getElementById(cellId); if (cellOutputContainer) { + if (cellOutputContainer.contains(document.activeElement)) { + return; + } + const focusableElement = cellOutputContainer.querySelector('[tabindex="0"], [href], button, input, option, select, textarea') as HTMLElement | null; focusableElement?.focus(); } -- cgit v1.2.3 From 3e18c4995f9233937c391cf34057be191a989230 Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Tue, 12 Jul 2022 17:05:28 -0700 Subject: Escape query, fixes #153583 (#154990) --- src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts b/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts index 8f833f178f6..2c59b8bfc44 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts @@ -554,7 +554,7 @@ export class SettingMatches { // Trim excess ending characters off the query. singleWordQuery = singleWordQuery.toLowerCase().replace(/[\s-\._]+$/, ''); lineToSearch = lineToSearch.toLowerCase(); - const singleWordRegex = new RegExp(`\\b${singleWordQuery}\\b`); + const singleWordRegex = new RegExp(`\\b${strings.escapeRegExpCharacters(singleWordQuery)}\\b`); if (singleWordRegex.test(lineToSearch)) { this.matchType |= SettingMatchType.WholeWordMatch; } -- cgit v1.2.3 From f64912465fa76c2c1d4f8cbe0152864c2194c281 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 12 Jul 2022 18:02:32 -0700 Subject: Add hot exit support for interactive window (#154974) * Export Interactive Window tab input. * Update inputBoxUri. * remove inputBoxUri from API * Hot exit * Expose inputBoxUri and make IW Tab ctor private * disable hot exit by default --- .../browser/interactive.contribution.ts | 43 +++++--- .../interactive/browser/interactiveCommon.ts | 5 + .../interactive/browser/interactiveEditor.ts | 12 ++- .../interactive/browser/interactiveEditorInput.ts | 120 ++++++++++++++++++++- .../contrib/notebook/common/notebookCommon.ts | 3 +- 5 files changed, 162 insertions(+), 21 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts index c49ec5ad519..9969bd9c645 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts @@ -24,6 +24,7 @@ import { peekViewBorder /*, peekViewEditorBackground, peekViewResultsBackground import { Context as SuggestContext } from 'vs/editor/contrib/suggest/browser/suggest'; import { localize } from 'vs/nls'; import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { EditorActivation, IResourceEditorInput } from 'vs/platform/editor/common/editor'; @@ -38,12 +39,12 @@ import { contrastBorder, listInactiveSelectionBackground, registerColor, transpa import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { EditorPaneDescriptor, IEditorPaneRegistry } from 'vs/workbench/browser/editor'; import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; -import { EditorExtensions, EditorsOrder, IEditorSerializer } from 'vs/workbench/common/editor'; +import { EditorExtensions, EditorsOrder, IEditorFactoryRegistry, IEditorSerializer } from 'vs/workbench/common/editor'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; // import { Color } from 'vs/base/common/color'; import { PANEL_BORDER } from 'vs/workbench/common/theme'; import { ResourceNotebookCellEdit } from 'vs/workbench/contrib/bulkEdit/browser/bulkCellEdits'; -import { INTERACTIVE_INPUT_CURSOR_BOUNDARY } from 'vs/workbench/contrib/interactive/browser/interactiveCommon'; +import { InteractiveWindowSetting, INTERACTIVE_INPUT_CURSOR_BOUNDARY } from 'vs/workbench/contrib/interactive/browser/interactiveCommon'; import { IInteractiveDocumentService, InteractiveDocumentService } from 'vs/workbench/contrib/interactive/browser/interactiveDocumentService'; import { InteractiveEditor } from 'vs/workbench/contrib/interactive/browser/interactiveEditor'; import { InteractiveEditorInput } from 'vs/workbench/contrib/interactive/browser/interactiveEditorInput'; @@ -52,7 +53,7 @@ import { NOTEBOOK_EDITOR_WIDGET_ACTION_WEIGHT } from 'vs/workbench/contrib/noteb import { INotebookEditorOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { NotebookEditorWidget } from 'vs/workbench/contrib/notebook/browser/notebookEditorWidget'; import * as icons from 'vs/workbench/contrib/notebook/browser/notebookIcons'; -import { CellEditType, CellKind, CellUri, ICellOutput, NotebookSetting } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellEditType, CellKind, CellUri, ICellOutput } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService'; import { INotebookContentProvider, INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; import { columnToEditorGroup } from 'vs/workbench/services/editor/common/editorGroupColumn'; @@ -194,7 +195,7 @@ export class InteractiveDocumentContribution extends Disposable implements IWork editorResolverService.registerEditor( `${Schemas.vscodeInteractiveInput}:/**`, { - id: InteractiveEditorInput.ID, + id: 'vscode-interactive-input', label: 'Interactive Editor', priority: RegisteredEditorPriority.exclusive }, @@ -211,7 +212,7 @@ export class InteractiveDocumentContribution extends Disposable implements IWork editorResolverService.registerEditor( `*.interactive`, { - id: InteractiveEditorInput.ID, + id: 'interactive', label: 'Interactive Editor', priority: RegisteredEditorPriority.exclusive }, @@ -272,8 +273,13 @@ workbenchContributionsRegistry.registerWorkbenchContribution(InteractiveDocument workbenchContributionsRegistry.registerWorkbenchContribution(InteractiveInputContentProvider, LifecyclePhase.Starting); export class InteractiveEditorSerializer implements IEditorSerializer { + public static readonly ID = InteractiveEditorInput.ID; + + constructor(@IConfigurationService private configurationService: IConfigurationService) { + } + canSerialize(): boolean { - return true; + return this.configurationService.getValue(InteractiveWindowSetting.interactiveWindowHotExit); } serialize(input: EditorInput): string { @@ -281,11 +287,16 @@ export class InteractiveEditorSerializer implements IEditorSerializer { return JSON.stringify({ resource: input.primary.resource, inputResource: input.inputResource, + name: input.getName(), + data: input.getSerialization() }); } deserialize(instantiationService: IInstantiationService, raw: string) { - type Data = { resource: URI; inputResource: URI }; + if (!this.canSerialize()) { + return undefined; + } + type Data = { resource: URI; inputResource: URI; data: any }; const data = parse(raw); if (!data) { return undefined; @@ -296,14 +307,15 @@ export class InteractiveEditorSerializer implements IEditorSerializer { } const input = InteractiveEditorInput.create(instantiationService, resource, inputResource); + input.restoreSerialization(data.data); return input; } } -// Registry.as(EditorExtensions.EditorInputFactories).registerEditorInputSerializer( -// InteractiveEditorInput.ID, -// InteractiveEditorSerializer -// ); +Registry.as(EditorExtensions.EditorFactory) + .registerEditorSerializer( + InteractiveEditorSerializer.ID, + InteractiveEditorSerializer); registerSingleton(IInteractiveHistoryService, InteractiveHistoryService); registerSingleton(IInteractiveDocumentService, InteractiveDocumentService); @@ -738,15 +750,20 @@ registerThemingParticipant((theme) => { }); Registry.as(ConfigurationExtensions.Configuration).registerConfiguration({ - id: 'notebook', + id: 'interactiveWindow', order: 100, type: 'object', 'properties': { - [NotebookSetting.interactiveWindowAlwaysScrollOnNewCell]: { + [InteractiveWindowSetting.interactiveWindowAlwaysScrollOnNewCell]: { type: 'boolean', default: true, markdownDescription: localize('interactiveWindow.alwaysScrollOnNewCell', "Automatically scroll the interactive window to show the output of the last statement executed. If this value is false, the window will only scroll if the last cell was already the one scrolled to.") }, + [InteractiveWindowSetting.interactiveWindowHotExit]: { + type: 'boolean', + default: false, + markdownDescription: localize('interactiveWindow.hotExit', "Controls whether the interactive window sessions should be restored when the workspace reloads.") + } } }); diff --git a/src/vs/workbench/contrib/interactive/browser/interactiveCommon.ts b/src/vs/workbench/contrib/interactive/browser/interactiveCommon.ts index ef37c64c93b..edda5c7f25f 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactiveCommon.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactiveCommon.ts @@ -6,3 +6,8 @@ import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; export const INTERACTIVE_INPUT_CURSOR_BOUNDARY = new RawContextKey<'none' | 'top' | 'bottom' | 'both'>('interactiveInputCursorAtBoundary', 'none'); + +export const InteractiveWindowSetting = { + interactiveWindowAlwaysScrollOnNewCell: 'interactiveWindow.alwaysScrollOnNewCell', + interactiveWindowHotExit: 'interactiveWindow.hotExit' +}; diff --git a/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts b/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts index ca1f164befa..81992e7547d 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts @@ -33,9 +33,8 @@ import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry' import { ILanguageService } from 'vs/editor/common/languages/language'; import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { INTERACTIVE_INPUT_CURSOR_BOUNDARY } from 'vs/workbench/contrib/interactive/browser/interactiveCommon'; +import { InteractiveWindowSetting, INTERACTIVE_INPUT_CURSOR_BOUNDARY } from 'vs/workbench/contrib/interactive/browser/interactiveCommon'; import { ComplexNotebookEditorModel } from 'vs/workbench/contrib/notebook/common/notebookEditorModel'; -import { NotebookSetting } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { NotebookOptions } from 'vs/workbench/contrib/notebook/common/notebookOptions'; import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar'; @@ -57,6 +56,7 @@ import { ITextEditorOptions, TextEditorSelectionSource } from 'vs/platform/edito import { INotebookExecutionStateService } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService'; import { NOTEBOOK_KERNEL } from 'vs/workbench/contrib/notebook/common/notebookContextKeys'; import { ICursorPositionChangedEvent } from 'vs/editor/common/cursorEvents'; +import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; const DECORATION_KEY = 'interactiveInputDecoration'; const INTERACTIVE_EDITOR_VIEW_STATE_PREFERENCE_KEY = 'InteractiveEditorViewState'; @@ -97,6 +97,7 @@ export class InteractiveEditor extends EditorPane { #contextMenuService: IContextMenuService; #editorGroupService: IEditorGroupsService; #notebookExecutionStateService: INotebookExecutionStateService; + #extensionService: IExtensionService; #widgetDisposableStore: DisposableStore = this._register(new DisposableStore()); #dimension?: DOM.Dimension; #notebookOptions: NotebookOptions; @@ -124,7 +125,8 @@ export class InteractiveEditor extends EditorPane { @IContextMenuService contextMenuService: IContextMenuService, @IEditorGroupsService editorGroupService: IEditorGroupsService, @ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService, - @INotebookExecutionStateService notebookExecutionStateService: INotebookExecutionStateService + @INotebookExecutionStateService notebookExecutionStateService: INotebookExecutionStateService, + @IExtensionService extensionService: IExtensionService, ) { super( InteractiveEditor.ID, @@ -142,6 +144,7 @@ export class InteractiveEditor extends EditorPane { this.#contextMenuService = contextMenuService; this.#editorGroupService = editorGroupService; this.#notebookExecutionStateService = notebookExecutionStateService; + this.#extensionService = extensionService; this.#notebookOptions = new NotebookOptions(configurationService, notebookExecutionStateService, { cellToolbarInteraction: 'hover', globalToolbar: true, defaultCellCollapseConfig: { codeCell: { inputCollapsed: true } } }); this.#editorMemento = this.getEditorMemento(editorGroupService, textResourceConfigurationService, INTERACTIVE_EDITOR_VIEW_STATE_PREFERENCE_KEY); @@ -397,6 +400,7 @@ export class InteractiveEditor extends EditorPane { this.#notebookWidget.value?.setParentContextKeyService(this.#contextKeyService); const viewState = options?.viewState ?? this.#loadNotebookEditorViewState(input); + await this.#extensionService.whenInstalledExtensionsRegistered(); await this.#notebookWidget.value!.setModel(model.notebook, viewState?.notebook); model.notebook.setCellCollapseDefault(this.#notebookOptions.getCellCollapseDefault()); this.#notebookWidget.value!.setOptions({ @@ -528,7 +532,7 @@ export class InteractiveEditor extends EditorPane { const index = this.#notebookWidget.value!.getCellIndex(cvm); if (index === this.#notebookWidget.value!.getLength() - 1) { // If we're already at the bottom or auto scroll is enabled, scroll to the bottom - if (this.configurationService.getValue(NotebookSetting.interactiveWindowAlwaysScrollOnNewCell) || this.#cellAtBottom(cvm)) { + if (this.configurationService.getValue(InteractiveWindowSetting.interactiveWindowAlwaysScrollOnNewCell) || this.#cellAtBottom(cvm)) { this.#notebookWidget.value!.scrollToBottom(); } } diff --git a/src/vs/workbench/contrib/interactive/browser/interactiveEditorInput.ts b/src/vs/workbench/contrib/interactive/browser/interactiveEditorInput.ts index b814db12b5b..71b125ec799 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactiveEditorInput.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactiveEditorInput.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { VSBuffer } from 'vs/base/common/buffer'; import { Event } from 'vs/base/common/event'; import { IReference } from 'vs/base/common/lifecycle'; import * as paths from 'vs/base/common/path'; @@ -14,7 +15,9 @@ import { IUntypedEditorInput } from 'vs/workbench/common/editor'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { IInteractiveDocumentService } from 'vs/workbench/contrib/interactive/browser/interactiveDocumentService'; import { IInteractiveHistoryService } from 'vs/workbench/contrib/interactive/browser/interactiveHistoryService'; -import { IResolvedNotebookEditorModel } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel'; +import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; +import { CellKind, ICellDto2, IOutputDto, IResolvedNotebookEditorModel, NotebookCellCollapseState, NotebookCellInternalMetadata, NotebookCellMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { ICompositeNotebookEditorInput, NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput'; export class InteractiveEditorInput extends EditorInput implements ICompositeNotebookEditorInput { @@ -131,7 +134,14 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot return this._inputResolver; } - this._inputResolver = this._resolveEditorModel(); + this._inputResolver = this._resolveEditorModel().then(editorModel => { + if (this._data) { + editorModel?.notebook.reset(this._data.notebookData.cells.map((cell: ISerializedCell) => deserializeCell(cell)), this._data.notebookData.metadata, this._data.notebookData.transientOptions); + } + + return editorModel; + }); + return this._inputResolver; } @@ -143,6 +153,10 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot this._interactiveDocumentService.willCreateInteractiveDocument(this.resource!, this.inputResource, language); this._inputModelRef = await this._textModelService.createModelReference(this.inputResource); + if (this._data && this._data.inputData) { + this._inputModelRef.object.textEditorModel.setValue(this._data.inputData.value); + } + return this._inputModelRef.object.textEditorModel; } @@ -167,6 +181,37 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot return basename.substr(0, basename.length - paths.extname(p).length); } + getSerialization(): { notebookData: any | undefined; inputData: any | undefined } { + return { + notebookData: this._serializeNotebook(this._editorModelReference?.notebook), + inputData: this._inputModelRef ? { + value: this._inputModelRef.object.textEditorModel.getValue(), + language: this._inputModelRef.object.textEditorModel.getLanguageId() + } : undefined + }; + } + + private _data: { notebookData: any | undefined; inputData: any | undefined } | undefined; + + async restoreSerialization(data: { notebookData: any | undefined; inputData: any | undefined } | undefined) { + this._data = data; + } + + private _serializeNotebook(notebook?: NotebookTextModel) { + if (!notebook) { + return undefined; + } + + const cells = notebook.cells.map(cell => serializeCell(cell)); + + return { + cells: cells, + metadata: notebook.metadata, + transientOptions: notebook.transientOptions + }; + } + + override dispose() { // we support closing the interactive window without prompt, so the editor model should not be dirty this._editorModelReference?.revert({ soft: true }); @@ -184,3 +229,74 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot return this._historyService; } } + +/** + * Serialization of interactive notebook. + * This is not placed in notebook land as regular notebooks are handled by file service directly. + */ + +interface ISerializedOutputItem { + readonly mime: string; + readonly data: number[]; +} + +interface ISerializedCellOutput { + outputs: ISerializedOutputItem[]; + metadata?: Record; + outputId: string; +} + +export interface ISerializedCell { + source: string; + language: string; + mime: string | undefined; + cellKind: CellKind; + outputs: ISerializedCellOutput[]; + metadata?: NotebookCellMetadata; + internalMetadata?: NotebookCellInternalMetadata; + collapseState?: NotebookCellCollapseState; +} + +function serializeCell(cell: NotebookCellTextModel): ISerializedCell { + return { + cellKind: cell.cellKind, + language: cell.language, + metadata: cell.metadata, + mime: cell.mime, + outputs: cell.outputs.map(output => serializeCellOutput(output)), + source: cell.getValue() + }; +} + +function deserializeCell(cell: ISerializedCell): ICellDto2 { + return { + cellKind: cell.cellKind, + source: cell.source, + language: cell.language, + metadata: cell.metadata, + mime: cell.mime, + outputs: cell.outputs.map((output) => deserializeCellOutput(output)) + }; +} + +function serializeCellOutput(output: IOutputDto): ISerializedCellOutput { + return { + outputId: output.outputId, + outputs: output.outputs.map(ot => ({ + mime: ot.mime, + data: ot.data.buffer ? Array.from(ot.data.buffer) : [] + })), + metadata: output.metadata + }; +} + +function deserializeCellOutput(output: ISerializedCellOutput): IOutputDto { + return { + outputId: output.outputId, + outputs: output.outputs.map(ot => ({ + mime: ot.mime, + data: VSBuffer.fromByteArray(ot.data) + })), + metadata: output.metadata + }; +} diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index a95ecc6fb84..8e13cf654cd 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -923,8 +923,7 @@ export const NotebookSetting = { interactiveWindowCollapseCodeCells: 'interactiveWindow.collapseCellInputCode', outputLineHeight: 'notebook.outputLineHeight', outputFontSize: 'notebook.outputFontSize', - outputFontFamily: 'notebook.outputFontFamily', - interactiveWindowAlwaysScrollOnNewCell: 'interactiveWindow.alwaysScrollOnNewCell' + outputFontFamily: 'notebook.outputFontFamily' } as const; export const enum CellStatusbarAlignment { -- cgit v1.2.3 From 052d5b0027f6c9d64c8ca35955cb5117ba94d5d7 Mon Sep 17 00:00:00 2001 From: Rich Chiodo Date: Tue, 12 Jul 2022 18:03:49 -0700 Subject: Fix issue with kernel preselection being overridden by view state (#154968) * Fix view state overriding selected kernel * Add test to verify correct kernel is used --- src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/vs') diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index dc1e9554840..3debc2599a6 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -1693,8 +1693,11 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD private _restoreSelectedKernel(viewState: INotebookEditorViewState | undefined): void { if (viewState?.selectedKernelId && this.textModel) { - const kernel = this.notebookKernelService.getMatchingKernel(this.textModel).all.find(k => k.id === viewState.selectedKernelId); - if (kernel) { + const matching = this.notebookKernelService.getMatchingKernel(this.textModel); + const kernel = matching.all.find(k => k.id === viewState.selectedKernelId); + // Selected kernel may have already been picked prior to the view state loading + // If so, don't overwrite it with the saved kernel. + if (kernel && !matching.selected) { this.notebookKernelService.selectKernelForNotebook(kernel, this.textModel); } } -- cgit v1.2.3 From 3ec5a08318d9e7e6c6e2c94f310fa13137b05b41 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 13 Jul 2022 11:13:53 +0200 Subject: `--diff` on workspace files opens the workspace instead of diff-ing them (fix #149731) (#155011) --- src/vs/platform/windows/electron-main/windowsMainService.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/platform/windows/electron-main/windowsMainService.ts b/src/vs/platform/windows/electron-main/windowsMainService.ts index 0d2cdc09834..af32788dce5 100644 --- a/src/vs/platform/windows/electron-main/windowsMainService.ts +++ b/src/vs/platform/windows/electron-main/windowsMainService.ts @@ -785,7 +785,12 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic private doExtractPathsFromCLI(cli: NativeParsedArgs): IPath[] { const pathsToOpen: IPathToOpen[] = []; - const pathResolveOptions: IPathResolveOptions = { ignoreFileNotFound: true, gotoLineMode: cli.goto, remoteAuthority: cli.remote || undefined, forceOpenWorkspaceAsFile: false }; + const pathResolveOptions: IPathResolveOptions = { + ignoreFileNotFound: true, + gotoLineMode: cli.goto, + remoteAuthority: cli.remote || undefined, + forceOpenWorkspaceAsFile: cli.diff && cli._.length === 2 // special case diff mode to force open workspace as file (https://github.com/microsoft/vscode/issues/149731) + }; // folder uris const folderUris = cli['folder-uri']; -- cgit v1.2.3 From bc7496ec7b93f75beb7af98695b72c02cb367632 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 13 Jul 2022 11:14:49 +0200 Subject: editors - do not check confirm again right after for custom confirm handlers (#155024) --- src/vs/workbench/browser/parts/editor/editorGroupView.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/vs') diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index bdeec719d93..d2df00e4d5e 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -1576,7 +1576,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // again to see if anything needs to happen before closing for good. // This can happen for example if `autoSave: onFocusChange` is configured // so that the save happens when the dialog opens. - if (!this.shouldConfirmClose(editor)) { + // However, we only do this unless a custom confirm handler is installed + // that may not be fit to be asked a second time right after. + if (!editor.closeHandler && !this.shouldConfirmClose(editor)) { return confirmation === ConfirmResult.CANCEL ? true : false; } -- cgit v1.2.3 From 3f4cc8752baf3e48155e9aaaf06531d71cb26e42 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 13 Jul 2022 11:15:57 +0200 Subject: fix #155022 (#155025) --- .../extensionManagement/common/webExtensionManagementService.ts | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/vs') diff --git a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts index 23413b1b130..a35c50b1cd2 100644 --- a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts @@ -103,10 +103,16 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe } protected doCreateInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions): IInstallExtensionTask { + if (!options.profileLocation) { + options = { ...options, profileLocation: this.userDataProfileService.currentProfile.extensionsResource }; + } return new InstallExtensionTask(manifest, extension, options, this.webExtensionsScannerService); } protected doCreateUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions): IUninstallExtensionTask { + if (!options.profileLocation) { + options = { ...options, profileLocation: this.userDataProfileService.currentProfile.extensionsResource }; + } return new UninstallExtensionTask(extension, options, this.webExtensionsScannerService); } -- cgit v1.2.3 From 5737c7eea15e195edde1e9228238cddbf3e93c1d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 13 Jul 2022 11:54:40 +0200 Subject: allow to reuse a menu id and only to create one when none with the id exists (#155042) fixes https://github.com/microsoft/vscode/issues/155030 --- src/vs/platform/actions/common/actions.ts | 19 +++++++++++++++---- .../platform/actions/test/common/menuService.test.ts | 9 +++++++++ .../services/actions/common/menusExtensionPoint.ts | 2 +- 3 files changed, 25 insertions(+), 5 deletions(-) (limited to 'src/vs') diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index 0b4a4ea32db..461df3221c1 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -45,7 +45,7 @@ export function isISubmenuItem(item: IMenuItem | ISubmenuItem): item is ISubmenu export class MenuId { - private static readonly _idPool = new Set(); + private static readonly _instances = new Map(); static readonly CommandPalette = new MenuId('CommandPalette'); static readonly DebugBreakpointsContext = new MenuId('DebugBreakpointsContext'); @@ -162,14 +162,25 @@ export class MenuId { static readonly NewFile = new MenuId('NewFile'); static readonly MergeToolbar = new MenuId('MergeToolbar'); + /** + * Create or reuse a `MenuId` with the given identifier + */ + static for(identifier: string): MenuId { + return MenuId._instances.get(identifier) ?? new MenuId(identifier); + } readonly id: string; + /** + * Create a new `MenuId` with the unique identifier. Will throw if a menu + * with the identifier already exists, use `MenuId.for(ident)` or a unique + * identifier + */ constructor(identifier: string) { - if (MenuId._idPool.has(identifier)) { - throw new Error(`Duplicate menu identifier ${identifier}`); + if (MenuId._instances.has(identifier)) { + throw new TypeError(`MenuId with identifier '${identifier}' already exists. Use MenuId.for(ident) or a unique identifier`); } - MenuId._idPool.add(identifier); + MenuId._instances.set(identifier, this); this.id = identifier; } } diff --git a/src/vs/platform/actions/test/common/menuService.test.ts b/src/vs/platform/actions/test/common/menuService.test.ts index d1eb35d24f8..99b108e152e 100644 --- a/src/vs/platform/actions/test/common/menuService.test.ts +++ b/src/vs/platform/actions/test/common/menuService.test.ts @@ -202,4 +202,13 @@ suite('MenuService', function () { assert.strictEqual(foundA, true); assert.strictEqual(foundB, true); }); + + test('Extension contributed submenus missing with errors in output #155030', function () { + + const id = generateUuid(); + const menu = new MenuId(id); + + assert.throws(() => new MenuId(id)); + assert.ok(menu === MenuId.for(id)); + }); }); diff --git a/src/vs/workbench/services/actions/common/menusExtensionPoint.ts b/src/vs/workbench/services/actions/common/menusExtensionPoint.ts index 04a83f56357..001cf0f3815 100644 --- a/src/vs/workbench/services/actions/common/menusExtensionPoint.ts +++ b/src/vs/workbench/services/actions/common/menusExtensionPoint.ts @@ -717,7 +717,7 @@ submenusExtensionPoint.setHandler(extensions => { } const item: IRegisteredSubmenu = { - id: new MenuId(`api:${submenuInfo.id}`), + id: MenuId.for(`api:${submenuInfo.id}`), label: submenuInfo.label, icon: absoluteIcon }; -- cgit v1.2.3 From 4404dc63561a286e13f9ba5a669e5403a367425a Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 13 Jul 2022 11:56:15 +0200 Subject: Explorer: cannot copy paste anymore to duplicate file with sandbox enabled (fix #154820) (#155044) * Explorer: cannot copy paste anymore to duplicate file with sandbox enabled (fix #154820) * skip smudge! --- src/vs/base/parts/sandbox/electron-browser/preload.js | 8 ++++---- src/vs/platform/native/common/native.ts | 5 +++-- src/vs/platform/native/electron-main/nativeHostMainService.ts | 9 +++++---- .../services/clipboard/electron-sandbox/clipboardService.ts | 6 +++--- src/vs/workbench/test/electron-browser/workbenchTestServices.ts | 5 +++-- 5 files changed, 18 insertions(+), 15 deletions(-) (limited to 'src/vs') diff --git a/src/vs/base/parts/sandbox/electron-browser/preload.js b/src/vs/base/parts/sandbox/electron-browser/preload.js index 3e25c4097f1..53e38ce14c2 100644 --- a/src/vs/base/parts/sandbox/electron-browser/preload.js +++ b/src/vs/base/parts/sandbox/electron-browser/preload.js @@ -145,7 +145,7 @@ /** * @param {string} channel * @param {any[]} args - * @returns {Promise | undefined} + * @returns {Promise | never} */ invoke(channel, ...args) { if (validateIPC(channel)) { @@ -156,7 +156,7 @@ /** * @param {string} channel * @param {(event: IpcRendererEvent, ...args: any[]) => void} listener - * @returns {IpcRenderer} + * @returns {IpcRenderer | never} */ on(channel, listener) { if (validateIPC(channel)) { @@ -169,7 +169,7 @@ /** * @param {string} channel * @param {(event: IpcRendererEvent, ...args: any[]) => void} listener - * @returns {IpcRenderer} + * @returns {IpcRenderer | never} */ once(channel, listener) { if (validateIPC(channel)) { @@ -182,7 +182,7 @@ /** * @param {string} channel * @param {(event: IpcRendererEvent, ...args: any[]) => void} listener - * @returns {IpcRenderer} + * @returns {IpcRenderer | never} */ removeListener(channel, listener) { if (validateIPC(channel)) { diff --git a/src/vs/platform/native/common/native.ts b/src/vs/platform/native/common/native.ts index 5f6937e8655..5698299eb3c 100644 --- a/src/vs/platform/native/common/native.ts +++ b/src/vs/platform/native/common/native.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { VSBuffer } from 'vs/base/common/buffer'; import { Event } from 'vs/base/common/event'; import { URI } from 'vs/base/common/uri'; import { MessageBoxOptions, MessageBoxReturnValue, MouseInputEvent, OpenDevToolsOptions, OpenDialogOptions, OpenDialogReturnValue, SaveDialogOptions, SaveDialogReturnValue } from 'vs/base/parts/sandbox/common/electronTypes'; @@ -121,8 +122,8 @@ export interface ICommonNativeHostService { writeClipboardText(text: string, type?: 'selection' | 'clipboard'): Promise; readClipboardFindText(): Promise; writeClipboardFindText(text: string): Promise; - writeClipboardBuffer(format: string, buffer: Uint8Array, type?: 'selection' | 'clipboard'): Promise; - readClipboardBuffer(format: string): Promise; + writeClipboardBuffer(format: string, buffer: VSBuffer, type?: 'selection' | 'clipboard'): Promise; + readClipboardBuffer(format: string): Promise; hasClipboard(format: string, type?: 'selection' | 'clipboard'): Promise; // macOS Touchbar diff --git a/src/vs/platform/native/electron-main/nativeHostMainService.ts b/src/vs/platform/native/electron-main/nativeHostMainService.ts index 639c6cfa063..3cfca907766 100644 --- a/src/vs/platform/native/electron-main/nativeHostMainService.ts +++ b/src/vs/platform/native/electron-main/nativeHostMainService.ts @@ -39,6 +39,7 @@ import { IColorScheme, IOpenedWindow, IOpenEmptyWindowOptions, IOpenWindowOption import { IWindowsMainService, OpenContext } from 'vs/platform/windows/electron-main/windows'; import { isWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; import { IWorkspacesManagementMainService } from 'vs/platform/workspaces/electron-main/workspacesManagementMainService'; +import { VSBuffer } from 'vs/base/common/buffer'; export interface INativeHostMainService extends AddFirstParameterToFunctions /* only methods, not events */, number | undefined /* window ID */> { } @@ -603,12 +604,12 @@ export class NativeHostMainService extends Disposable implements INativeHostMain return clipboard.writeFindText(text); } - async writeClipboardBuffer(windowId: number | undefined, format: string, buffer: Uint8Array, type?: 'selection' | 'clipboard'): Promise { - return clipboard.writeBuffer(format, Buffer.from(buffer), type); + async writeClipboardBuffer(windowId: number | undefined, format: string, buffer: VSBuffer, type?: 'selection' | 'clipboard'): Promise { + return clipboard.writeBuffer(format, Buffer.from(buffer.buffer), type); } - async readClipboardBuffer(windowId: number | undefined, format: string): Promise { - return clipboard.readBuffer(format); + async readClipboardBuffer(windowId: number | undefined, format: string): Promise { + return VSBuffer.wrap(clipboard.readBuffer(format)); } async hasClipboard(windowId: number | undefined, format: string, type?: 'selection' | 'clipboard'): Promise { diff --git a/src/vs/workbench/services/clipboard/electron-sandbox/clipboardService.ts b/src/vs/workbench/services/clipboard/electron-sandbox/clipboardService.ts index 8e3f25df564..326d09c3a37 100644 --- a/src/vs/workbench/services/clipboard/electron-sandbox/clipboardService.ts +++ b/src/vs/workbench/services/clipboard/electron-sandbox/clipboardService.ts @@ -56,11 +56,11 @@ export class NativeClipboardService implements IClipboardService { return this.nativeHostService.hasClipboard(NativeClipboardService.FILE_FORMAT); } - private resourcesToBuffer(resources: URI[]): Uint8Array { - return VSBuffer.fromString(resources.map(r => r.toString()).join('\n')).buffer; + private resourcesToBuffer(resources: URI[]): VSBuffer { + return VSBuffer.fromString(resources.map(r => r.toString()).join('\n')); } - private bufferToResources(buffer: Uint8Array): URI[] { + private bufferToResources(buffer: VSBuffer): URI[] { if (!buffer) { return []; } diff --git a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts index 3a35d0f4018..f4fce1346e2 100644 --- a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts @@ -54,6 +54,7 @@ import { joinPath } from 'vs/base/common/resources'; import { UserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfileService'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; +import { VSBuffer } from 'vs/base/common/buffer'; const args = parseArgs(process.argv, OPTIONS); @@ -272,8 +273,8 @@ export class TestNativeHostService implements INativeHostService { async writeClipboardText(text: string, type?: 'selection' | 'clipboard' | undefined): Promise { } async readClipboardFindText(): Promise { return ''; } async writeClipboardFindText(text: string): Promise { } - async writeClipboardBuffer(format: string, buffer: Uint8Array, type?: 'selection' | 'clipboard' | undefined): Promise { } - async readClipboardBuffer(format: string): Promise { return Uint8Array.from([]); } + async writeClipboardBuffer(format: string, buffer: VSBuffer, type?: 'selection' | 'clipboard' | undefined): Promise { } + async readClipboardBuffer(format: string): Promise { return VSBuffer.wrap(Uint8Array.from([])); } async hasClipboard(format: string, type?: 'selection' | 'clipboard' | undefined): Promise { return false; } async sendInputEvent(event: MouseInputEvent): Promise { } async windowsGetStringRegKey(hive: 'HKEY_CURRENT_USER' | 'HKEY_LOCAL_MACHINE' | 'HKEY_CLASSES_ROOT' | 'HKEY_USERS' | 'HKEY_CURRENT_CONFIG', path: string, name: string): Promise { return undefined; } -- cgit v1.2.3