Skip to content

Commit

Permalink
Add 'open file' command to context menu on diff tab (#1135)
Browse files Browse the repository at this point in the history
* attempting to add a command to context menu but not successful

* implement opening on file from diff tab context menu

* Add className to diff widget title and implement more specific context menu selector

* Add caption to command `openFileFromDiff`

Co-authored-by: Frédéric Collonval <[email protected]>

* change contextMenuHitTest to test for nodeId 'git-diff...'

* Don't rely on dom node title and open file even if it is not currently modified

Co-authored-by: Frédéric Collonval <[email protected]>
Co-authored-by: Frédéric Collonval <[email protected]>
  • Loading branch information
3 people authored Jul 9, 2022
1 parent 0a50d7e commit 985d163
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 10 deletions.
6 changes: 6 additions & 0 deletions schema/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,12 @@
"label": "Git",
"icon": "git"
}
},
{
"type": "command",
"command": "git:open-file-from-diff",
"selector": ".jp-git-diff-title",
"rank": 1
}
]
}
Expand Down
52 changes: 51 additions & 1 deletion src/commandsAndMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ export function addCommands(
getDiffProvider(fullPath) ?? (isText && createPlainTextDiff);

if (buildDiffWidget) {
const id = `diff-${fullPath}-${model.reference.label}-${model.challenger.label}`;
const id = `git-diff-${fullPath}-${model.reference.label}-${model.challenger.label}`;
const mainAreaItems = shell.widgets('main');
let mainAreaItem = mainAreaItems.next();
while (mainAreaItem) {
Expand All @@ -519,6 +519,7 @@ export function addCommands(
diffWidget.title.caption = fullPath;
diffWidget.title.icon = diffIcon;
diffWidget.title.closable = true;
diffWidget.title.className = 'jp-git-diff-title';
diffWidget.addClass('jp-git-diff-parent-widget');

shell.add(diffWidget, 'main');
Expand Down Expand Up @@ -750,6 +751,55 @@ export function addCommands(
icon: openIcon.bindprops({ stylesheet: 'menuItem' })
});

commands.addCommand(ContextCommandIDs.openFileFromDiff, {
label: trans.__('Open File'),
caption: trans.__('Open file from its diff view'),
execute: async _ => {
const domNode = app.contextMenuHitTest((node: HTMLElement) => {
const nodeId = node.dataset.id;
return nodeId && nodeId.substring(0, 8) === 'git-diff';
});
if (!domNode) {
return;
}

const matches = toArray(shell.widgets('main')).filter(
widget => widget.id === domNode.dataset.id
);

if (matches.length === 0) {
return;
}

const diffModel = (
((matches[0] as MainAreaWidget).content as Panel)
.widgets[0] as Git.Diff.IDiffWidget
).model;

const filename = diffModel.filename;

if (
diffModel.reference.source === Git.Diff.SpecialRef.INDEX ||
diffModel.reference.source === Git.Diff.SpecialRef.WORKING ||
diffModel.challenger.source === Git.Diff.SpecialRef.INDEX ||
diffModel.challenger.source === Git.Diff.SpecialRef.WORKING
) {
const file = gitModel.status.files.find(
fileStatus => fileStatus.from === filename
);
if (file) {
commands.execute(ContextCommandIDs.gitFileOpen, {
files: [file]
} as any);
}
} else {
commands.execute('docmanager:open', {
path: gitModel.getRelativeFilePath(filename)
});
}
}
});

commands.addCommand(ContextCommandIDs.gitFileDiff, {
label: trans.__('Diff'),
caption: pluralizedContextLabel(
Expand Down
7 changes: 7 additions & 0 deletions src/components/diff/NotebookDiff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,13 @@ export class NotebookDiff extends Panel implements Git.Diff.IDiffWidget {
return this._model.hasConflict;
}

/**
* Diff model
*/
get model(): Git.Diff.IModel {
return this._model;
}

/**
* Nbdime notebook widget.
*/
Expand Down
7 changes: 7 additions & 0 deletions src/components/diff/PlainTextDiff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ export class PlainTextDiff extends Widget implements Git.Diff.IDiffWidget {
return true;
}

/**
* Diff model
*/
get model(): Git.Diff.IModel {
return this._model;
}

/**
* Promise which fulfills when the widget is ready.
*/
Expand Down
23 changes: 14 additions & 9 deletions src/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -568,20 +568,24 @@ export namespace Git {
*/
export interface IDiffWidget extends Widget {
/**
* Refresh the diff widget
*
* Note: Update the content and recompute the diff
*/
refresh(): Promise<void>;
/**
* Checks if the conflicted file has been resolved.
* Diff model
*/
isFileResolved: boolean;
readonly model: Git.Diff.IModel;
/**
* Gets the file model of a resolved merge conflict,
* and rejects if unable to retrieve
*/
getResolvedFile(): Promise<Partial<Contents.IModel>>;
/**
* Checks if the conflicted file has been resolved.
*/
readonly isFileResolved: boolean;
/**
* Refresh the diff widget
*
* Note: Update the content and recompute the diff
*/
refresh(): Promise<void>;
}

/**
Expand Down Expand Up @@ -1149,7 +1153,8 @@ export enum ContextCommandIDs {
gitFileHistory = 'git:context-history',
gitIgnore = 'git:context-ignore',
gitIgnoreExtension = 'git:context-ignoreExtension',
gitNoAction = 'git:no-action'
gitNoAction = 'git:no-action',
openFileFromDiff = 'git:open-file-from-diff'
}

/**
Expand Down

0 comments on commit 985d163

Please sign in to comment.