Skip to content

Commit 3b7e216

Browse files
Adds command deep links (#3679)
Closes #3677 and #3678
1 parent 7f2b284 commit 3b7e216

File tree

3 files changed

+87
-3
lines changed

3 files changed

+87
-3
lines changed

docs/links.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ This document covers the various VSCode link formats that work with GitLens, alo
2222

2323
- [Login](#login 'Jump to Login')
2424

25+
### Other Links
26+
27+
- [Command](#command 'Jump to Command')
28+
2529
## Notation
2630

2731
The following are used in link notation in this document:
@@ -249,3 +253,27 @@ _vscode://eamodio.gitlens/login?code={code}(&state={state})(&context={context})_
249253
#### Example Usage
250254

251255
External sources, such as GitKraken web pages, can use these links internally to get you into GitLens and logged in to your GitKraken account.
256+
257+
## Other Links
258+
259+
### Command
260+
261+
#### Description
262+
263+
Used to run a GitLens command.
264+
265+
#### Format
266+
267+
_{prefix}/command/{command}_
268+
269+
#### References
270+
271+
- _{command}_ is the name of the command to run. Currently supported values include:
272+
273+
- _launchpad_ - Runs the `GitLens: Show Launchpad` command.
274+
275+
- _walkthrough_ - Runs the `GitLens: Open Walkthrough` command.
276+
277+
#### Example Usage
278+
279+
External sources, such as GitKraken web pages, can use these links to directly run a GitLens command - for example, to show the Launchpad.

src/uris/deepLinks/deepLink.ts

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Uri } from 'vscode';
2+
import { Commands } from '../../constants.commands';
23
import type { GitReference } from '../../git/models/reference';
34
import type { GitRemote } from '../../git/models/remote';
45
import type { Repository } from '../../git/models/repository';
@@ -8,6 +9,7 @@ export type UriTypes = 'link';
89

910
export enum DeepLinkType {
1011
Branch = 'b',
12+
Command = 'command',
1113
Commit = 'c',
1214
Comparison = 'compare',
1315
Draft = 'drafts',
@@ -17,6 +19,20 @@ export enum DeepLinkType {
1719
Workspace = 'workspace',
1820
}
1921

22+
export enum DeepLinkCommandType {
23+
Launchpad = 'launchpad',
24+
Walkthrough = 'walkthrough',
25+
}
26+
27+
export function isDeepLinkCommandType(type: string): type is DeepLinkCommandType {
28+
return Object.values(DeepLinkCommandType).includes(type as DeepLinkCommandType);
29+
}
30+
31+
export const DeepLinkCommandTypeToCommand = new Map<DeepLinkCommandType, Commands>([
32+
[DeepLinkCommandType.Launchpad, Commands.ShowLaunchpad],
33+
[DeepLinkCommandType.Walkthrough, Commands.OpenWalkthrough],
34+
]);
35+
2036
export enum DeepLinkActionType {
2137
Switch = 'switch',
2238
SwitchToPullRequest = 'switch-to-pr',
@@ -31,6 +47,8 @@ export function deepLinkTypeToString(type: DeepLinkType): string {
3147
switch (type) {
3248
case DeepLinkType.Branch:
3349
return 'Branch';
50+
case DeepLinkType.Command:
51+
return 'Command';
3452
case DeepLinkType.Commit:
3553
return 'Commit';
3654
case DeepLinkType.Comparison:
@@ -169,14 +187,20 @@ export function parseDeepLinkUri(uri: Uri): DeepLink | undefined {
169187
params: urlParams,
170188
};
171189
}
172-
173-
case DeepLinkType.Workspace:
190+
case DeepLinkType.Workspace: {
174191
return {
175192
type: DeepLinkType.Workspace,
176193
mainId: mainId,
177194
params: urlParams,
178195
};
179-
196+
}
197+
case DeepLinkType.Command: {
198+
return {
199+
type: DeepLinkType.Command,
200+
mainId: mainId,
201+
params: urlParams,
202+
};
203+
}
180204
default:
181205
return undefined;
182206
}
@@ -206,6 +230,7 @@ export const enum DeepLinkServiceState {
206230
OpenFile,
207231
OpenInspect,
208232
SwitchToRef,
233+
RunCommand,
209234
}
210235

211236
export const enum DeepLinkServiceAction {
@@ -215,6 +240,7 @@ export const enum DeepLinkServiceAction {
215240
DeepLinkResolved,
216241
DeepLinkStored,
217242
DeepLinkErrored,
243+
LinkIsCommandType,
218244
LinkIsRepoType,
219245
LinkIsDraftType,
220246
LinkIsWorkspaceType,
@@ -282,6 +308,7 @@ export const deepLinkStateTransitionTable: Record<string, Record<string, DeepLin
282308
[DeepLinkServiceState.TypeMatch]: {
283309
[DeepLinkServiceAction.DeepLinkErrored]: DeepLinkServiceState.Idle,
284310
[DeepLinkServiceAction.DeepLinkCancelled]: DeepLinkServiceState.Idle,
311+
[DeepLinkServiceAction.LinkIsCommandType]: DeepLinkServiceState.RunCommand,
285312
[DeepLinkServiceAction.LinkIsRepoType]: DeepLinkServiceState.RepoMatch,
286313
[DeepLinkServiceAction.LinkIsDraftType]: DeepLinkServiceState.OpenDraft,
287314
[DeepLinkServiceAction.LinkIsWorkspaceType]: DeepLinkServiceState.OpenWorkspace,
@@ -392,6 +419,11 @@ export const deepLinkStateTransitionTable: Record<string, Record<string, DeepLin
392419
[DeepLinkServiceAction.DeepLinkErrored]: DeepLinkServiceState.Idle,
393420
[DeepLinkServiceAction.DeepLinkCancelled]: DeepLinkServiceState.Idle,
394421
},
422+
[DeepLinkServiceState.RunCommand]: {
423+
[DeepLinkServiceAction.DeepLinkResolved]: DeepLinkServiceState.Idle,
424+
[DeepLinkServiceAction.DeepLinkErrored]: DeepLinkServiceState.Idle,
425+
[DeepLinkServiceAction.DeepLinkCancelled]: DeepLinkServiceState.Idle,
426+
},
395427
};
396428

397429
export interface DeepLinkProgress {
@@ -422,4 +454,5 @@ export const deepLinkStateToProgress: Record<string, DeepLinkProgress> = {
422454
[DeepLinkServiceState.OpenFile]: { message: 'Opening file...', increment: 90 },
423455
[DeepLinkServiceState.OpenInspect]: { message: 'Opening inspect...', increment: 90 },
424456
[DeepLinkServiceState.SwitchToRef]: { message: 'Switching to ref...', increment: 90 },
457+
[DeepLinkServiceState.RunCommand]: { message: 'Running command...', increment: 90 },
425458
};

src/uris/deepLinks/deepLinkService.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,14 @@ import type { DeepLink, DeepLinkProgress, DeepLinkRepoOpenType, DeepLinkServiceC
3333
import {
3434
AccountDeepLinkTypes,
3535
DeepLinkActionType,
36+
DeepLinkCommandTypeToCommand,
3637
DeepLinkServiceAction,
3738
DeepLinkServiceState,
3839
deepLinkStateToProgress,
3940
deepLinkStateTransitionTable,
4041
DeepLinkType,
4142
deepLinkTypeToString,
43+
isDeepLinkCommandType,
4244
PaidDeepLinkTypes,
4345
parseDeepLinkUri,
4446
} from './deepLink';
@@ -659,6 +661,9 @@ export class DeepLinkService implements Disposable {
659661
case DeepLinkType.Workspace:
660662
action = DeepLinkServiceAction.LinkIsWorkspaceType;
661663
break;
664+
case DeepLinkType.Command:
665+
action = DeepLinkServiceAction.LinkIsCommandType;
666+
break;
662667
default:
663668
action = DeepLinkServiceAction.LinkIsRepoType;
664669
break;
@@ -1384,6 +1389,24 @@ export class DeepLinkService implements Disposable {
13841389
action = DeepLinkServiceAction.DeepLinkResolved;
13851390
break;
13861391
}
1392+
case DeepLinkServiceState.RunCommand: {
1393+
if (mainId == null || !isDeepLinkCommandType(mainId)) {
1394+
action = DeepLinkServiceAction.DeepLinkErrored;
1395+
message = 'Invalid command type.';
1396+
break;
1397+
}
1398+
1399+
const command = DeepLinkCommandTypeToCommand.get(mainId);
1400+
if (command == null) {
1401+
action = DeepLinkServiceAction.DeepLinkErrored;
1402+
message = 'Invalid command.';
1403+
break;
1404+
}
1405+
1406+
await executeCommand(command, { source: 'deeplink' });
1407+
action = DeepLinkServiceAction.DeepLinkResolved;
1408+
break;
1409+
}
13871410
default: {
13881411
action = DeepLinkServiceAction.DeepLinkErrored;
13891412
message = 'Unknown state.';

0 commit comments

Comments
 (0)