Skip to content

Commit

Permalink
Adds better diff editor support to diff commands
Browse files Browse the repository at this point in the history
Changes behavior of diffWithNext when in a diff
Changes behavior of diffWithPrevious when in a diff
Changes behavior of diffWithWorking when in a diff
  • Loading branch information
eamodio committed Apr 1, 2019
1 parent c8dad4d commit 97c6509
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 29 deletions.
100 changes: 79 additions & 21 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1851,6 +1851,15 @@
"light": "images/light/icon-next-commit.svg"
}
},
{
"command": "gitlens.diffWithNextInDiff",
"title": "Open Changes with Next Revision",
"category": "GitLens",
"icon": {
"dark": "images/dark/icon-next-commit.svg",
"light": "images/light/icon-next-commit.svg"
}
},
{
"command": "gitlens.diffWithPrevious",
"title": "Open Changes with Previous Revision",
Expand Down Expand Up @@ -1892,6 +1901,15 @@
"light": "images/light/icon-compare-ref-working.svg"
}
},
{
"command": "gitlens.diffWithWorkingInDiff",
"title": "Open Changes with Working File",
"category": "GitLens",
"icon": {
"dark": "images/dark/icon-compare-ref-working.svg",
"light": "images/light/icon-compare-ref-working.svg"
}
},
{
"command": "gitlens.diffLineWithWorking",
"title": "Open Line Changes with Working File",
Expand Down Expand Up @@ -2879,7 +2897,11 @@
},
{
"command": "gitlens.diffWithNext",
"when": "gitlens:activeFileStatus =~ /tracked/ && gitlens:activeFileStatus =~ /revision/"
"when": "!isInDiffEditor && gitlens:activeFileStatus =~ /revision/"
},
{
"command": "gitlens.diffWithNextInDiff",
"when": "isInDiffEditor && gitlens:activeFileStatus =~ /revision/"
},
{
"command": "gitlens.diffWithPrevious",
Expand All @@ -2899,7 +2921,11 @@
},
{
"command": "gitlens.diffWithWorking",
"when": "gitlens:activeFileStatus =~ /tracked/"
"when": "!isInDiffEditor && gitlens:activeFileStatus =~ /revision/"
},
{
"command": "gitlens.diffWithWorkingInDiff",
"when": "isInDiffEditor && gitlens:activeFileStatus =~ /revision/"
},
{
"command": "gitlens.diffLineWithWorking",
Expand Down Expand Up @@ -3514,7 +3540,12 @@
"editor/title": [
{
"command": "gitlens.diffWithWorking",
"when": "gitlens:activeFileStatus =~ /revision/ && resourceScheme != file && resourceScheme != git",
"when": "!isInDiffEditor && gitlens:activeFileStatus =~ /revision/ && resourceScheme != file && resourceScheme != git",
"group": "navigation@0"
},
{
"command": "gitlens.diffWithWorkingInDiff",
"when": "isInDiffEditor && gitlens:activeFileStatus =~ /revision/ && resourceScheme != file && resourceScheme != git",
"group": "navigation@0"
},
{
Expand Down Expand Up @@ -3551,7 +3582,12 @@
},
{
"command": "gitlens.diffWithNext",
"when": "gitlens:activeFileStatus =~ /tracked/ && gitlens:activeFileStatus =~ /tracked/ && gitlens:activeFileStatus =~ /revision/ && config.gitlens.menus.editorGroup.compare",
"when": "!isInDiffEditor && gitlens:activeFileStatus =~ /revision/ && config.gitlens.menus.editorGroup.compare",
"group": "navigation@99"
},
{
"command": "gitlens.diffWithNextInDiff",
"when": "isInDiffEditor && gitlens:activeFileStatus =~ /revision/ && config.gitlens.menus.editorGroup.compare",
"group": "navigation@99"
},
{
Expand Down Expand Up @@ -4643,12 +4679,12 @@
{
"command": "gitlens.diffWithNext",
"key": "alt+.",
"when": "config.gitlens.keymap == alternate && editorTextFocus && gitlens:activeFileStatus =~ /tracked/"
"when": "config.gitlens.keymap == alternate && editorTextFocus && !isInDiffEditor && gitlens:activeFileStatus =~ /revision/"
},
{
"command": "gitlens.diffLineWithPrevious",
"key": "shift+alt+,",
"when": "config.gitlens.keymap == alternate && editorTextFocus && gitlens:activeFileStatus =~ /tracked/"
"command": "gitlens.diffWithNextInDiff",
"key": "alt+.",
"when": "config.gitlens.keymap == alternate && isInDiffEditor && gitlens:activeFileStatus =~ /revision/"
},
{
"command": "gitlens.diffWithPrevious",
Expand All @@ -4661,13 +4697,23 @@
"when": "config.gitlens.keymap == alternate && isInDiffEditor && gitlens:activeFileStatus =~ /tracked/"
},
{
"command": "gitlens.diffLineWithWorking",
"key": "alt+w",
"command": "gitlens.diffLineWithPrevious",
"key": "shift+alt+,",
"when": "config.gitlens.keymap == alternate && editorTextFocus && gitlens:activeFileStatus =~ /tracked/"
},
{
"command": "gitlens.diffWithWorking",
"key": "shift+alt+w",
"key": "shift+alt+.",
"when": "config.gitlens.keymap == alternate && editorTextFocus && !isInDiffEditor && gitlens:activeFileStatus =~ /revision/"
},
{
"command": "gitlens.diffWithWorkingInDiff",
"key": "shift+alt+.",
"when": "config.gitlens.keymap == alternate && isInDiffEditor && gitlens:activeFileStatus =~ /revision/"
},
{
"command": "gitlens.diffLineWithWorking",
"key": "alt+w",
"when": "config.gitlens.keymap == alternate && editorTextFocus && gitlens:activeFileStatus =~ /tracked/"
},
{
Expand Down Expand Up @@ -4722,13 +4768,13 @@
"command": "gitlens.diffWithNext",
"key": "ctrl+shift+g .",
"mac": "cmd+alt+g .",
"when": "config.gitlens.keymap == chorded && editorTextFocus && gitlens:activeFileStatus =~ /tracked/"
"when": "config.gitlens.keymap == chorded && editorTextFocus && !isInDiffEditor && gitlens:activeFileStatus =~ /revision/"
},
{
"command": "gitlens.diffLineWithPrevious",
"key": "ctrl+shift+g shift+,",
"mac": "cmd+alt+g shift+,",
"when": "config.gitlens.keymap == chorded && editorTextFocus && gitlens:activeFileStatus =~ /tracked/"
"command": "gitlens.diffWithNextInDiff",
"key": "ctrl+shift+g .",
"mac": "cmd+alt+g .",
"when": "config.gitlens.keymap == chorded && isInDiffEditor && gitlens:activeFileStatus =~ /revision/"
},
{
"command": "gitlens.diffWithPrevious",
Expand All @@ -4743,15 +4789,27 @@
"when": "config.gitlens.keymap == chorded && isInDiffEditor && gitlens:activeFileStatus =~ /tracked/"
},
{
"command": "gitlens.diffLineWithWorking",
"key": "ctrl+shift+g w",
"mac": "cmd+alt+g w",
"command": "gitlens.diffLineWithPrevious",
"key": "ctrl+shift+g shift+,",
"mac": "cmd+alt+g shift+,",
"when": "config.gitlens.keymap == chorded && editorTextFocus && gitlens:activeFileStatus =~ /tracked/"
},
{
"command": "gitlens.diffWithWorking",
"key": "ctrl+shift+g shift+w",
"mac": "cmd+alt+g shift+w",
"key": "ctrl+shift+g shift+.",
"mac": "cmd+alt+g shift+.",
"when": "config.gitlens.keymap == chorded && editorTextFocus && !isInDiffEditor && gitlens:activeFileStatus =~ /revision/"
},
{
"command": "gitlens.diffWithWorkingInDiff",
"key": "ctrl+shift+g shift+.",
"mac": "cmd+alt+g shift+.",
"when": "config.gitlens.keymap == chorded && isInDiffEditor && gitlens:activeFileStatus =~ /revision/"
},
{
"command": "gitlens.diffLineWithWorking",
"key": "ctrl+shift+g w",
"mac": "cmd+alt+g w",
"when": "config.gitlens.keymap == chorded && editorTextFocus && gitlens:activeFileStatus =~ /tracked/"
},
{
Expand Down
2 changes: 2 additions & 0 deletions src/commands/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ export enum Commands {
DiffWith = 'gitlens.diffWith',
DiffWithBranch = 'gitlens.diffWithBranch',
DiffWithNext = 'gitlens.diffWithNext',
DiffWithNextInDiff = 'gitlens.diffWithNextInDiff',
DiffWithPrevious = 'gitlens.diffWithPrevious',
DiffWithPreviousInDiff = 'gitlens.diffWithPreviousInDiff',
DiffLineWithPrevious = 'gitlens.diffLineWithPrevious',
DiffWithRevision = 'gitlens.diffWithRevision',
DiffWithWorking = 'gitlens.diffWithWorking',
DiffWithWorkingInDiff = 'gitlens.diffWithWorkingInDiff',
DiffLineWithWorking = 'gitlens.diffLineWithWorking',
ExternalDiff = 'gitlens.externalDiff',
FetchRepositories = 'gitlens.fetchRepositories',
Expand Down
25 changes: 23 additions & 2 deletions src/commands/diffWithNext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,42 @@ import { GitLogCommit, GitService, GitStatusFile, GitUri } from '../git/gitServi
import { Logger } from '../logger';
import { Messages } from '../messages';
import { Iterables } from '../system';
import { ActiveEditorCommand, command, Commands, getCommandUri } from './common';
import { ActiveEditorCommand, command, CommandContext, Commands, getCommandUri } from './common';
import { DiffWithCommandArgs } from './diffWith';
import { UriComparer } from '../comparers';

export interface DiffWithNextCommandArgs {
commit?: GitLogCommit;
range?: Range;

inDiffEditor?: boolean;
line?: number;
showOptions?: TextDocumentShowOptions;
}

@command()
export class DiffWithNextCommand extends ActiveEditorCommand {
constructor() {
super(Commands.DiffWithNext);
super([Commands.DiffWithNext, Commands.DiffWithNextInDiff]);
}

protected preExecute(context: CommandContext, args: DiffWithNextCommandArgs = {}) {
if (
context.command === Commands.DiffWithNextInDiff
// || (context.editor !== undefined && context.editor.viewColumn === undefined)
) {
// HACK: If in a diff, try to determine if we are on the right or left side
// If there is a context uri and it doesn't match the editor uri, assume we are on the left
// If on the left, use the editor uri and pretend we aren't in a diff
if (context.uri !== undefined && context.editor !== undefined && context.editor.document !== undefined) {
if (!UriComparer.equals(context.uri, context.editor.document.uri, { exact: true })) {
return this.execute(context.editor, context.editor.document.uri, args);
}
}
args.inDiffEditor = true;
}

return this.execute(context.editor, context.uri, args);
}

async execute(editor?: TextEditor, uri?: Uri, args: DiffWithNextCommandArgs = {}) {
Expand Down
14 changes: 13 additions & 1 deletion src/commands/diffWithPrevious.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Iterables } from '../system';
import { ActiveEditorCommand, command, CommandContext, Commands, getCommandUri } from './common';
import { DiffWithCommandArgs } from './diffWith';
import { DiffWithWorkingCommandArgs } from './diffWithWorking';
import { UriComparer } from '../comparers';

export interface DiffWithPreviousCommandArgs {
commit?: GitCommit;
Expand All @@ -24,7 +25,18 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand {
}

protected preExecute(context: CommandContext, args: DiffWithPreviousCommandArgs = {}) {
if (context.command === Commands.DiffWithPreviousInDiff) {
if (
context.command === Commands.DiffWithPreviousInDiff
// || (context.editor !== undefined && context.editor.viewColumn === undefined)
) {
// HACK: If in a diff, try to determine if we are on the right or left side
// If there is a context uri and it doesn't match the editor uri, assume we are on the left
// If on the left, use the editor uri and pretend we aren't in a diff
if (context.uri !== undefined && context.editor !== undefined && context.editor.document !== undefined) {
if (!UriComparer.equals(context.uri, context.editor.document.uri, { exact: true })) {
return this.execute(context.editor, context.editor.document.uri, args);
}
}
args.inDiffEditor = true;
}

Expand Down
44 changes: 40 additions & 4 deletions src/commands/diffWithWorking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,42 @@ import { Container } from '../container';
import { GitCommit, GitService, GitUri } from '../git/gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
import { ActiveEditorCommand, command, Commands, getCommandUri } from './common';
import { ActiveEditorCommand, command, CommandContext, Commands, getCommandUri } from './common';
import { DiffWithCommandArgs } from './diffWith';
import { UriComparer } from '../comparers';

export interface DiffWithWorkingCommandArgs {
commit?: GitCommit;

inDiffEditor?: boolean;
line?: number;
showOptions?: TextDocumentShowOptions;
}

@command()
export class DiffWithWorkingCommand extends ActiveEditorCommand {
constructor() {
super(Commands.DiffWithWorking);
super([Commands.DiffWithWorking, Commands.DiffWithWorkingInDiff]);
}

protected preExecute(context: CommandContext, args: DiffWithWorkingCommandArgs = {}) {
if (
context.command === Commands.DiffWithWorkingInDiff ||
(context.editor !== undefined && context.editor.viewColumn === undefined)
) {
// HACK: If in a diff, try to determine if we are on the right or left side
// If there is a context uri and it doesn't match the editor uri, assume we are on the left
// If on the left, use the editor uri and pretend we aren't in a diff
if (context.uri !== undefined && context.editor !== undefined && context.editor.document !== undefined) {
if (!UriComparer.equals(context.uri, context.editor.document.uri, { exact: true })) {
return this.execute(context.editor, context.editor.document.uri, args);
}
}

args.inDiffEditor = true;
}

return this.execute(context.editor, context.uri, args);
}

async execute(editor?: TextEditor, uri?: Uri, args: DiffWithWorkingCommandArgs = {}): Promise<any> {
Expand All @@ -44,10 +66,18 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand {

const status = await Container.git.getStatusForFile(gitUri.repoPath!, gitUri.fsPath);
if (status !== undefined && status.indexStatus !== undefined) {
let sha = GitService.stagedUncommittedSha;
if (args.inDiffEditor) {
const commit = await Container.git.getRecentLogCommitForFile(gitUri.repoPath!, gitUri.fsPath);
if (commit === undefined) return Messages.showCommitHasNoPreviousCommitWarningMessage();

sha = commit.sha;
}

const diffArgs: DiffWithCommandArgs = {
repoPath: gitUri.repoPath,
lhs: {
sha: GitService.stagedUncommittedSha,
sha: sha,
uri: gitUri.documentUri()
},
rhs: {
Expand All @@ -62,9 +92,15 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand {
}
}

// If we are in a diff editor, assume we are on the right side, and need to move back 2 revisions
let sha = gitUri.sha;
if (args.inDiffEditor && sha !== undefined) {
sha = `${sha}^`;
}

try {
args.commit = await Container.git.getLogCommitForFile(gitUri.repoPath, gitUri.fsPath, {
ref: gitUri.sha,
ref: sha,
firstIfNotFound: true
});
if (args.commit === undefined) {
Expand Down
5 changes: 4 additions & 1 deletion src/comparers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ abstract class Comparer<T> {
}

class UriComparer extends Comparer<Uri> {
equals(lhs: Uri | undefined, rhs: Uri | undefined) {
equals(lhs: Uri | undefined, rhs: Uri | undefined, options: { exact?: boolean } = { exact: false }) {
if (lhs === rhs) return true;
if (lhs === undefined || rhs === undefined) return false;

if (options.exact) {
return lhs.toString(true) === rhs.toString(true);
}
return lhs.scheme === rhs.scheme && lhs.fsPath === rhs.fsPath;
}
}
Expand Down

0 comments on commit 97c6509

Please sign in to comment.