You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
4.8 KiB

5 years ago
  1. 'use strict';
  2. import { window } from 'vscode';
  3. import { Commands, OpenInRemoteCommandArgs } from '../commands';
  4. import { GlyphChars } from '../constants';
  5. import {
  6. getNameFromRemoteResource,
  7. GitRemote,
  8. GitService,
  9. GitUri,
  10. RemoteResource,
  11. RemoteResourceType
  12. } from '../git/gitService';
  13. import { CommandQuickPickItem, getQuickPickIgnoreFocusOut } from './commonQuickPicks';
  14. export class OpenRemoteCommandQuickPickItem extends CommandQuickPickItem {
  15. private remote: GitRemote;
  16. private resource: RemoteResource;
  17. constructor(remote: GitRemote, resource: RemoteResource, public readonly clipboard?: boolean) {
  18. super(
  19. {
  20. label: clipboard
  21. ? `$(link-external) Copy ${getNameFromRemoteResource(resource)} Url to Clipboard from ${
  22. remote.provider!.name
  23. }`
  24. : `$(link-external) Open ${getNameFromRemoteResource(resource)} on ${remote.provider!.name}`,
  25. description: `$(repo) ${remote.provider!.path}`
  26. },
  27. undefined,
  28. undefined
  29. );
  30. this.remote = remote;
  31. this.resource = resource;
  32. }
  33. execute(): Thenable<{} | undefined> {
  34. if (this.clipboard) return this.remote.provider!.copy(this.resource);
  35. return this.remote.provider!.open(this.resource);
  36. }
  37. }
  38. export class OpenRemotesCommandQuickPickItem extends CommandQuickPickItem {
  39. constructor(remotes: GitRemote[], resource: RemoteResource, goBackCommand?: CommandQuickPickItem) {
  40. const name = getNameFromRemoteResource(resource);
  41. let description;
  42. switch (resource.type) {
  43. case RemoteResourceType.Branch:
  44. description = `$(git-branch) ${resource.branch}`;
  45. break;
  46. case RemoteResourceType.Branches:
  47. description = '$(git-branch) Branches';
  48. break;
  49. case RemoteResourceType.Commit:
  50. description = `$(git-commit) ${GitService.shortenSha(resource.sha)}`;
  51. break;
  52. case RemoteResourceType.File:
  53. description = GitUri.getFormattedPath(resource.fileName);
  54. break;
  55. case RemoteResourceType.Repo:
  56. description = '$(repo) Repository';
  57. break;
  58. case RemoteResourceType.Revision:
  59. if (resource.commit !== undefined && resource.commit.isFile) {
  60. if (resource.commit.status === 'D') {
  61. resource.sha = resource.commit.previousSha;
  62. description = `${GitUri.getFormattedPath(resource.fileName)} from ${
  63. GlyphChars.Space
  64. }$(git-commit) ${resource.commit.previousShortSha} (deleted in ${
  65. GlyphChars.Space
  66. }$(git-commit) ${resource.commit.shortSha})`;
  67. } else {
  68. resource.sha = resource.commit.sha;
  69. description = `${GitUri.getFormattedPath(resource.fileName)} from ${
  70. GlyphChars.Space
  71. }$(git-commit) ${resource.commit.shortSha}`;
  72. }
  73. } else {
  74. const shortFileSha = resource.sha === undefined ? '' : GitService.shortenSha(resource.sha);
  75. description = `${GitUri.getFormattedPath(resource.fileName)}${
  76. shortFileSha ? ` from ${GlyphChars.Space}$(git-commit) ${shortFileSha}` : ''
  77. }`;
  78. }
  79. break;
  80. default:
  81. description = '';
  82. break;
  83. }
  84. let remote: GitRemote | undefined;
  85. if (remotes.length > 1) {
  86. remote = remotes.find(r => r.default);
  87. } else if (remotes.length === 1) {
  88. remote = remotes[0];
  89. }
  90. if (remote != null) {
  91. const commandArgs: OpenInRemoteCommandArgs = {
  92. remotes: remotes,
  93. resource: resource,
  94. goBackCommand: goBackCommand
  95. };
  96. super(
  97. {
  98. label: `$(link-external) Open ${name} on ${remote.provider!.name}`,
  99. description: `${description} in ${GlyphChars.Space}$(repo) ${remote.provider!.path}`
  100. },
  101. Commands.OpenInRemote,
  102. [undefined, commandArgs]
  103. );
  104. return;
  105. }
  106. remote = remotes[0];
  107. // Use the real provider name if there is only 1 provider
  108. const provider = remotes.every(r => r.provider !== undefined && r.provider.name === remote!.provider!.name)
  109. ? remote.provider!.name
  110. : 'Remote';
  111. const commandArgs: OpenInRemoteCommandArgs = {
  112. remotes: remotes,
  113. resource: resource,
  114. goBackCommand: goBackCommand
  115. };
  116. super(
  117. {
  118. label: `$(link-external) Open ${name} on ${provider}${GlyphChars.Ellipsis}`,
  119. description: `${description}`
  120. },
  121. Commands.OpenInRemote,
  122. [undefined, commandArgs]
  123. );
  124. }
  125. }
  126. export class RemotesQuickPick {
  127. static async show(
  128. remotes: GitRemote[],
  129. placeHolder: string,
  130. resource: RemoteResource,
  131. clipboard?: boolean,
  132. goBackCommand?: CommandQuickPickItem
  133. ): Promise<OpenRemoteCommandQuickPickItem | CommandQuickPickItem | undefined> {
  134. const items = remotes.map(r => new OpenRemoteCommandQuickPickItem(r, resource, clipboard)) as (
  135. | OpenRemoteCommandQuickPickItem
  136. | CommandQuickPickItem
  137. )[];
  138. if (goBackCommand) {
  139. items.splice(0, 0, goBackCommand);
  140. }
  141. // const scope = await Container.keyboard.beginScope({ left: goBackCommand });
  142. const pick = await window.showQuickPick(items, {
  143. placeHolder: placeHolder,
  144. ignoreFocusOut: getQuickPickIgnoreFocusOut()
  145. });
  146. if (pick === undefined) return undefined;
  147. // await scope.dispose();
  148. return pick;
  149. }
  150. }