Skip to content

Commit

Permalink
Adds ref range support to terminal links
Browse files Browse the repository at this point in the history
Adds git command support to terminal links
  • Loading branch information
eamodio committed Nov 13, 2020
1 parent b0fab09 commit 90880e4
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/commands/git/cherry-pick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ export class CherryPickGitCommand extends QuickCommand<State> {
state.repo.cherryPick(...state.flags, ...state.references.map(c => c.ref).reverse());
}

isMatch(name: string) {
return super.isMatch(name) || name === 'cherry';
isFuzzyMatch(name: string) {
return super.isFuzzyMatch(name) || name === 'cherry';
}

protected async *steps(state: PartialStepState<State>): StepGenerator {
Expand Down
4 changes: 2 additions & 2 deletions src/commands/git/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ export class LogGitCommand extends QuickCommand<State> {
return false;
}

isMatch(name: string) {
return super.isMatch(name) || name === 'history';
isFuzzyMatch(name: string) {
return super.isFuzzyMatch(name) || name === 'log';
}

protected async *steps(state: PartialStepState<State>): StepGenerator {
Expand Down
10 changes: 7 additions & 3 deletions src/commands/git/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ interface State extends Required<SearchPattern> {
}

export interface SearchGitCommandArgs {
readonly command: 'search';
readonly command: 'search' | 'grep';
prefillOnly?: boolean;
state?: Partial<State>;
}
Expand Down Expand Up @@ -81,8 +81,12 @@ export class SearchGitCommand extends QuickCommand<State> {
return false;
}

isMatch(name: string) {
return super.isMatch(name) || name === 'grep';
isMatch(key: string) {
return super.isMatch(key) || key === 'grep';
}

isFuzzyMatch(name: string) {
return super.isFuzzyMatch(name) || name === 'grep';
}

protected async *steps(state: PartialStepState<State>): StepGenerator {
Expand Down
10 changes: 7 additions & 3 deletions src/commands/git/switch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ interface State {
type SwitchStepState<T extends State = State> = ExcludeSome<StepState<T>, 'repos', string | string[] | Repository>;

export interface SwitchGitCommandArgs {
readonly command: 'switch';
readonly command: 'switch' | 'checkout';
confirm?: boolean;
state?: Partial<State>;
}
Expand Down Expand Up @@ -78,8 +78,12 @@ export class SwitchGitCommand extends QuickCommand<State> {
));
}

isMatch(name: string) {
return super.isMatch(name) || name === 'checkout';
isMatch(key: string) {
return super.isMatch(key) || key === 'checkout';
}

isFuzzyMatch(name: string) {
return super.isFuzzyMatch(name) || name === 'checkout';
}

protected async *steps(state: PartialStepState<State>): StepGenerator {
Expand Down
8 changes: 4 additions & 4 deletions src/commands/gitCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -715,11 +715,11 @@ class PickCommandStep implements QuickPickStep {
new RebaseGitCommand(args?.command === 'rebase' ? args : undefined),
new ResetGitCommand(args?.command === 'reset' ? args : undefined),
new RevertGitCommand(args?.command === 'revert' ? args : undefined),
new SearchGitCommand(args?.command === 'search' ? args : undefined),
new SearchGitCommand(args?.command === 'search' || args?.command === 'grep' ? args : undefined),
new ShowGitCommand(args?.command === 'show' ? args : undefined),
new StashGitCommand(args?.command === 'stash' ? args : undefined),
new StatusGitCommand(args?.command === 'status' ? args : undefined),
new SwitchGitCommand(args?.command === 'switch' ? args : undefined),
new SwitchGitCommand(args?.command === 'switch' || args?.command === 'checkout' ? args : undefined),
new TagGitCommand(args?.command === 'tag' ? args : undefined),
];

Expand All @@ -734,10 +734,10 @@ class PickCommandStep implements QuickPickStep {
find(commandName: string, fuzzy: boolean = false) {
if (fuzzy) {
const cmd = commandName.toLowerCase();
return this.items.find(c => c.isMatch(cmd)) ?? this.hiddenItems.find(c => c.isMatch(cmd));
return this.items.find(c => c.isFuzzyMatch(cmd)) ?? this.hiddenItems.find(c => c.isFuzzyMatch(cmd));
}

return this.items.find(c => c.key === commandName) ?? this.hiddenItems.find(c => c.key === commandName);
return this.items.find(c => c.isMatch(commandName)) ?? this.hiddenItems.find(c => c.isMatch(commandName));
}

setCommand(command: QuickCommand | undefined, via: 'menu' | 'command'): void {
Expand Down
6 changes: 5 additions & 1 deletion src/commands/quickCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,11 @@ export abstract class QuickCommand<State = any> implements QuickPickItem {
: !Container.config.gitCommands.skipConfirmations.includes(this.skipConfirmKey);
}

isMatch(name: string) {
isMatch(key: string) {
return this.key === key;
}

isFuzzyMatch(name: string) {
return this.label === name;
}

Expand Down
58 changes: 53 additions & 5 deletions src/terminal/linkProvider.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
'use strict';
import { commands, Disposable, TerminalLink, TerminalLinkContext, TerminalLinkProvider, window } from 'vscode';
import { Commands, ShowQuickBranchHistoryCommandArgs, ShowQuickCommitCommandArgs } from '../commands';
import {
Commands,
GitCommandsCommandArgs,
ShowQuickBranchHistoryCommandArgs,
ShowQuickCommitCommandArgs,
} from '../commands';
import { Container } from '../container';
import { GitReference } from '../git/git';

const commandsRegexShared = /\b(g(?:it)?\b\s*)\b(branch|checkout|cherry-pick|fetch|grep|log|merge|pull|push|rebase|reset|revert|show|stash|status|tag)\b/gi;
const refRegexShared = /\b((?!\/)(?!\S*\/\/)(?!\S*@\{)(?!@$)(?!\S*\\)[^\000-\037\177 ~^:?*[]+(?<!\.lock)(?<!\/)(?<!\.))\b/gi;
const rangeRegex = /^[0-9a-f]{7,40}\.\.\.?[0-9a-f]{7,40}$/;
const shaRegex = /^[0-9a-f]{7,40}$/;
const refRegex = /\b((?!\S*\/\.)(?!\S*\.\.)(?!\/)(?!\S*\/\/)(?!\S*@\{)(?!@$)(?!\S*\\)[^\000-\037\177 ~^:?*[]+(?<!\.lock)(?<!\/)(?<!\.))\b/gi;

interface GitTerminalLink<T = object> extends TerminalLink {
command: {
Expand Down Expand Up @@ -35,11 +43,30 @@ export class GitTerminalLinkProvider implements Disposable, TerminalLinkProvider
const branchesAndTags = await Container.git.getBranchesAndOrTags(repoPath);

// Don't use the shared regex instance directly, because we can be called reentrantly (because of the awaits below)
const regex = new RegExp(refRegex, refRegex.flags);
const refRegex = new RegExp(refRegexShared, refRegexShared.flags);
const commandsRegex = new RegExp(commandsRegexShared, commandsRegexShared.flags);

let match;
do {
match = regex.exec(context.line);
match = commandsRegex.exec(context.line);
if (match != null) {
const [_, git, command] = match;

const link: GitTerminalLink<GitCommandsCommandArgs> = {
startIndex: match.index + git.length,
length: command.length,
tooltip: 'Open in Git Command Palette',
command: {
command: Commands.GitCommands,
args: {
command: command as GitCommandsCommandArgs['command'],
},
},
};
links.push(link);
}

match = refRegex.exec(context.line);
if (match == null) break;

const [_, ref] = match;
Expand Down Expand Up @@ -82,7 +109,28 @@ export class GitTerminalLinkProvider implements Disposable, TerminalLinkProvider
continue;
}

if (!shaRegex.test(ref)) continue;
if (!shaRegex.test(ref)) {
if (rangeRegex.test(ref)) {
const link: GitTerminalLink<GitCommandsCommandArgs> = {
startIndex: match.index,
length: ref.length,
tooltip: 'Show Commits',
command: {
command: Commands.GitCommands,
args: {
command: 'log',
state: {
repo: repoPath,
reference: GitReference.create(ref, repoPath, { refType: 'revision' }),
},
},
},
};
links.push(link);
}

continue;
}

if (await Container.git.validateReference(repoPath, ref)) {
const link: GitTerminalLink<ShowQuickCommitCommandArgs> = {
Expand Down

0 comments on commit 90880e4

Please sign in to comment.