Skip to content

Commit 58700ab

Browse files
committed
Closes #467 - Adds copy remote url to clipboard command
1 parent 457ab38 commit 58700ab

File tree

10 files changed

+169
-56
lines changed

10 files changed

+169
-56
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
66

77
## [Unreleased] - 2018-08-16
8+
### Added
9+
- Adds *Copy Remote File Url to Clipboard* (`gitlens.copyRemoteFileUrlToClipboard`) command — copies the remote url of the current file and line to the clipboard — closes [#467](https://github.com/eamodio/vscode-gitlens/issues/467)
10+
811
### Fixed
912
- Fixes [#471](https://github.com/eamodio/vscode-gitlens/issues/471) - Don't use Ctrl+Alt+[character] as a shortcut
1013
- Fixes [#478](https://github.com/eamodio/vscode-gitlens/issues/478) - `suppressShowKeyBindingsNotice` gets saved even when it is not required

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ The repository view provides a full Git repository explorer, which has the follo
175175
- Context menus for each revision (commit) provide
176176
- *Open Commit in Remote* (if available), *Open All Changes*, *Open All Changes with Working Tree*, *Open Files*, *Open Revisions*, *Copy Commit ID to Clipboard*, *Copy Commit Message to Clipboard*, *Show Commit Details*, *Compare with HEAD*, *Compare with Working Tree*, *Compare with Selected* (when available), *Select for Compare*, *Cherry Pick Commit (via Terminal)* (when available), *Push to Commit (via Terminal)* (when available), *Revert Commit (via Terminal)* (when available), *Checkout Commit (via Terminal)*, *Rebase to Commit (via Terminal)*, *Reset to Commit (via Terminal)*, *Create Branch (via Terminal)...*, *Create Tag (via Terminal)...*, and *Refresh* commands
177177
- Context menus for each changed file provide
178-
- *Open Changes*, *Open Changes with Working File*, *Open File*, *Open Revision*, *Open File in Remote*, *Open Revision in Remote*, *Copy Commit ID to Clipboard*, *Copy Commit Message to Clipboard*, *Apply Changes*, *Compare with Selected* (when available), *Select for Compare*, and *Show Commit File Details* commands
178+
- *Open Changes*, *Open Changes with Working File*, *Open File*, *Open Revision*, *Open File in Remote*, *Open Revision in Remote*, *Copy Commit ID to Clipboard*, *Copy Commit Message to Clipboard*, *Copy Remote File Url to Clipboard*, *Apply Changes*, *Compare with Selected* (when available), *Select for Compare*, and *Show Commit File Details* commands
179179
- Inline toolbars for each changed file provide an *Open File* command
180180

181181
- **Remotes** — lists the remotes
@@ -250,7 +250,7 @@ An on-demand, [customizable](#gitlens-results-explorer-settings "Jump to the Git
250250
- Context menus for each revision (commit) provide
251251
- *Open Commit in Remote* (if available), *Open All Changes*, *Open All Changes with Working Tree*, *Open Files*, *Open Revisions*, *Copy Commit ID to Clipboard*, *Copy Commit Message to Clipboard*, *Show Commit Details*, *Compare with HEAD*, *Compare with Working Tree*, *Compare with Selected* (when available), *Select for Compare*, *Cherry Pick Commit (via Terminal)* (when available), *Push to Commit (via Terminal)* (when available), *Revert Commit (via Terminal)* (when available), *Checkout Commit (via Terminal)*, *Rebase to Commit (via Terminal)*, *Reset to Commit (via Terminal)*, *Create Branch (via Terminal)...*, *Create Tag (via Terminal)...*, and *Refresh* commands
252252
- Context menus for each changed file provide
253-
- *Open Changes*, *Open Changes with Working File*, *Open File*, *Open Revision*, *Open File in Remote*, *Open Revision in Remote*, *Copy Commit ID to Clipboard*, *Copy Commit Message to Clipboard*, *Apply Changes*, *Compare with Selected* (when available), *Select for Compare*, and *Show Commit File Details* commands
253+
- *Open Changes*, *Open Changes with Working File*, *Open File*, *Open Revision*, *Open File in Remote*, *Open Revision in Remote*, *Copy Commit ID to Clipboard*, *Copy Commit Message to Clipboard*, *Copy Remote File Url to Clipboard*, *Apply Changes*, *Compare with Selected* (when available), *Select for Compare*, and *Show Commit File Details* commands
254254

255255
#### Compare
256256
- Provides a semi-persistent results view for comparison operations
@@ -270,7 +270,7 @@ An on-demand, [customizable](#gitlens-results-explorer-settings "Jump to the Git
270270
- **Changed Files** — lists the files changed between the compared revisions (branches or commits)
271271
- Expands to a file-based view of all changed files
272272
- Context menus for each changed file provide
273-
- *Open Changes*, *Open Changes with Working File*, *Open File*, *Open Revision*, *Open File in Remote*, *Open Revision in Remote*, *Copy Commit ID to Clipboard*, *Copy Commit Message to Clipboard*, *Apply Changes*, *Compare with Selected* (when available), *Select for Compare*, and *Show Commit File Details* commands
273+
- *Open Changes*, *Open Changes with Working File*, *Open File*, *Open Revision*, *Open File in Remote*, *Open Revision in Remote*, *Copy Commit ID to Clipboard*, *Copy Commit Message to Clipboard*, *Copy Remote File Url to Clipboard*, *Apply Changes*, *Compare with Selected* (when available), *Select for Compare*, and *Show Commit File Details* commands
274274

275275
---
276276
### Code Lens
@@ -568,6 +568,8 @@ An on-demand, [customizable](#gitlens-results-explorer-settings "Jump to the Git
568568

569569
- Adds a *Copy Commit Message to Clipboard* command (`gitlens.copyMessageToClipboard`) to copy the commit message of the current line to the clipboard or from the most recent commit to the current branch, if there is no current editor
570570

571+
- Adds a *Copy Remote File Url to Clipboard* command (`gitlens.copyRemoteFileUrlToClipboard`) to copy the remote url of the current file and line to the clipboard
572+
571573
- Adds a *Open Working File"* command (`gitlens.openWorkingFile`) to open the working file for the current file revision
572574

573575
- Adds a *Open Revision...* command (`gitlens.openFileRevision`) to open the selected revision for the current file

package.json

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,13 +1710,18 @@
17101710
"category": "GitLens"
17111711
},
17121712
{
1713-
"command": "gitlens.copyShaToClipboard",
1714-
"title": "Copy Commit ID to Clipboard",
1713+
"command": "gitlens.copyMessageToClipboard",
1714+
"title": "Copy Commit Message to Clipboard",
17151715
"category": "GitLens"
17161716
},
17171717
{
1718-
"command": "gitlens.copyMessageToClipboard",
1719-
"title": "Copy Commit Message to Clipboard",
1718+
"command": "gitlens.copyRemoteFileUrlToClipboard",
1719+
"title": "Copy Remote File Url to Clipboard",
1720+
"category": "GitLens"
1721+
},
1722+
{
1723+
"command": "gitlens.copyShaToClipboard",
1724+
"title": "Copy Commit ID to Clipboard",
17201725
"category": "GitLens"
17211726
},
17221727
{
@@ -2325,11 +2330,15 @@
23252330
"when": "gitlens:enabled"
23262331
},
23272332
{
2328-
"command": "gitlens.copyShaToClipboard",
2333+
"command": "gitlens.copyMessageToClipboard",
23292334
"when": "gitlens:activeFileStatus =~ /blameable/"
23302335
},
23312336
{
2332-
"command": "gitlens.copyMessageToClipboard",
2337+
"command": "gitlens.copyRemoteFileUrlToClipboard",
2338+
"when": "gitlens:activeFileStatus =~ /tracked/ && gitlens:activeFileStatus =~ /remotes/"
2339+
},
2340+
{
2341+
"command": "gitlens.copyShaToClipboard",
23332342
"when": "gitlens:activeFileStatus =~ /blameable/"
23342343
},
23352344
{
@@ -2682,6 +2691,11 @@
26822691
"command": "gitlens.copyMessageToClipboard",
26832692
"when": "editorTextFocus && gitlens:activeFileStatus =~ /blameable/ && config.gitlens.menus.editor.clipboard",
26842693
"group": "9_gitlens@2"
2694+
},
2695+
{
2696+
"command": "gitlens.copyRemoteFileUrlToClipboard",
2697+
"when": "editorTextFocus && gitlens:activeFileStatus =~ /remotes/ && config.gitlens.menus.editor.clipboard",
2698+
"group": "9_gitlens@3"
26852699
}
26862700
],
26872701
"editor/title": [
@@ -2781,6 +2795,11 @@
27812795
"command": "gitlens.diffWithPrevious",
27822796
"when": "!explorerResourceIsRoot && !explorerResourceIsFolder && gitlens:enabled && config.gitlens.menus.explorer.compare",
27832797
"group": "3_compare@1"
2798+
},
2799+
{
2800+
"command": "gitlens.copyRemoteFileUrlToClipboard",
2801+
"when": "!explorerResourceIsRoot && !explorerResourceIsFolder && gitlens:enabled && gitlens:hasRemotes && config.gitlens.menus.explorer.remote",
2802+
"group": "9_gitlens@1"
27842803
}
27852804
],
27862805
"scm/resourceGroup/context": [
@@ -2840,6 +2859,11 @@
28402859
"command": "gitlens.stashSave",
28412860
"when": "gitlens:enabled",
28422861
"group": "2_gitlens@1"
2862+
},
2863+
{
2864+
"command": "gitlens.copyRemoteFileUrlToClipboard",
2865+
"when": "gitlens:enabled && gitlens:hasRemotes",
2866+
"group": "9_gitlens@1"
28432867
}
28442868
],
28452869
"view/title": [
@@ -3155,6 +3179,11 @@
31553179
"when": "viewItem =~ /gitlens:file\\b/ && gitlens:hasRemotes",
31563180
"group": "4_gitlens@1"
31573181
},
3182+
{
3183+
"command": "gitlens.copyRemoteFileUrlToClipboard",
3184+
"when": "viewItem =~ /gitlens:file\\b/ && gitlens:hasRemotes",
3185+
"group": "5_gitlens@3"
3186+
},
31583187
{
31593188
"command": "gitlens.explorers.openFileRevisionInRemote",
31603189
"when": "viewItem == gitlens:file:commit && gitlens:hasRemotes",
@@ -3165,6 +3194,11 @@
31653194
"when": "viewItem =~ /gitlens:(history-file|status:file)\\b/ && gitlens:hasRemotes",
31663195
"group": "3_gitlens@2"
31673196
},
3197+
{
3198+
"command": "gitlens.copyRemoteFileUrlToClipboard",
3199+
"when": "viewItem =~ /gitlens:(history-file|status:file)\\b/ && gitlens:hasRemotes",
3200+
"group": "5_gitlens@3"
3201+
},
31683202
{
31693203
"command": "gitlens.showQuickFileHistory",
31703204
"when": "viewItem =~ /gitlens:file\\b/ && gitlens:gitExplorer:view == repository",

src/commands.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export * from './commands/common';
77
export * from './commands/clearFileAnnotations';
88
export * from './commands/closeUnchangedFiles';
99
export * from './commands/copyMessageToClipboard';
10+
export * from './commands/copyRemoteFileUrlToClipboard';
1011
export * from './commands/copyShaToClipboard';
1112
export * from './commands/diffBranchWithBranch';
1213
export * from './commands/diffDirectory';
@@ -59,6 +60,7 @@ export function configureCommands(): void {
5960
Container.context.subscriptions.push(new Commands.ClearFileAnnotationsCommand());
6061
Container.context.subscriptions.push(new Commands.CloseUnchangedFilesCommand());
6162
Container.context.subscriptions.push(new Commands.CopyMessageToClipboardCommand());
63+
Container.context.subscriptions.push(new Commands.CopyRemoteFileUrlToClipboardCommand());
6264
Container.context.subscriptions.push(new Commands.CopyShaToClipboardCommand());
6365
Container.context.subscriptions.push(new Commands.DiffBranchWithBranchCommand());
6466
Container.context.subscriptions.push(new Commands.DiffDirectoryCommand());

src/commands/common.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export enum Commands {
2626
CloseUnchangedFiles = 'gitlens.closeUnchangedFiles',
2727
ComputingFileAnnotations = 'gitlens.computingFileAnnotations',
2828
CopyMessageToClipboard = 'gitlens.copyMessageToClipboard',
29+
CopyRemoteFileUrlToClipboard = 'gitlens.copyRemoteFileUrlToClipboard',
2930
CopyShaToClipboard = 'gitlens.copyShaToClipboard',
3031
DiffDirectory = 'gitlens.diffDirectory',
3132
DiffHeadWithBranch = 'gitlens.diffHeadWithBranch',
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use strict';
2+
import { commands, TextEditor, Uri } from 'vscode';
3+
import {
4+
ActiveEditorCommand,
5+
CommandContext,
6+
Commands,
7+
isCommandViewContextWithBranch,
8+
isCommandViewContextWithCommit
9+
} from './common';
10+
11+
export interface CopyRemoteFileUrlToClipboardCommandArgs {
12+
branch?: string;
13+
range?: boolean;
14+
}
15+
16+
export class CopyRemoteFileUrlToClipboardCommand extends ActiveEditorCommand {
17+
constructor() {
18+
super(Commands.CopyRemoteFileUrlToClipboard);
19+
}
20+
21+
protected async preExecute(
22+
context: CommandContext,
23+
args: CopyRemoteFileUrlToClipboardCommandArgs = { range: true }
24+
): Promise<any> {
25+
if (isCommandViewContextWithCommit(context)) {
26+
args = { ...args };
27+
args.range = false;
28+
if (isCommandViewContextWithBranch(context)) {
29+
args.branch = context.node.branch !== undefined ? context.node.branch.name : undefined;
30+
}
31+
return this.execute(context.editor, context.node.commit.uri, args);
32+
}
33+
34+
return this.execute(context.editor, context.uri, args);
35+
}
36+
37+
async execute(editor?: TextEditor, uri?: Uri, args: CopyRemoteFileUrlToClipboardCommandArgs = { range: true }) {
38+
return commands.executeCommand(Commands.OpenFileInRemote, uri, { ...args, clipboard: true });
39+
}
40+
}

src/commands/openFileInRemote.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { OpenInRemoteCommandArgs } from './openInRemote';
1818
export interface OpenFileInRemoteCommandArgs {
1919
branch?: string;
2020
range?: boolean;
21+
clipboard?: boolean;
2122
}
2223

2324
export class OpenFileInRemoteCommand extends ActiveEditorCommand {
@@ -57,7 +58,11 @@ export class OpenFileInRemoteCommand extends ActiveEditorCommand {
5758
if (branches.length > 1) {
5859
const pick = await BranchesQuickPick.show(
5960
branches,
60-
`Open ${gitUri.getRelativePath()} in remote for which branch${GlyphChars.Ellipsis}`
61+
args.clipboard
62+
? `Copy url for ${gitUri.getRelativePath()} to clipboard for which branch${
63+
GlyphChars.Ellipsis
64+
}`
65+
: `Open ${gitUri.getRelativePath()} in remote for which branch${GlyphChars.Ellipsis}`
6166
);
6267
if (pick === undefined) return undefined;
6368

@@ -92,7 +97,8 @@ export class OpenFileInRemoteCommand extends ActiveEditorCommand {
9297
range: range,
9398
sha: gitUri.sha
9499
},
95-
remotes
100+
remotes,
101+
clipboard: args.clipboard
96102
} as OpenInRemoteCommandArgs);
97103
}
98104
catch (ex) {

src/commands/openInRemote.ts

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export interface OpenInRemoteCommandArgs {
1111
remote?: string;
1212
remotes?: GitRemote[];
1313
resource?: RemoteResource;
14+
clipboard?: boolean;
1415

1516
goBackCommand?: CommandQuickPickItem;
1617
}
@@ -35,57 +36,60 @@ export class OpenInRemoteCommand extends ActiveEditorCommand {
3536
try {
3637
if (args.remotes.length === 1) {
3738
this.ensureRemoteBranchName(args);
38-
const command = new OpenRemoteCommandQuickPickItem(args.remotes[0], args.resource);
39+
const command = new OpenRemoteCommandQuickPickItem(args.remotes[0], args.resource, args.clipboard);
3940
return await command.execute();
4041
}
4142

43+
const verb = args.clipboard ? 'Copy url for' : 'Open';
44+
const suffix = args.clipboard ? `to clipboard from${GlyphChars.Ellipsis}` : `in${GlyphChars.Ellipsis}`;
4245
let placeHolder = '';
4346
switch (args.resource.type) {
4447
case RemoteResourceType.Branch:
4548
this.ensureRemoteBranchName(args);
46-
placeHolder = `open ${args.resource.branch} branch in${GlyphChars.Ellipsis}`;
49+
placeHolder = `${verb} ${args.resource.branch} branch ${suffix}`;
4750
break;
4851

4952
case RemoteResourceType.Commit:
5053
const shortSha = GitService.shortenSha(args.resource.sha);
51-
placeHolder = `open commit ${shortSha} in${GlyphChars.Ellipsis}`;
54+
placeHolder = `${verb} commit ${shortSha} ${suffix}`;
5255
break;
5356

5457
case RemoteResourceType.File:
55-
placeHolder = `open ${args.resource.fileName} in${GlyphChars.Ellipsis}`;
58+
placeHolder = `${verb} ${args.resource.fileName} ${suffix}`;
5659
break;
5760

5861
case RemoteResourceType.Revision:
5962
if (args.resource.commit !== undefined && args.resource.commit instanceof GitLogCommit) {
6063
if (args.resource.commit.status === 'D') {
6164
args.resource.sha = args.resource.commit.previousSha;
62-
placeHolder = `open ${args.resource.fileName} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${
65+
placeHolder = `${verb} ${args.resource.fileName} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${
6366
args.resource.commit.previousShortSha
64-
} in${GlyphChars.Ellipsis}`;
67+
} ${suffix}`;
6568
}
6669
else {
6770
args.resource.sha = args.resource.commit.sha;
68-
placeHolder = `open ${args.resource.fileName} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${
71+
placeHolder = `${verb} ${args.resource.fileName} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${
6972
args.resource.commit.shortSha
70-
} in${GlyphChars.Ellipsis}`;
73+
} ${suffix}`;
7174
}
7275
}
7376
else {
7477
const shortFileSha =
7578
args.resource.sha === undefined ? '' : GitService.shortenSha(args.resource.sha);
7679
const shaSuffix = shortFileSha ? ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${shortFileSha}` : '';
7780

78-
placeHolder = `open ${args.resource.fileName}${shaSuffix} in${GlyphChars.Ellipsis}`;
81+
placeHolder = `${verb} ${args.resource.fileName}${shaSuffix} ${suffix}`;
7982
}
8083
break;
8184
}
8285

83-
if (args.remotes.length === 1) {
84-
const command = new OpenRemoteCommandQuickPickItem(args.remotes[0], args.resource);
85-
return await command.execute();
86-
}
87-
88-
const pick = await RemotesQuickPick.show(args.remotes, placeHolder, args.resource, args.goBackCommand);
86+
const pick = await RemotesQuickPick.show(
87+
args.remotes,
88+
placeHolder,
89+
args.resource,
90+
args.clipboard,
91+
args.goBackCommand
92+
);
8993
if (pick === undefined) return undefined;
9094

9195
return await pick.execute();

0 commit comments

Comments
 (0)