Adds commit navigation in quick pick lists via alt+, alt+.

Reworks keyboard context
This commit is contained in:
Eric Amodio
2017-03-11 04:14:47 -05:00
parent f499bffbc6
commit a2a3f1a81e
13 changed files with 179 additions and 79 deletions

View File

@@ -341,16 +341,6 @@
} }
}, },
"commands": [ "commands": [
{
"command": "gitlens.key.left",
"title": "Left KeyPress",
"category": "GitLens:KeyPress"
},
{
"command": "gitlens.key.right",
"title": "Right KeyPress",
"category": "GitLens:KeyPress"
},
{ {
"command": "gitlens.diffDirectory", "command": "gitlens.diffDirectory",
"title": "Directory Compare", "title": "Directory Compare",
@@ -458,14 +448,6 @@
], ],
"menus": { "menus": {
"commandPalette": [ "commandPalette": [
{
"command": "gitlens.key.left",
"when": "false"
},
{
"command": "gitlens.key.right",
"when": "false"
},
{ {
"command": "gitlens.diffDirectory", "command": "gitlens.diffDirectory",
"when": "gitlens:enabled" "when": "gitlens:enabled"
@@ -661,12 +643,22 @@
{ {
"command": "gitlens.key.left", "command": "gitlens.key.left",
"key": "alt+left", "key": "alt+left",
"when": "gitlens:key" "when": "gitlens:key:left"
}, },
{ {
"command": "gitlens.key.right", "command": "gitlens.key.right",
"key": "alt+right", "key": "alt+right",
"when": "gitlens:key" "when": "gitlens:key:right"
},
{
"command": "gitlens.key.,",
"key": "alt+,",
"when": "gitlens:key:,"
},
{
"command": "gitlens.key..",
"key": "alt+.",
"when": "gitlens:key:."
}, },
{ {
"command": "gitlens.toggleBlame", "command": "gitlens.toggleBlame",

View File

@@ -35,6 +35,6 @@ export const CommandContext = {
}; };
export function setCommandContext(key: CommandContext, value: any) { export function setCommandContext(key: CommandContext | string, value: any) {
return commands.executeCommand(BuiltInCommands.SetContext, key, value); return commands.executeCommand(BuiltInCommands.SetContext, key, value);
} }

View File

@@ -4,13 +4,21 @@ import { CommandContext, setCommandContext } from '../commands';
import { CommandQuickPickItem, OpenFileCommandQuickPickItem } from '../quickPicks/quickPicks'; import { CommandQuickPickItem, OpenFileCommandQuickPickItem } from '../quickPicks/quickPicks';
import { Logger } from '../logger'; import { Logger } from '../logger';
export declare type Keys = 'left' | 'right'; export declare type Keys = 'left' | 'right' | ',' | '.';
export const keys: Keys[] = [ export const keys: Keys[] = [
'left', 'left',
'right' 'right',
',',
'.'
]; ];
let scopeCount = 0; let scopeCount = 0;
let counters = {
left: 0,
right: 0,
',': 0,
'.': 0
};
let _instance: Keyboard; let _instance: Keyboard;
@@ -41,7 +49,10 @@ export class Keyboard extends Disposable {
} }
async execute(key: Keys): Promise<{}> { async execute(key: Keys): Promise<{}> {
const command = this.context.globalState.get(`gitlens:key:${key}`) as CommandQuickPickItem; let command = this.context.globalState.get(`gitlens:key:${key}`) as CommandQuickPickItem | (() => Promise<CommandQuickPickItem>);
if (typeof command === 'function') {
command = await command();
}
if (!command || !(command instanceof CommandQuickPickItem)) return undefined; if (!command || !(command instanceof CommandQuickPickItem)) return undefined;
Logger.log('Keyboard.execute', key); Logger.log('Keyboard.execute', key);
@@ -54,11 +65,13 @@ export class Keyboard extends Disposable {
return await command.execute(); return await command.execute();
} }
async enterScope(...keyCommands: [Keys, QuickPickItem][]) { async enterScope(...keyCommands: [Keys, QuickPickItem | (() => Promise<QuickPickItem>)][]) {
Logger.log('Keyboard.enterScope', scopeCount); Logger.log('Keyboard.enterScope', scopeCount);
await setCommandContext(CommandContext.Key, ++scopeCount); scopeCount++;
// await setCommandContext(CommandContext.Key, ++scopeCount);
if (keyCommands && Array.isArray(keyCommands) && keyCommands.length) { if (keyCommands && Array.isArray(keyCommands) && keyCommands.length) {
for (const [key, command] of keyCommands) { for (const [key, command] of keyCommands) {
await setCommandContext(`${CommandContext.Key}:${key}`, ++counters[key]);
await this.setKeyCommand(key as Keys, command); await this.setKeyCommand(key as Keys, command);
} }
} }
@@ -66,9 +79,15 @@ export class Keyboard extends Disposable {
async exitScope(clear: boolean = true) { async exitScope(clear: boolean = true) {
Logger.log('Keyboard.exitScope', scopeCount); Logger.log('Keyboard.exitScope', scopeCount);
await setCommandContext(CommandContext.Key, --scopeCount); if (scopeCount) {
scopeCount--;
// await setCommandContext(CommandContext.Key, --scopeCount);
}
if (clear && !scopeCount) { if (clear && !scopeCount) {
for (const key of keys) { for (const key of keys) {
if (counters[key]) {
await setCommandContext(`${CommandContext.Key}:${key}`, --counters[key]);
}
await this.clearKeyCommand(key); await this.clearKeyCommand(key);
} }
} }
@@ -76,11 +95,15 @@ export class Keyboard extends Disposable {
async clearKeyCommand(key: Keys) { async clearKeyCommand(key: Keys) {
Logger.log('Keyboard.clearKeyCommand', key); Logger.log('Keyboard.clearKeyCommand', key);
if (counters[key]) {
await setCommandContext(`${CommandContext.Key}:${key}`, --counters[key]);
}
await this.context.globalState.update(`gitlens:key:${key}`, undefined); await this.context.globalState.update(`gitlens:key:${key}`, undefined);
} }
async setKeyCommand(key: Keys, command: QuickPickItem) { async setKeyCommand(key: Keys, command: QuickPickItem | (() => Promise<QuickPickItem>)) {
Logger.log('Keyboard.setKeyCommand', key); Logger.log('Keyboard.setKeyCommand', key);
await setCommandContext(`${CommandContext.Key}:${key}`, ++counters[key]);
await this.context.globalState.update(`gitlens:key:${key}`, command); await this.context.globalState.update(`gitlens:key:${key}`, command);
} }
} }

View File

@@ -1,18 +1,17 @@
'use strict'; 'use strict';
import { Iterables } from '../system';
import { commands, TextEditor, Uri, window } from 'vscode'; import { commands, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands } from './commands'; import { ActiveEditorCommand, Commands } from './commands';
import { GitCommit, GitLogCommit, GitProvider, GitUri } from '../gitProvider'; import { GitCommit, GitLogCommit, GitProvider, GitUri, IGitLog } from '../gitProvider';
import { Logger } from '../logger'; import { Logger } from '../logger';
import { CommandQuickPickItem, CommitDetailsQuickPick, CommitWithFileStatusQuickPickItem } from '../quickPicks'; import { CommandQuickPickItem, CommitDetailsQuickPick, CommitWithFileStatusQuickPickItem } from '../quickPicks';
export class ShowQuickCommitDetailsCommand extends ActiveEditorCommand { export class ShowQuickCommitDetailsCommand extends ActiveEditorCommand {
constructor(private git: GitProvider) { constructor(private git: GitProvider, private repoPath: string) {
super(Commands.ShowQuickCommitDetails); super(Commands.ShowQuickCommitDetails);
} }
async execute(editor: TextEditor, uri?: Uri, sha?: string, commit?: GitCommit | GitLogCommit, goBackCommand?: CommandQuickPickItem) { async execute(editor: TextEditor, uri?: Uri, sha?: string, commit?: GitCommit | GitLogCommit, goBackCommand?: CommandQuickPickItem, repoLog?: IGitLog) {
if (!(uri instanceof Uri)) { if (!(uri instanceof Uri)) {
if (!editor || !editor.document) return undefined; if (!editor || !editor.document) return undefined;
uri = editor.document.uri; uri = editor.document.uri;
@@ -45,21 +44,31 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCommand {
try { try {
if (!commit || !(commit instanceof GitLogCommit) || commit.type !== 'repo') { if (!commit || !(commit instanceof GitLogCommit) || commit.type !== 'repo') {
let log = await this.git.getLogForRepo(repoPath, sha, 2); if (repoLog) {
if (!log) return window.showWarningMessage(`Unable to show commit details`); commit = repoLog.commits.get(sha);
// If we can't find the commit, kill the repoLog
if (!commit) {
repoLog = undefined;
}
}
commit = Iterables.first(log.commits.values()); if (!repoLog) {
const log = await this.git.getLogForRepo(repoPath || this.repoPath, sha, 2);
if (!log) return window.showWarningMessage(`Unable to show commit details`);
commit = log.commits.get(sha);
}
} }
if (!goBackCommand) { if (!goBackCommand) {
// Create a command to get back to the commit details // Create a command to get back to the repository history
goBackCommand = new CommandQuickPickItem({ goBackCommand = new CommandQuickPickItem({
label: `go back \u21A9`, label: `go back \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to repository history` description: `\u00a0 \u2014 \u00a0\u00a0 to repository history`
}, Commands.ShowQuickRepoHistory, [new GitUri(commit.uri, commit)]); }, Commands.ShowQuickRepoHistory, [new GitUri(commit.uri, commit)]);
} }
const pick = await CommitDetailsQuickPick.show(commit as GitLogCommit, uri, goBackCommand); const pick = await CommitDetailsQuickPick.show(this.git, commit as GitLogCommit, uri, goBackCommand, repoLog);
if (!pick) return undefined; if (!pick) return undefined;
if (!(pick instanceof CommitWithFileStatusQuickPickItem)) { if (!(pick instanceof CommitWithFileStatusQuickPickItem)) {
@@ -71,7 +80,7 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCommand {
new CommandQuickPickItem({ new CommandQuickPickItem({
label: `go back \u21A9`, label: `go back \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to details of \u00a0$(git-commit) ${pick.shortSha}` description: `\u00a0 \u2014 \u00a0\u00a0 to details of \u00a0$(git-commit) ${pick.shortSha}`
}, Commands.ShowQuickCommitDetails, [new GitUri(commit.uri, commit), sha, commit, goBackCommand])); }, Commands.ShowQuickCommitDetails, [new GitUri(commit.uri, commit), sha, commit, goBackCommand, repoLog]));
} }
catch (ex) { catch (ex) {
Logger.error('[GitLens.ShowQuickCommitDetailsCommand]', ex); Logger.error('[GitLens.ShowQuickCommitDetailsCommand]', ex);

View File

@@ -1,8 +1,7 @@
'use strict'; 'use strict';
import { Iterables } from '../system';
import { TextEditor, Uri, window } from 'vscode'; import { TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands } from './commands'; import { ActiveEditorCommand, Commands } from './commands';
import { GitCommit, GitLogCommit, GitProvider, GitUri } from '../gitProvider'; import { GitCommit, GitLogCommit, GitProvider, GitUri, IGitLog } from '../gitProvider';
import { Logger } from '../logger'; import { Logger } from '../logger';
import { CommandQuickPickItem, CommitFileDetailsQuickPick } from '../quickPicks'; import { CommandQuickPickItem, CommitFileDetailsQuickPick } from '../quickPicks';
import * as path from 'path'; import * as path from 'path';
@@ -13,19 +12,17 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCommand {
super(Commands.ShowQuickCommitFileDetails); super(Commands.ShowQuickCommitFileDetails);
} }
async execute(editor: TextEditor, uri?: Uri, sha?: string, commit?: GitCommit | GitLogCommit, goBackCommand?: CommandQuickPickItem, options: { showFileHistory?: boolean } = { showFileHistory: true }) { async execute(editor: TextEditor, uri?: Uri, sha?: string, commit?: GitCommit | GitLogCommit, goBackCommand?: CommandQuickPickItem, options: { showFileHistory?: boolean } = { showFileHistory: true }, fileLog?: IGitLog) {
if (!(uri instanceof Uri)) { if (!(uri instanceof Uri)) {
if (!editor || !editor.document) return undefined; if (!editor || !editor.document) return undefined;
uri = editor.document.uri; uri = editor.document.uri;
} }
const gitUri = await GitUri.fromUri(uri, this.git);
let repoPath = gitUri.repoPath;
if (!sha) { if (!sha) {
if (!editor) return undefined; if (!editor) return undefined;
const gitUri = await GitUri.fromUri(uri, this.git);
const blameline = editor.selection.active.line - gitUri.offset; const blameline = editor.selection.active.line - gitUri.offset;
if (blameline < 0) return undefined; if (blameline < 0) return undefined;
@@ -34,7 +31,6 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCommand {
if (!blame) return window.showWarningMessage(`Unable to show commit file details. File is probably not under source control`); if (!blame) return window.showWarningMessage(`Unable to show commit file details. File is probably not under source control`);
sha = blame.commit.isUncommitted ? blame.commit.previousSha : blame.commit.sha; sha = blame.commit.isUncommitted ? blame.commit.previousSha : blame.commit.sha;
repoPath = blame.commit.repoPath;
commit = blame.commit; commit = blame.commit;
} }
@@ -45,11 +41,21 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCommand {
} }
try { try {
if (!commit || ((commit instanceof GitLogCommit) && commit.type !== 'file')) { if (!commit || !(commit instanceof GitLogCommit) || commit.type !== 'file') {
let log = await this.git.getLogForFile(uri.fsPath, sha, undefined, undefined, 2); if (fileLog) {
if (!log) return window.showWarningMessage(`Unable to show commit file details`); commit = fileLog.commits.get(sha);
// If we can't find the commit, kill the fileLog
if (!commit) {
fileLog = undefined;
}
}
commit = Iterables.find(log.commits.values(), c => c.sha === sha); if (!fileLog) {
const log = await this.git.getLogForFile(uri.fsPath, sha, undefined, undefined, 2);
if (!log) return window.showWarningMessage(`Unable to show commit file details`);
commit = log.commits.get(sha);
}
} }
// Attempt to the most recent commit -- so that we can find the real working filename if there was a rename // Attempt to the most recent commit -- so that we can find the real working filename if there was a rename
@@ -67,13 +73,13 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCommand {
}, Commands.ShowQuickCommitDetails, [new GitUri(commit.uri, commit), sha, commit]); }, Commands.ShowQuickCommitDetails, [new GitUri(commit.uri, commit), sha, commit]);
} }
const pick = await CommitFileDetailsQuickPick.show(this.git, commit, workingFileName, uri, goBackCommand, const pick = await CommitFileDetailsQuickPick.show(this.git, commit as GitLogCommit, workingFileName, uri, goBackCommand,
// Create a command to get back to where we are right now // Create a command to get back to where we are right now
new CommandQuickPickItem({ new CommandQuickPickItem({
label: `go back \u21A9`, label: `go back \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to details of \u00a0$(file-text) ${path.basename(commit.fileName)} in \u00a0$(git-commit) ${shortSha}` description: `\u00a0 \u2014 \u00a0\u00a0 to details of \u00a0$(file-text) ${path.basename(commit.fileName)} in \u00a0$(git-commit) ${shortSha}`
}, Commands.ShowQuickCommitFileDetails, [new GitUri(commit.uri, commit), sha, commit, goBackCommand, options]), }, Commands.ShowQuickCommitFileDetails, [new GitUri(commit.uri, commit), sha, commit, goBackCommand, options]),
{ showFileHistory: options.showFileHistory }); { showFileHistory: options.showFileHistory }, fileLog);
if (!pick) return undefined; if (!pick) return undefined;

View File

@@ -1,7 +1,7 @@
'use strict'; 'use strict';
import { commands, TextEditor, Uri, window } from 'vscode'; import { commands, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands } from './commands'; import { ActiveEditorCommand, Commands } from './commands';
import { GitProvider, GitUri } from '../gitProvider'; import { GitProvider, GitUri, IGitLog } from '../gitProvider';
import { Logger } from '../logger'; import { Logger } from '../logger';
import { CommandQuickPickItem, FileHistoryQuickPick } from '../quickPicks'; import { CommandQuickPickItem, FileHistoryQuickPick } from '../quickPicks';
import * as path from 'path'; import * as path from 'path';
@@ -12,7 +12,7 @@ export class ShowQuickFileHistoryCommand extends ActiveEditorCommand {
super(Commands.ShowQuickFileHistory); super(Commands.ShowQuickFileHistory);
} }
async execute(editor: TextEditor, uri?: Uri, maxCount?: number, goBackCommand?: CommandQuickPickItem) { async execute(editor: TextEditor, uri?: Uri, maxCount?: number, goBackCommand?: CommandQuickPickItem, log?: IGitLog) {
if (!(uri instanceof Uri)) { if (!(uri instanceof Uri)) {
uri = editor && editor.document && editor.document.uri; uri = editor && editor.document && editor.document.uri;
} }
@@ -28,10 +28,12 @@ export class ShowQuickFileHistoryCommand extends ActiveEditorCommand {
} }
try { try {
const log = await this.git.getLogForFile(gitUri.fsPath, gitUri.sha, gitUri.repoPath, undefined, maxCount); if (!log) {
if (!log) return window.showWarningMessage(`Unable to show file history. File is probably not under source control`); log = await this.git.getLogForFile(gitUri.fsPath, gitUri.sha, gitUri.repoPath, undefined, maxCount);
if (!log) return window.showWarningMessage(`Unable to show file history. File is probably not under source control`);
}
let pick = await FileHistoryQuickPick.show(log, uri, gitUri.sha, maxCount, this.git.config.advanced.maxQuickHistory, goBackCommand); const pick = await FileHistoryQuickPick.show(log, uri, gitUri.sha, maxCount, this.git.config.advanced.maxQuickHistory, goBackCommand);
if (!pick) return undefined; if (!pick) return undefined;
if (pick instanceof CommandQuickPickItem) { if (pick instanceof CommandQuickPickItem) {
@@ -42,8 +44,9 @@ export class ShowQuickFileHistoryCommand extends ActiveEditorCommand {
new CommandQuickPickItem({ new CommandQuickPickItem({
label: `go back \u21A9`, label: `go back \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to history of \u00a0$(file-text) ${path.basename(pick.commit.fileName)}` description: `\u00a0 \u2014 \u00a0\u00a0 to history of \u00a0$(file-text) ${path.basename(pick.commit.fileName)}`
}, Commands.ShowQuickFileHistory, [uri, maxCount, goBackCommand]), }, Commands.ShowQuickFileHistory, [uri, maxCount, goBackCommand, log]),
{ showFileHistory: false }); { showFileHistory: false },
log);
} }
catch (ex) { catch (ex) {
Logger.error('[GitLens.ShowQuickFileHistoryCommand]', 'getLogLocations', ex); Logger.error('[GitLens.ShowQuickFileHistoryCommand]', 'getLogLocations', ex);

View File

@@ -1,7 +1,7 @@
'use strict'; 'use strict';
import { commands, TextEditor, Uri, window } from 'vscode'; import { commands, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands } from './commands'; import { ActiveEditorCommand, Commands } from './commands';
import { GitProvider, GitUri } from '../gitProvider'; import { GitProvider, GitUri, IGitLog } from '../gitProvider';
import { Logger } from '../logger'; import { Logger } from '../logger';
import { CommandQuickPickItem, RepoHistoryQuickPick } from '../quickPicks'; import { CommandQuickPickItem, RepoHistoryQuickPick } from '../quickPicks';
@@ -11,7 +11,7 @@ export class ShowQuickRepoHistoryCommand extends ActiveEditorCommand {
super(Commands.ShowQuickRepoHistory); super(Commands.ShowQuickRepoHistory);
} }
async execute(editor: TextEditor, uri?: Uri, maxCount?: number, goBackCommand?: CommandQuickPickItem) { async execute(editor: TextEditor, uri?: Uri, maxCount?: number, goBackCommand?: CommandQuickPickItem, log?: IGitLog) {
if (!(uri instanceof Uri)) { if (!(uri instanceof Uri)) {
uri = editor && editor.document && editor.document.uri; uri = editor && editor.document && editor.document.uri;
} }
@@ -21,11 +21,13 @@ export class ShowQuickRepoHistoryCommand extends ActiveEditorCommand {
} }
try { try {
const repoPath = await this.git.getRepoPathFromUri(uri, this.repoPath); if (!log) {
if (!repoPath) return window.showWarningMessage(`Unable to show repository history`); const repoPath = await this.git.getRepoPathFromUri(uri, this.repoPath);
if (!repoPath) return window.showWarningMessage(`Unable to show repository history`);
const log = await this.git.getLogForRepo(repoPath, undefined, maxCount); log = await this.git.getLogForRepo(repoPath, undefined, maxCount);
if (!log) return window.showWarningMessage(`Unable to show repository history`); if (!log) return window.showWarningMessage(`Unable to show repository history`);
}
const pick = await RepoHistoryQuickPick.show(log, uri, maxCount, this.git.config.advanced.maxQuickHistory, goBackCommand); const pick = await RepoHistoryQuickPick.show(log, uri, maxCount, this.git.config.advanced.maxQuickHistory, goBackCommand);
if (!pick) return undefined; if (!pick) return undefined;
@@ -38,7 +40,8 @@ export class ShowQuickRepoHistoryCommand extends ActiveEditorCommand {
new CommandQuickPickItem({ new CommandQuickPickItem({
label: `go back \u21A9`, label: `go back \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to repository history` description: `\u00a0 \u2014 \u00a0\u00a0 to repository history`
}, Commands.ShowQuickRepoHistory, [uri, maxCount, goBackCommand])); }, Commands.ShowQuickRepoHistory, [uri, maxCount, goBackCommand, log]),
log);
} }
catch (ex) { catch (ex) {
Logger.error('[GitLens.ShowQuickRepoHistoryCommand]', ex); Logger.error('[GitLens.ShowQuickRepoHistoryCommand]', ex);

View File

@@ -102,7 +102,7 @@ export async function activate(context: ExtensionContext) {
context.subscriptions.push(new ToggleBlameCommand(annotationController)); context.subscriptions.push(new ToggleBlameCommand(annotationController));
context.subscriptions.push(new ShowBlameHistoryCommand(git)); context.subscriptions.push(new ShowBlameHistoryCommand(git));
context.subscriptions.push(new ShowFileHistoryCommand(git)); context.subscriptions.push(new ShowFileHistoryCommand(git));
context.subscriptions.push(new ShowQuickCommitDetailsCommand(git)); context.subscriptions.push(new ShowQuickCommitDetailsCommand(git, repoPath));
context.subscriptions.push(new ShowQuickCommitFileDetailsCommand(git)); context.subscriptions.push(new ShowQuickCommitFileDetailsCommand(git));
context.subscriptions.push(new ShowQuickFileHistoryCommand(git)); context.subscriptions.push(new ShowQuickFileHistoryCommand(git));
context.subscriptions.push(new ShowQuickRepoHistoryCommand(git, repoPath)); context.subscriptions.push(new ShowQuickRepoHistoryCommand(git, repoPath));

View File

@@ -1,9 +1,9 @@
'use strict'; 'use strict';
import { QuickPickItem, QuickPickOptions, Uri, window } from 'vscode'; import { QuickPickItem, QuickPickOptions, Uri, window } from 'vscode';
import { Commands, Keyboard } from '../commands'; import { Commands, Keyboard } from '../commands';
import { GitLogCommit, GitProvider } from '../gitProvider'; import { GitLogCommit, GitProvider, IGitLog } from '../gitProvider';
import { CommitWithFileStatusQuickPickItem } from './gitQuickPicks'; import { CommitWithFileStatusQuickPickItem } from './gitQuickPicks';
import { CommandQuickPickItem, getQuickPickIgnoreFocusOut, OpenFilesCommandQuickPickItem } from './quickPicks'; import { CommandQuickPickItem, getQuickPickIgnoreFocusOut, KeyCommandQuickPickItem, KeyNoopCommandQuickPickItem, OpenFilesCommandQuickPickItem } from './quickPicks';
import * as moment from 'moment'; import * as moment from 'moment';
import * as path from 'path'; import * as path from 'path';
@@ -35,7 +35,7 @@ export class OpenCommitWorkingTreeFilesCommandQuickPickItem extends OpenFilesCom
export class CommitDetailsQuickPick { export class CommitDetailsQuickPick {
static async show(commit: GitLogCommit, uri: Uri, goBackCommand?: CommandQuickPickItem): Promise<CommitWithFileStatusQuickPickItem | CommandQuickPickItem | undefined> { static async show(git: GitProvider, commit: GitLogCommit, uri: Uri, goBackCommand?: CommandQuickPickItem, repoLog?: IGitLog): Promise<CommitWithFileStatusQuickPickItem | CommandQuickPickItem | undefined> {
const items: (CommitWithFileStatusQuickPickItem | CommandQuickPickItem)[] = commit.fileStatuses.map(fs => new CommitWithFileStatusQuickPickItem(commit, fs.fileName, fs.status)); const items: (CommitWithFileStatusQuickPickItem | CommandQuickPickItem)[] = commit.fileStatuses.map(fs => new CommitWithFileStatusQuickPickItem(commit, fs.fileName, fs.status));
let index = 0; let index = 0;
@@ -63,7 +63,7 @@ export class CommitDetailsQuickPick {
items.splice(index++, 0, new CommandQuickPickItem({ items.splice(index++, 0, new CommandQuickPickItem({
label: `Changed Files`, label: `Changed Files`,
description: null description: null
}, Commands.ShowQuickCommitDetails, [uri, commit.sha, commit, goBackCommand])); }, Commands.ShowQuickCommitDetails, [uri, commit.sha, commit, goBackCommand, repoLog]));
items.push(new OpenCommitFilesCommandQuickPickItem(commit)); items.push(new OpenCommitFilesCommandQuickPickItem(commit));
items.push(new OpenCommitWorkingTreeFilesCommandQuickPickItem(commit)); items.push(new OpenCommitWorkingTreeFilesCommandQuickPickItem(commit));
@@ -72,7 +72,30 @@ export class CommitDetailsQuickPick {
items.splice(0, 0, goBackCommand); items.splice(0, 0, goBackCommand);
} }
await Keyboard.instance.enterScope(['left', goBackCommand]); const previousCommand = commit.previousSha
? new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [commit.previousUri, commit.previousSha, undefined, goBackCommand, repoLog])
: new KeyNoopCommandQuickPickItem();
let nextCommand: CommandQuickPickItem | (() => Promise<CommandQuickPickItem>);
if (repoLog) {
nextCommand = commit.nextSha
? new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [commit.nextUri, commit.nextSha, undefined, goBackCommand, repoLog])
: new KeyNoopCommandQuickPickItem();
}
else {
nextCommand = async () => {
const log = await git.getLogForRepo(commit.repoPath, undefined, git.config.advanced.maxQuickHistory);
const c = log && log.commits.get(commit.sha);
if (!c) return new KeyNoopCommandQuickPickItem();
return new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [c.nextUri, c.nextSha, undefined, goBackCommand, log]);
};
}
await Keyboard.instance.enterScope(
['left', goBackCommand],
[',', previousCommand],
['.', nextCommand]
);
const pick = await window.showQuickPick(items, { const pick = await window.showQuickPick(items, {
matchOnDescription: true, matchOnDescription: true,

View File

@@ -2,8 +2,8 @@
import { Iterables } from '../system'; import { Iterables } from '../system';
import { QuickPickItem, QuickPickOptions, Uri, window } from 'vscode'; import { QuickPickItem, QuickPickOptions, Uri, window } from 'vscode';
import { Commands, Keyboard } from '../commands'; import { Commands, Keyboard } from '../commands';
import { GitCommit, GitLogCommit, GitProvider, GitUri } from '../gitProvider'; import { GitCommit, GitLogCommit, GitProvider, GitUri, IGitLog } from '../gitProvider';
import { CommandQuickPickItem, getQuickPickIgnoreFocusOut, OpenFileCommandQuickPickItem } from './quickPicks'; import { CommandQuickPickItem, getQuickPickIgnoreFocusOut, KeyCommandQuickPickItem, KeyNoopCommandQuickPickItem, OpenFileCommandQuickPickItem } from './quickPicks';
import * as moment from 'moment'; import * as moment from 'moment';
import * as path from 'path'; import * as path from 'path';
@@ -31,7 +31,7 @@ export class OpenCommitWorkingTreeFileCommandQuickPickItem extends OpenFileComma
export class CommitFileDetailsQuickPick { export class CommitFileDetailsQuickPick {
static async show(git: GitProvider, commit: GitCommit | GitLogCommit, workingFileName: string, uri: Uri, goBackCommand?: CommandQuickPickItem, currentCommand?: CommandQuickPickItem, options: { showFileHistory?: boolean } = {}): Promise<CommandQuickPickItem | undefined> { static async show(git: GitProvider, commit: GitLogCommit, workingFileName: string, uri: Uri, goBackCommand?: CommandQuickPickItem, currentCommand?: CommandQuickPickItem, options: { showFileHistory?: boolean } = {}, fileLog?: IGitLog): Promise<CommandQuickPickItem | undefined> {
const items: CommandQuickPickItem[] = []; const items: CommandQuickPickItem[] = [];
const workingName = (workingFileName && path.basename(workingFileName)) || path.basename(commit.fileName); const workingName = (workingFileName && path.basename(workingFileName)) || path.basename(commit.fileName);
@@ -81,7 +81,7 @@ export class CommitFileDetailsQuickPick {
items.push(new CommandQuickPickItem({ items.push(new CommandQuickPickItem({
label: `$(history) Show File History`, label: `$(history) Show File History`,
description: `\u00a0 \u2014 \u00a0\u00a0 of ${path.basename(commit.fileName)}` description: `\u00a0 \u2014 \u00a0\u00a0 of ${path.basename(commit.fileName)}`
}, Commands.ShowQuickFileHistory, [commit.uri, undefined, currentCommand])); }, Commands.ShowQuickFileHistory, [commit.uri, undefined, currentCommand, fileLog]));
} }
items.push(new CommandQuickPickItem({ items.push(new CommandQuickPickItem({
@@ -93,7 +93,30 @@ export class CommitFileDetailsQuickPick {
items.splice(0, 0, goBackCommand); items.splice(0, 0, goBackCommand);
} }
await Keyboard.instance.enterScope(['left', goBackCommand]); const previousCommand = commit.previousSha
? new KeyCommandQuickPickItem(Commands.ShowQuickCommitFileDetails, [commit.previousUri, commit.previousSha, undefined, goBackCommand, options, fileLog])
: new KeyNoopCommandQuickPickItem();
let nextCommand: CommandQuickPickItem | (() => Promise<CommandQuickPickItem>);
if (fileLog) {
nextCommand = commit.nextSha
? new KeyCommandQuickPickItem(Commands.ShowQuickCommitFileDetails, [commit.nextUri, commit.nextSha, undefined, goBackCommand, options, fileLog])
: new KeyNoopCommandQuickPickItem();
}
else {
nextCommand = async () => {
const log = await git.getLogForFile(uri.fsPath, undefined, commit.repoPath, undefined, git.config.advanced.maxQuickHistory);
const c = log && log.commits.get(commit.sha);
if (!c) return new KeyNoopCommandQuickPickItem();
return new KeyCommandQuickPickItem(Commands.ShowQuickCommitFileDetails, [c.nextUri, c.nextSha, undefined, goBackCommand, options, log]);
};
}
await Keyboard.instance.enterScope(
['left', goBackCommand],
[',', previousCommand],
['.', nextCommand]
);
const pick = await window.showQuickPick(items, { const pick = await window.showQuickPick(items, {
matchOnDescription: true, matchOnDescription: true,

View File

@@ -33,7 +33,7 @@ export class FileHistoryQuickPick {
new CommandQuickPickItem({ new CommandQuickPickItem({
label: `go back \u21A9`, label: `go back \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to history of \u00a0$(file-text) ${path.basename(uri.fsPath)}` description: `\u00a0 \u2014 \u00a0\u00a0 to history of \u00a0$(file-text) ${path.basename(uri.fsPath)}`
}, Commands.ShowQuickFileHistory, [uri, maxCount]) }, Commands.ShowQuickFileHistory, [uri, maxCount, undefined, log])
])); ]));
} }

View File

@@ -22,6 +22,24 @@ export class CommandQuickPickItem implements QuickPickItem {
} }
} }
export class KeyCommandQuickPickItem extends CommandQuickPickItem {
constructor(protected command: Commands, protected args?: any[]) {
super({ label: undefined, description: undefined }, command, args);
}
}
export class KeyNoopCommandQuickPickItem extends CommandQuickPickItem {
constructor() {
super({ label: undefined, description: undefined }, undefined, undefined);
}
execute(): Thenable<{}> {
return Promise.resolve(undefined);
}
}
export class OpenFileCommandQuickPickItem extends CommandQuickPickItem { export class OpenFileCommandQuickPickItem extends CommandQuickPickItem {
constructor(public uri: Uri, item: QuickPickItem) { constructor(public uri: Uri, item: QuickPickItem) {

View File

@@ -9,7 +9,7 @@ import { CommandQuickPickItem, getQuickPickIgnoreFocusOut } from './quickPicks';
export class RepoHistoryQuickPick { export class RepoHistoryQuickPick {
static async show(log: IGitLog, uri: Uri, maxCount: number, defaultMaxCount: number, goBackCommand?: CommandQuickPickItem): Promise<CommitQuickPickItem | CommandQuickPickItem | undefined> { static async show(log: IGitLog, uri: Uri, maxCount: number, defaultMaxCount: number, goBackCommand?: CommandQuickPickItem): Promise<CommitQuickPickItem | CommandQuickPickItem | undefined> {
const items = Array.from(Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c, ` \u2014 ${c.fileName}`))) as (CommitQuickPickItem | CommandQuickPickItem)[]; const items = Array.from(Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c, ` \u2014 ${c.fileNames}`))) as (CommitQuickPickItem | CommandQuickPickItem)[];
if (maxCount !== 0 && items.length >= defaultMaxCount) { if (maxCount !== 0 && items.length >= defaultMaxCount) {
items.splice(0, 0, new CommandQuickPickItem({ items.splice(0, 0, new CommandQuickPickItem({