Browse Source

Adds terminal links

main
Eric Amodio 4 years ago
parent
commit
99a32c07d2
4 changed files with 156 additions and 20 deletions
  1. +21
    -16
      src/commands/showQuickBranchHistory.ts
  2. +23
    -4
      src/commands/showQuickCommit.ts
  3. +2
    -0
      src/container.ts
  4. +110
    -0
      src/terminal/linkProvider.ts

+ 21
- 16
src/commands/showQuickBranchHistory.ts View File

@ -6,7 +6,9 @@ import { executeGitCommand } from './gitCommands';
import { GitUri } from '../git/gitUri'; import { GitUri } from '../git/gitUri';
export interface ShowQuickBranchHistoryCommandArgs { export interface ShowQuickBranchHistoryCommandArgs {
repoPath?: string;
branch?: string; branch?: string;
tag?: string;
} }
@command() @command()
@ -29,24 +31,27 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand {
const gitUri = uri && (await GitUri.fromUri(uri)); const gitUri = uri && (await GitUri.fromUri(uri));
const repoPath = args?.repoPath ?? gitUri?.repoPath;
let ref: GitReference | 'HEAD' | undefined;
if (repoPath != null) {
if (args?.branch != null) {
ref =
args.branch === 'HEAD'
? 'HEAD'
: GitReference.create(args.branch, repoPath, {
refType: 'branch',
name: args.branch,
remote: false,
});
} else if (args?.tag != null) {
ref = GitReference.create(args.tag, repoPath, { refType: 'tag', name: args.tag });
}
}
return executeGitCommand({ return executeGitCommand({
command: 'log', command: 'log',
state:
gitUri?.repoPath != null
? {
repo: gitUri.repoPath,
reference:
args?.branch != null
? args.branch === 'HEAD'
? 'HEAD'
: GitReference.create(args.branch, gitUri.repoPath, {
refType: 'branch',
name: args.branch,
remote: false,
})
: undefined,
}
: {},
state: repoPath != null ? { repo: repoPath, reference: ref } : {},
}); });
} }
} }

+ 23
- 4
src/commands/showQuickCommit.ts View File

@ -55,12 +55,31 @@ export class ShowQuickCommitCommand extends ActiveEditorCachedCommand {
} }
async execute(editor?: TextEditor, uri?: Uri, args?: ShowQuickCommitCommandArgs) { async execute(editor?: TextEditor, uri?: Uri, args?: ShowQuickCommitCommandArgs) {
uri = getCommandUri(uri, editor);
if (uri == null && args?.repoPath == null) return;
let gitUri;
let repoPath;
if (args?.commit == null) {
if (args?.repoPath != null && args.sha != null) {
repoPath = args.repoPath;
gitUri = GitUri.fromRepoPath(repoPath);
} else {
uri = getCommandUri(uri, editor);
if (uri == null) return;
gitUri = await GitUri.fromUri(uri);
repoPath = gitUri.repoPath;
}
} else {
if (args.sha == null) {
args.sha = args.commit.sha;
}
const gitUri = uri != null ? await GitUri.fromUri(uri) : GitUri.fromRepoPath(args!.repoPath!);
gitUri = args.commit.toGitUri();
repoPath = args.commit.repoPath;
let repoPath = gitUri.repoPath;
if (uri == null) {
uri = args.commit.uri;
}
}
args = { ...args }; args = { ...args };
if (args.sha == null) { if (args.sha == null) {

+ 2
- 0
src/container.ts View File

@ -14,6 +14,7 @@ import { LineHoverController } from './hovers/lineHoverController';
import { Keyboard } from './keyboard'; import { Keyboard } from './keyboard';
import { Logger } from './logger'; import { Logger } from './logger';
import { StatusBarController } from './statusbar/statusBarController'; import { StatusBarController } from './statusbar/statusBarController';
import { GitTerminalLinkProvider } from './terminal/linkProvider';
import { GitDocumentTracker } from './trackers/gitDocumentTracker'; import { GitDocumentTracker } from './trackers/gitDocumentTracker';
import { GitLineTracker } from './trackers/gitLineTracker'; import { GitLineTracker } from './trackers/gitLineTracker';
import { CompareView } from './views/compareView'; import { CompareView } from './views/compareView';
@ -111,6 +112,7 @@ export class Container {
} }
context.subscriptions.push(new RebaseEditorProvider()); context.subscriptions.push(new RebaseEditorProvider());
context.subscriptions.push(new GitTerminalLinkProvider());
context.subscriptions.push(new GitFileSystemProvider()); context.subscriptions.push(new GitFileSystemProvider());
context.subscriptions.push(configuration.onWillChange(this.onConfigurationChanging, this)); context.subscriptions.push(configuration.onWillChange(this.onConfigurationChanging, this));

+ 110
- 0
src/terminal/linkProvider.ts View File

@ -0,0 +1,110 @@
'use strict';
import { commands, Disposable, TerminalLink, TerminalLinkContext, TerminalLinkProvider, window } from 'vscode';
import { Commands, ShowQuickBranchHistoryCommandArgs, ShowQuickCommitCommandArgs } from '../commands';
import { Container } from '../container';
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: {
command: Commands;
args: T;
};
}
export class GitTerminalLinkProvider implements Disposable, TerminalLinkProvider<GitTerminalLink> {
private disposable: Disposable;
constructor() {
this.disposable = window.registerTerminalLinkProvider(this);
}
dispose() {
this.disposable.dispose();
}
async provideTerminalLinks(context: TerminalLinkContext): Promise<GitTerminalLink[]> {
if (context.line.trim().length === 0) return [];
const repoPath = Container.git.getHighlanderRepoPath();
if (repoPath == null) return [];
const links: GitTerminalLink[] = [];
const branchesAndTags = await Container.git.getBranchesAndOrTags(repoPath, { include: 'all' });
// Don't use the shared regex instance directly, because we can be called reentrantly (because of the awaits below)
const regex = new RegExp(refRegex, 'gi');
let match;
do {
match = regex.exec(context.line);
if (match == null) break;
const [_, ref] = match;
if (ref.toUpperCase() === 'HEAD') {
const link: GitTerminalLink<ShowQuickBranchHistoryCommandArgs> = {
startIndex: match.index,
length: ref.length,
tooltip: 'Show HEAD',
command: {
command: Commands.ShowQuickBranchHistory,
args: {
branch: 'HEAD',
repoPath: repoPath,
},
},
};
links.push(link);
continue;
}
const branchOrTag = branchesAndTags?.find(r => r.name === ref);
if (branchOrTag != null) {
const link: GitTerminalLink<ShowQuickBranchHistoryCommandArgs> = {
startIndex: match.index,
length: ref.length,
tooltip: branchOrTag.refType === 'branch' ? 'Show Branch' : 'Show Tag',
command: {
command: Commands.ShowQuickBranchHistory,
args: {
branch: branchOrTag.refType === 'branch' ? branchOrTag.name : undefined,
tag: branchOrTag.refType === 'tag' ? branchOrTag.name : undefined,
repoPath: repoPath,
},
},
};
links.push(link);
continue;
}
if (!shaRegex.test(ref)) continue;
if (await Container.git.validateReference(repoPath, ref)) {
const link: GitTerminalLink<ShowQuickCommitCommandArgs> = {
startIndex: match.index,
length: ref.length,
tooltip: 'Show Commit',
command: {
command: Commands.ShowQuickCommit,
args: {
repoPath: repoPath,
sha: ref,
},
},
};
links.push(link);
}
} while (true);
return links;
}
handleTerminalLink(link: GitTerminalLink): void {
void commands.executeCommand(link.command.command, link.command.args);
}
}

Loading…
Cancel
Save