doneOn => completionEvents
implement onLink, onEvent, onCommand, extensionInstalled, stepSelected ref #122570
This commit is contained in:
parent
1f2077f7e6
commit
4c63cdf2fa
5 changed files with 123 additions and 60 deletions
|
@ -117,9 +117,9 @@ export interface IWalkthroughStep {
|
|||
readonly id: string;
|
||||
readonly title: string;
|
||||
readonly description: string | undefined;
|
||||
readonly media:
|
||||
| { path: string | { dark: string, light: string, hc: string }, altText: string }
|
||||
| { path: string, },
|
||||
readonly media: { path: string | { dark: string, light: string, hc: string }, altText?: string }
|
||||
readonly completionEvents?: string[];
|
||||
/** @deprecated use `completionEvents: 'onCommand:...'` */
|
||||
readonly doneOn?: { command: string };
|
||||
readonly when?: string;
|
||||
}
|
||||
|
|
|
@ -460,6 +460,7 @@ export class GettingStartedPage extends EditorPane {
|
|||
stepElement.classList.add('expanded');
|
||||
stepElement.setAttribute('aria-expanded', 'true');
|
||||
this.buildMediaComponent(id);
|
||||
this.gettingStartedService.progressByEvent('stepSelected:' + id);
|
||||
} else {
|
||||
this.editorInput.selectedStep = undefined;
|
||||
}
|
||||
|
@ -488,7 +489,8 @@ export class GettingStartedPage extends EditorPane {
|
|||
const path = joinPath(base, src);
|
||||
const transformed = asWebviewUri({
|
||||
isExtensionDevelopmentDebug: this.environmentService.isExtensionDevelopment,
|
||||
...this.environmentService,
|
||||
webviewResourceRoot: this.environmentService.webviewResourceRoot,
|
||||
webviewCspSource: this.environmentService.webviewCspSource,
|
||||
remote: { authority: undefined },
|
||||
}, this.webviewID, path).toString();
|
||||
return `src="${transformed}"`;
|
||||
|
@ -889,6 +891,10 @@ export class GettingStartedPage extends EditorPane {
|
|||
}
|
||||
this.openerService.open(command, { allowCommands: true });
|
||||
|
||||
if (!isCommand && node.href.startsWith('https://')) {
|
||||
this.gettingStartedService.progressByEvent('onLink:' + node.href);
|
||||
}
|
||||
|
||||
}, null, this.detailsPageDisposables);
|
||||
|
||||
if (isCommand) {
|
||||
|
|
|
@ -50,7 +50,7 @@ export const walkthroughsExtensionPoint = ExtensionsRegistry.registerExtensionPo
|
|||
defaultSnippets: [{
|
||||
body: {
|
||||
'id': '$1', 'title': '$2', 'description': '$3',
|
||||
'doneOn': { 'command': '$5' },
|
||||
'completionEvents': ['$5'],
|
||||
'media': { 'path': '$6', 'type': '$7' }
|
||||
}
|
||||
}],
|
||||
|
@ -122,8 +122,38 @@ export const walkthroughsExtensionPoint = ExtensionsRegistry.registerExtensionPo
|
|||
}
|
||||
]
|
||||
},
|
||||
completionEvents: {
|
||||
description: localize('walkthroughs.steps.completionEvents', "Events that should trigger this step to become checked off. If empty or not defined, the step will check off when any of the step's buttons or links are clicked; if the step has no buttons or links it will check on when it is selected."),
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
defaultSnippets: [
|
||||
{
|
||||
label: 'onCommand',
|
||||
description: localize('walkthroughs.steps.completionEvents.onCommand', 'Check off step when a given command is executed anywhere in VS Code.'),
|
||||
body: 'onCommand:${1:commandId}'
|
||||
},
|
||||
{
|
||||
label: 'onLink',
|
||||
description: localize('walkthroughs.steps.completionEvents.onLink', 'Check off step when a given link is opened via a Getting Started step.'),
|
||||
body: 'onLink:${2:linkId}'
|
||||
},
|
||||
{
|
||||
label: 'extensionInstalled',
|
||||
description: localize('walkthroughs.steps.completionEvents.extensionInstalled', 'Check off step when an extension with the given id is installed. If the extension is already installed, the step will start off checked.'),
|
||||
body: 'extensionInstalled:${3:extensionId}'
|
||||
},
|
||||
{
|
||||
label: 'stepSelected',
|
||||
description: localize('walkthroughs.steps.completionEvents.stepSelected', 'Check off step as soon as it is selected.'),
|
||||
body: 'stepSelected'
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
doneOn: {
|
||||
description: localize('walkthroughs.steps.doneOn', "Signal to mark step as complete."),
|
||||
deprecationMessage: localize('walkthroughs.steps.doneOn.deprecation', "doneOn is deprecated, use completionEvents"),
|
||||
type: 'object',
|
||||
required: ['command'],
|
||||
defaultSnippets: [{ 'body': { command: '$1' } }],
|
||||
|
|
|
@ -28,10 +28,11 @@ import { GettingStartedInput } from 'vs/workbench/contrib/welcome/gettingStarted
|
|||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { GettingStartedPage } from 'vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { LinkedText, parseLinkedText } from 'vs/base/common/linkedText';
|
||||
import { ILink, LinkedText, parseLinkedText } from 'vs/base/common/linkedText';
|
||||
import { walkthroughsExtensionPoint } from 'vs/workbench/contrib/welcome/gettingStarted/browser/gettingStartedExtensionPoint';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { dirname } from 'vs/base/common/path';
|
||||
import { coalesce, flatten } from 'vs/base/common/arrays';
|
||||
|
||||
export const IGettingStartedService = createDecorator<IGettingStartedService>('gettingStartedService');
|
||||
|
||||
|
@ -52,7 +53,9 @@ export interface IGettingStartedStep {
|
|||
category: GettingStartedCategory | string
|
||||
when: ContextKeyExpression
|
||||
order: number
|
||||
doneOn: { commandExecuted: string, eventFired?: never } | { eventFired: string, commandExecuted?: never }
|
||||
/** @deprecated */
|
||||
doneOn?: { commandExecuted: string, eventFired?: never } | { eventFired: string, commandExecuted?: never }
|
||||
completionEvents: string[]
|
||||
media:
|
||||
| { type: 'image', path: { hc: URI, light: URI, dark: URI }, altText: string }
|
||||
| { type: 'markdown', path: URI, base: URI, root: URI }
|
||||
|
@ -151,8 +154,8 @@ export class GettingStartedService extends Disposable implements IGettingStarted
|
|||
private memento: Memento;
|
||||
private stepProgress: Record<string, StepProgress>;
|
||||
|
||||
private commandListeners = new Map<string, string[]>();
|
||||
private eventListeners = new Map<string, string[]>();
|
||||
private sessionEvents = new Set<string>();
|
||||
private completionListeners = new Map<string, Set<string>>();
|
||||
|
||||
private gettingStartedContributions = new Map<string, IGettingStartedCategory>();
|
||||
private steps = new Map<string, IGettingStartedStep>();
|
||||
|
@ -186,17 +189,22 @@ export class GettingStartedService extends Disposable implements IGettingStarted
|
|||
removed.forEach(e => this.unregisterExtensionContributions(e.description));
|
||||
});
|
||||
|
||||
this._register(this.commandService.onDidExecuteCommand(command => this.progressByCommand(command.commandId)));
|
||||
this._register(this.commandService.onDidExecuteCommand(command => this.progressByEvent(`onCommand:${command.commandId}`)));
|
||||
|
||||
this.extensionManagementService.getInstalled().then(installed => {
|
||||
installed.forEach(ext => this.progressByEvent(`extensionInstalled:${ext.identifier.id.toLowerCase()}`));
|
||||
});
|
||||
|
||||
this._register(this.extensionManagementService.onDidInstallExtension(async e => {
|
||||
if (await this.hostService.hadLastFocus()) {
|
||||
this.sessionInstalledExtensions.add(e.identifier.id);
|
||||
}
|
||||
this.progressByEvent(`extensionInstalled:${e.identifier.id.toLowerCase()}`);
|
||||
}));
|
||||
|
||||
if (userDataAutoSyncEnablementService.isEnabled()) { this.progressByEvent('sync-enabled'); }
|
||||
if (userDataAutoSyncEnablementService.isEnabled()) { this.progressByEvent('onEvent:sync-enabled'); }
|
||||
this._register(userDataAutoSyncEnablementService.onDidChangeEnablement(() => {
|
||||
if (userDataAutoSyncEnablementService.isEnabled()) { this.progressByEvent('sync-enabled'); }
|
||||
if (userDataAutoSyncEnablementService.isEnabled()) { this.progressByEvent('onEvent:sync-enabled'); }
|
||||
}));
|
||||
|
||||
startEntries.forEach(async (entry, index) => {
|
||||
|
@ -221,6 +229,7 @@ export class GettingStartedService extends Disposable implements IGettingStarted
|
|||
this.getStepOverrides(step, category.id);
|
||||
return ({
|
||||
...step,
|
||||
completionEvents: step.completionEvents ?? [],
|
||||
description: parseDescription(step.description),
|
||||
category: category.id,
|
||||
order: index,
|
||||
|
@ -389,9 +398,7 @@ export class GettingStartedService extends Disposable implements IGettingStarted
|
|||
|
||||
return ({
|
||||
description, media,
|
||||
doneOn: step.doneOn?.command
|
||||
? { commandExecuted: step.doneOn.command }
|
||||
: { eventFired: 'markDone:' + fullyQualifiedID },
|
||||
completionEvents: step.completionEvents?.filter(x => typeof x === 'string') ?? [],
|
||||
id: fullyQualifiedID,
|
||||
title: step.title,
|
||||
when: ContextKeyExpr.deserialize(step.when) ?? ContextKeyExpr.true(),
|
||||
|
@ -456,20 +463,69 @@ export class GettingStartedService extends Disposable implements IGettingStarted
|
|||
}
|
||||
|
||||
private registerDoneListeners(step: IGettingStartedStep) {
|
||||
if (step.doneOn.commandExecuted) {
|
||||
const existing = this.commandListeners.get(step.doneOn.commandExecuted);
|
||||
if (existing) { existing.push(step.id); }
|
||||
else {
|
||||
this.commandListeners.set(step.doneOn.commandExecuted, [step.id]);
|
||||
if (step.doneOn) {
|
||||
if (step.doneOn.commandExecuted) { step.completionEvents.push(`onCommand:${step.doneOn.commandExecuted}`); }
|
||||
if (step.doneOn.eventFired) { step.completionEvents.push(`onEvent:${step.doneOn.eventFired}`); }
|
||||
}
|
||||
|
||||
if (!step.completionEvents.length) {
|
||||
step.completionEvents = coalesce(flatten(
|
||||
step.description
|
||||
.filter(linkedText => linkedText.nodes.length === 1) // only buttons
|
||||
.map(linkedText =>
|
||||
linkedText.nodes
|
||||
.filter(((node): node is ILink => typeof node !== 'string'))
|
||||
.map(({ href }) => {
|
||||
if (href.startsWith('command:')) {
|
||||
return 'onCommand:' + href.slice('command:'.length, href.includes('?') ? href.indexOf('?') : undefined);
|
||||
}
|
||||
if (href.startsWith('https://')) {
|
||||
return 'onLink:' + href;
|
||||
}
|
||||
return undefined;
|
||||
}))));
|
||||
}
|
||||
|
||||
if (!step.completionEvents.length) {
|
||||
step.completionEvents.push('stepSelected');
|
||||
}
|
||||
|
||||
for (let event of step.completionEvents) {
|
||||
const [_, eventType, argument] = /^([^:]*):?(.*)$/.exec(event) ?? [];
|
||||
|
||||
if (!eventType) {
|
||||
console.error(`Unknown completionEvent ${event} when registering step ${step.id}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (eventType) {
|
||||
case 'onLink': case 'onEvent': break;
|
||||
case 'stepSelected':
|
||||
event = eventType + ':' + step.id;
|
||||
break;
|
||||
case 'onCommand':
|
||||
event = eventType + ':' + argument.replace(/^toSide:/, '');
|
||||
break;
|
||||
case 'extensionInstalled':
|
||||
event = eventType + ':' + argument.toLowerCase();
|
||||
break;
|
||||
default:
|
||||
console.error(`Unknown completionEvent ${event} when registering step ${step.id}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
this.registerCompletionListener(event, step);
|
||||
if (this.sessionEvents.has(event)) {
|
||||
this.progressStep(step.id);
|
||||
}
|
||||
}
|
||||
if (step.doneOn.eventFired) {
|
||||
const existing = this.eventListeners.get(step.doneOn.eventFired);
|
||||
if (existing) { existing.push(step.id); }
|
||||
else {
|
||||
this.eventListeners.set(step.doneOn.eventFired, [step.id]);
|
||||
}
|
||||
}
|
||||
|
||||
private registerCompletionListener(event: string, step: IGettingStartedStep) {
|
||||
if (!this.completionListeners.has(event)) {
|
||||
this.completionListeners.set(event, new Set());
|
||||
}
|
||||
this.completionListeners.get(event)?.add(step.id);
|
||||
}
|
||||
|
||||
getCategories(): IGettingStartedCategoryWithProgress[] {
|
||||
|
@ -539,14 +595,9 @@ export class GettingStartedService extends Disposable implements IGettingStarted
|
|||
this._onDidProgressStep.fire(this.getStepProgress(step));
|
||||
}
|
||||
|
||||
private progressByCommand(command: string) {
|
||||
const listening = this.commandListeners.get(command) ?? [];
|
||||
listening.forEach(id => this.progressStep(id));
|
||||
}
|
||||
|
||||
progressByEvent(event: string): void {
|
||||
const listening = this.eventListeners.get(event) ?? [];
|
||||
listening.forEach(id => this.progressStep(id));
|
||||
this.sessionEvents.add(event);
|
||||
this.completionListeners.get(event)?.forEach(id => this.progressStep(id));
|
||||
}
|
||||
|
||||
private registerStartEntry(categoryDescriptor: IGettingStartedStartEntryDescriptor): void {
|
||||
|
|
|
@ -19,7 +19,7 @@ export type BuiltinGettingStartedStep = {
|
|||
id: string
|
||||
title: string,
|
||||
description: string,
|
||||
doneOn: { commandExecuted: string, eventFired?: never } | { eventFired: string, commandExecuted?: never, }
|
||||
completionEvents?: string[]
|
||||
when?: string,
|
||||
media:
|
||||
| { type: 'image', path: string | { hc: string, light: string, dark: string }, altText: string }
|
||||
|
@ -130,28 +130,24 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
id: 'runProjectStep',
|
||||
title: localize('gettingStarted.runProject.title', "Build & run your app"),
|
||||
description: localize('gettingStarted.runProject.description', "Build, run & debug your code in the cloud, right from the browser.\n[Start Debugging](command:workbench.action.debug.selectandstart)"),
|
||||
doneOn: { commandExecuted: 'workbench.action.debug.selectandstart' },
|
||||
media: { type: 'image', altText: 'Node.js project running debug mode and paused.', path: 'runProject.png' },
|
||||
},
|
||||
{
|
||||
id: 'forwardPortsStep',
|
||||
title: localize('gettingStarted.forwardPorts.title', "Access your running application"),
|
||||
description: localize('gettingStarted.forwardPorts.description', "Ports running within your codespace are automatically forwarded to the web, so you can open them in your browser.\n[Show Ports Panel](command:~remote.forwardedPorts.focus)"),
|
||||
doneOn: { commandExecuted: '~remote.forwardedPorts.focus' },
|
||||
media: { type: 'image', altText: 'Ports panel.', path: 'forwardPorts.png' },
|
||||
},
|
||||
{
|
||||
id: 'pullRequests',
|
||||
title: localize('gettingStarted.pullRequests.title', "Pull requests at your fingertips"),
|
||||
description: localize('gettingStarted.pullRequests.description', "Bring your GitHub workflow closer to your code, so you can review pull requests, add comments, merge branches, and more.\n[Open GitHub View](command:workbench.view.extension.github-pull-requests)"),
|
||||
doneOn: { commandExecuted: 'workbench.view.extension.github-pull-requests' },
|
||||
media: { type: 'image', altText: 'Preview for reviewing a pull request.', path: 'pullRequests.png' },
|
||||
},
|
||||
{
|
||||
id: 'remoteTerminal',
|
||||
title: localize('gettingStarted.remoteTerminal.title', "Run tasks in the integrated terminal"),
|
||||
description: localize('gettingStarted.remoteTerminal.description', "Perform quick command-line tasks using the built-in terminal.\n[Focus Terminal](command:terminal.focus)"),
|
||||
doneOn: { commandExecuted: 'terminal.focus' },
|
||||
media: { type: 'image', altText: 'Remote terminal showing npm commands.', path: 'remoteTerminal.png' },
|
||||
},
|
||||
{
|
||||
|
@ -159,7 +155,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
title: localize('gettingStarted.openVSC.title', "Develop remotely in VS Code"),
|
||||
description: localize('gettingStarted.openVSC.description', "Access the power of your cloud development environment from your local VS Code. Set it up by installing the GitHub Codespaces extension and connecting your GitHub account.\n[Open in VS Code](command:github.codespaces.openInStable)"),
|
||||
when: 'isWeb',
|
||||
doneOn: { commandExecuted: 'github.codespaces.openInStable' },
|
||||
media: {
|
||||
type: 'image', altText: 'Preview of the Open in VS Code command.', path: {
|
||||
dark: 'dark/openVSC.png',
|
||||
|
@ -185,14 +180,12 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
id: 'pickColorTheme',
|
||||
title: localize('gettingStarted.pickColor.title', "Customize the look with themes"),
|
||||
description: localize('gettingStarted.pickColor.description', "Pick a color theme to match your taste and mood while coding.\n[Pick a Theme](command:workbench.action.selectTheme)"),
|
||||
doneOn: { commandExecuted: 'workbench.action.selectTheme' },
|
||||
media: { type: 'image', altText: 'Color theme preview for dark and light theme.', path: 'colorTheme.png', }
|
||||
},
|
||||
{
|
||||
id: 'findLanguageExtensions',
|
||||
title: localize('gettingStarted.findLanguageExts.title', "Code in any language"),
|
||||
description: localize('gettingStarted.findLanguageExts.description', "VS Code supports over 50+ programming languages. While many are built-in, others can be easily installed as extensions in one click.\n[Browse Language Extensions](command:workbench.extensions.action.showLanguageExtensions)"),
|
||||
doneOn: { commandExecuted: 'workbench.extensions.action.showLanguageExtensions' },
|
||||
media: {
|
||||
type: 'image', altText: 'Language extensions', path: {
|
||||
dark: 'dark/languageExtensions.png',
|
||||
|
@ -205,7 +198,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
id: 'keymaps',
|
||||
title: localize('gettingStarted.keymaps.title', "Switch from other editors"),
|
||||
description: localize('gettingStarted.keymaps.description', "Bring your favorite keyboard shortcuts from other editors into VS Code with keymaps.\n[Browse Keymap Extensions](command:workbench.extensions.action.showRecommendedKeymapExtensions)"),
|
||||
doneOn: { commandExecuted: 'workbench.extensions.action.showRecommendedKeymapExtensions' },
|
||||
media: {
|
||||
type: 'image', altText: 'List of keymap extensions.', path: {
|
||||
dark: 'dark/keymaps.png',
|
||||
|
@ -219,7 +211,7 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
title: localize('gettingStarted.settingsSync.title', "Sync your favorite setup"),
|
||||
description: localize('gettingStarted.settingsSync.description', "Never lose the perfect VS Code setup! Settings Sync will back up and share settings, keybindings & extensions across several VS Code instances.\n[Enable Settings Sync](command:workbench.userDataSync.actions.turnOn)"),
|
||||
when: 'syncStatus != uninitialized',
|
||||
doneOn: { eventFired: 'sync-enabled' },
|
||||
completionEvents: ['onEvent:sync-enabled'],
|
||||
media: {
|
||||
type: 'image', altText: 'The "Turn on Sync" entry in the settings gear menu.', path: {
|
||||
dark: 'dark/settingsSync.png',
|
||||
|
@ -233,7 +225,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
title: localize('gettingStarted.setup.OpenFolder.title', "Open your project folder"),
|
||||
description: localize('gettingStarted.setup.OpenFolder.description', "Open a project folder to start coding!\n[Pick a Folder](command:workbench.action.files.openFileFolder)"),
|
||||
when: 'isMac && workspaceFolderCount == 0',
|
||||
doneOn: { commandExecuted: 'workbench.action.files.openFileFolder' },
|
||||
media: {
|
||||
type: 'image', altText: 'Explorer view showing buttons for opening folder and cloning repository.', path: {
|
||||
dark: 'dark/openFolder.png',
|
||||
|
@ -247,7 +238,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
title: localize('gettingStarted.setup.OpenFolder.title', "Open your project folder"),
|
||||
description: localize('gettingStarted.setup.OpenFolder.description2', "Open a project folder to start coding!\n[Pick a Folder](command:workbench.action.files.openFolder)"),
|
||||
when: '!isMac && workspaceFolderCount == 0',
|
||||
doneOn: { commandExecuted: 'workbench.action.files.openFolder' },
|
||||
media: {
|
||||
type: 'image', altText: 'Explorer view showing buttons for opening folder and cloning repository.', path: {
|
||||
dark: 'dark/openFolder.png',
|
||||
|
@ -261,7 +251,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
title: localize('gettingStarted.quickOpen.title', "Quick open files"),
|
||||
description: localize('gettingStarted.quickOpen.description', "Navigate between files in an instant with one keystroke. Tip: Open multiple files by pressing the right arrow key.\n[Quick Open a File](command:toSide:workbench.action.quickOpen)"),
|
||||
when: 'workspaceFolderCount != 0',
|
||||
doneOn: { commandExecuted: 'workbench.action.quickOpen' },
|
||||
media: {
|
||||
type: 'image', altText: 'Go to file in quick search.', path: {
|
||||
dark: 'dark/openFolder.png',
|
||||
|
@ -286,7 +275,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
id: 'commandPaletteTask',
|
||||
title: localize('gettingStarted.commandPalette.title', "Find & run commands"),
|
||||
description: localize('gettingStarted.commandPalette.description', "The easiest way to find everything VS Code can do. If you're ever looking for a feature or a shortcut, check here first!\n[Open Command Palette](command:workbench.action.showCommands)"),
|
||||
doneOn: { commandExecuted: 'workbench.action.showCommands' },
|
||||
media: {
|
||||
type: 'image', altText: 'Command Palette overlay for searching and executing commands.', path: {
|
||||
dark: 'dark/commandPalette.png',
|
||||
|
@ -300,7 +288,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
title: localize('gettingStarted.terminal.title', "Convenient built-in terminal"),
|
||||
description: localize('gettingStarted.terminal.description', "Quickly run shell commands and monitor build output, right next to your code.\n[Show Terminal Panel](command:workbench.action.terminal.toggleTerminal)"),
|
||||
when: 'remoteName != codespaces && !terminalIsOpen',
|
||||
doneOn: { commandExecuted: 'workbench.action.terminal.toggleTerminal' },
|
||||
media: {
|
||||
type: 'image', altText: 'Integrated terminal running a few npm commands', path: {
|
||||
dark: 'dark/terminal.png',
|
||||
|
@ -313,7 +300,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
id: 'extensions',
|
||||
title: localize('gettingStarted.extensions.title', "Limitless extensibility"),
|
||||
description: localize('gettingStarted.extensions.description', "Extensions are VS Code's power-ups. They range from handy productivity hacks, expanding out-of-the-box features, to adding completely new capabilities.\n[Browse Recommended Extensions](command:workbench.extensions.action.showRecommendedExtensions)"),
|
||||
doneOn: { commandExecuted: 'workbench.extensions.action.showRecommendedExtensions' },
|
||||
media: {
|
||||
type: 'image', altText: 'VS Code extension marketplace with featured language extensions', path: {
|
||||
dark: 'dark/extensions.png',
|
||||
|
@ -326,7 +312,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
id: 'settings',
|
||||
title: localize('gettingStarted.settings.title', "Tune your settings"),
|
||||
description: localize('gettingStarted.settings.description', "Tweak every aspect of VS Code and your extensions to your liking. Commonly used settings are listed first to get you started.\n[Tweak my Settings](command:toSide:workbench.action.openSettings)"),
|
||||
doneOn: { commandExecuted: 'workbench.action.openSettings' },
|
||||
media: {
|
||||
type: 'image', altText: 'VS Code Settings', path: {
|
||||
dark: 'dark/settings.png',
|
||||
|
@ -339,7 +324,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
id: 'videoTutorial',
|
||||
title: localize('gettingStarted.videoTutorial.title', "Lean back and learn"),
|
||||
description: localize('gettingStarted.videoTutorial.description', "Watch the first in a series of short & practical video tutorials for VS Code's key features.\n[Watch Tutorial](https://aka.ms/vscode-getting-started-video)"),
|
||||
doneOn: { eventFired: 'linkOpened:https://aka.ms/vscode-getting-started-video' },
|
||||
media: { type: 'image', altText: 'VS Code Settings', path: 'tutorialVideo.png' },
|
||||
}
|
||||
]
|
||||
|
@ -358,7 +342,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
id: 'playground',
|
||||
title: localize('gettingStarted.playground.title', "Redefine your editing skills"),
|
||||
description: localize('gettingStarted.playground.description', "Want to code faster and smarter? Practice powerful code editing features in the interactive playground.\n[Open Interactive Playground](command:toSide:workbench.action.showInteractivePlayground)"),
|
||||
doneOn: { commandExecuted: 'workbench.action.showInteractivePlayground' },
|
||||
media: {
|
||||
type: 'image', altText: 'Interactive Playground.', path: {
|
||||
dark: 'dark/playground.png',
|
||||
|
@ -371,7 +354,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
id: 'splitview',
|
||||
title: localize('gettingStarted.splitview.title', "Side by side editing"),
|
||||
description: localize('gettingStarted.splitview.description', "Make the most of your screen estate by opening files side by side, vertically and horizontally.\n[Split Editor](command:workbench.action.splitEditor)"),
|
||||
doneOn: { commandExecuted: 'workbench.action.splitEditor' },
|
||||
media: {
|
||||
type: 'image', altText: 'Multiple editors in split view.', path: {
|
||||
dark: 'dark/splitview.png',
|
||||
|
@ -385,7 +367,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
title: localize('gettingStarted.debug.title', "Watch your code in action"),
|
||||
description: localize('gettingStarted.debug.description', "Accelerate your edit, build, test, and debug loop by setting up a launch configuration.\n[Run your Project](command:workbench.action.debug.selectandstart)"),
|
||||
when: 'workspaceFolderCount != 0',
|
||||
doneOn: { commandExecuted: 'workbench.action.debug.selectandstart' },
|
||||
media: {
|
||||
type: 'image', altText: 'Run and debug view.', path: {
|
||||
dark: 'dark/debug.png',
|
||||
|
@ -399,7 +380,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
title: localize('gettingStarted.scm.title', "Track your code with Git"),
|
||||
description: localize('gettingStarted.scmClone.description', "Set up the built-in version control for your project to track your changes and collaborate with others.\n[Clone Repository](command:git.clone)"),
|
||||
when: 'config.git.enabled && !git.missing && workspaceFolderCount == 0',
|
||||
doneOn: { commandExecuted: 'git.clone' },
|
||||
media: {
|
||||
type: 'image', altText: 'Source Control view.', path: {
|
||||
dark: 'dark/scm.png',
|
||||
|
@ -413,7 +393,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
title: localize('gettingStarted.scm.title', "Track your code with Git"),
|
||||
description: localize('gettingStarted.scmSetup.description', "Set up the built-in version control for your project to track your changes and collaborate with others.\n[Initialize Git Repository](command:git.init)"),
|
||||
when: 'config.git.enabled && !git.missing && workspaceFolderCount != 0 && gitOpenRepositoryCount == 0',
|
||||
doneOn: { commandExecuted: 'git.init' },
|
||||
media: {
|
||||
type: 'image', altText: 'Source Control view.', path: {
|
||||
dark: 'dark/scm.png',
|
||||
|
@ -425,9 +404,8 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
{
|
||||
id: 'scm',
|
||||
title: localize('gettingStarted.scm.title', "Track your code with Git"),
|
||||
description: localize('gettingStarted.scm.description', "No more looking up Git commands! Git and GitHub workflows are seamlessly integrated.[Open Source Control](command:workbench.view.scm)"),
|
||||
description: localize('gettingStarted.scm.description', "No more looking up Git commands! Git and GitHub workflows are seamlessly integrated.\n[Open Source Control](command:workbench.view.scm)"),
|
||||
when: 'config.git.enabled && !git.missing && workspaceFolderCount != 0 && gitOpenRepositoryCount != 0 && activeViewlet != \'workbench.view.scm\'',
|
||||
doneOn: { commandExecuted: 'workbench.view.scm.focus' },
|
||||
media: {
|
||||
type: 'image', altText: 'Source Control view.', path: {
|
||||
dark: 'dark/scm.png',
|
||||
|
@ -441,7 +419,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
title: localize('gettingStarted.tasks.title', "Automate your project tasks"),
|
||||
when: 'workspaceFolderCount != 0',
|
||||
description: localize('gettingStarted.tasks.description', "Create tasks for your common workflows and enjoy the integrated experience of running scripts and automatically checking results.\n[Run Auto-detected Tasks](command:workbench.action.tasks.runTask)"),
|
||||
doneOn: { commandExecuted: 'workbench.action.tasks.runTask' },
|
||||
media: {
|
||||
type: 'image', altText: 'Task runner.', path: {
|
||||
dark: 'dark/tasks.png',
|
||||
|
@ -454,7 +431,6 @@ export const walkthroughs: GettingStartedWalkthroughContent = [
|
|||
id: 'shortcuts',
|
||||
title: localize('gettingStarted.shortcuts.title', "Customize your shortcuts"),
|
||||
description: localize('gettingStarted.shortcuts.description', "Once you have discovered your favorite commands, create custom keyboard shortcuts for instant access.\n[Keyboard Shortcuts](command:toSide:workbench.action.openGlobalKeybindings)"),
|
||||
doneOn: { commandExecuted: 'workbench.action.openGlobalKeybindings' },
|
||||
media: {
|
||||
type: 'image', altText: 'Interactive shortcuts.', path: {
|
||||
dark: 'dark/shortcuts.png',
|
||||
|
|
Loading…
Reference in a new issue