選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

186 行
5.9 KiB

  1. 'use strict';
  2. import { ConfigurationTarget, env, MessageItem, Uri, window } from 'vscode';
  3. import { configuration } from './configuration';
  4. import { GitCommit } from './git/git';
  5. import { Logger } from './logger';
  6. export enum SuppressedMessages {
  7. CommitHasNoPreviousCommitWarning = 'suppressCommitHasNoPreviousCommitWarning',
  8. CommitNotFoundWarning = 'suppressCommitNotFoundWarning',
  9. FileNotUnderSourceControlWarning = 'suppressFileNotUnderSourceControlWarning',
  10. GitDisabledWarning = 'suppressGitDisabledWarning',
  11. GitVersionWarning = 'suppressGitVersionWarning',
  12. LineUncommittedWarning = 'suppressLineUncommittedWarning',
  13. NoRepositoryWarning = 'suppressNoRepositoryWarning',
  14. }
  15. export class Messages {
  16. static showCommitHasNoPreviousCommitWarningMessage(commit?: GitCommit): Promise<MessageItem | undefined> {
  17. if (commit === undefined) {
  18. return Messages.showMessage(
  19. 'info',
  20. 'There is no previous commit.',
  21. SuppressedMessages.CommitHasNoPreviousCommitWarning,
  22. );
  23. }
  24. return Messages.showMessage(
  25. 'info',
  26. `Commit ${commit.shortSha} (${commit.author}, ${commit.formattedDate}) has no previous commit.`,
  27. SuppressedMessages.CommitHasNoPreviousCommitWarning,
  28. );
  29. }
  30. static showCommitNotFoundWarningMessage(message: string): Promise<MessageItem | undefined> {
  31. return Messages.showMessage(
  32. 'warn',
  33. `${message}. The commit could not be found.`,
  34. SuppressedMessages.CommitNotFoundWarning,
  35. );
  36. }
  37. static async showGenericErrorMessage(message: string): Promise<MessageItem | undefined> {
  38. const actions: MessageItem[] = [{ title: 'Open Output Channel' }];
  39. const result = await Messages.showMessage(
  40. 'error',
  41. `${message}. See output channel for more details`,
  42. undefined,
  43. null,
  44. ...actions,
  45. );
  46. if (result !== undefined) {
  47. Logger.showOutputChannel();
  48. }
  49. return result;
  50. }
  51. static showFileNotUnderSourceControlWarningMessage(message: string): Promise<MessageItem | undefined> {
  52. return Messages.showMessage(
  53. 'warn',
  54. `${message}. The file is probably not under source control.`,
  55. SuppressedMessages.FileNotUnderSourceControlWarning,
  56. );
  57. }
  58. static showGitDisabledErrorMessage() {
  59. return Messages.showMessage(
  60. 'error',
  61. 'GitLens requires Git to be enabled. Please re-enable Git \u2014 set `git.enabled` to true and reload',
  62. SuppressedMessages.GitDisabledWarning,
  63. );
  64. }
  65. static showGitVersionUnsupportedErrorMessage(version: string, required: string): Promise<MessageItem | undefined> {
  66. return Messages.showMessage(
  67. 'error',
  68. `GitLens requires a newer version of Git (>= ${required}) than is currently installed (${version}). Please install a more recent version of Git.`,
  69. SuppressedMessages.GitVersionWarning,
  70. );
  71. }
  72. static showLineUncommittedWarningMessage(message: string): Promise<MessageItem | undefined> {
  73. return Messages.showMessage(
  74. 'warn',
  75. `${message}. The line has uncommitted changes.`,
  76. SuppressedMessages.LineUncommittedWarning,
  77. );
  78. }
  79. static showNoRepositoryWarningMessage(message: string): Promise<MessageItem | undefined> {
  80. return Messages.showMessage(
  81. 'warn',
  82. `${message}. No repository could be found.`,
  83. SuppressedMessages.NoRepositoryWarning,
  84. );
  85. }
  86. static async showWhatsNewMessage(version: string) {
  87. const actions: MessageItem[] = [{ title: "What's New" }, { title: 'Release Notes' }, { title: '❤' }];
  88. const result = await Messages.showMessage(
  89. 'info',
  90. `GitLens has been updated to v${version} — check out what's new!`,
  91. undefined,
  92. null,
  93. ...actions,
  94. );
  95. if (result != null) {
  96. if (result === actions[0]) {
  97. await env.openExternal(Uri.parse('https://gitlens.amod.io/#whats-new'));
  98. } else if (result === actions[1]) {
  99. await env.openExternal(Uri.parse('https://github.com/eamodio/vscode-gitlens/blob/master/CHANGELOG.md'));
  100. } else if (result === actions[2]) {
  101. await env.openExternal(Uri.parse('https://gitlens.amod.io/#sponsor'));
  102. }
  103. }
  104. }
  105. private static async showMessage(
  106. type: 'info' | 'warn' | 'error',
  107. message: string,
  108. suppressionKey?: SuppressedMessages,
  109. dontShowAgain: MessageItem | null = { title: "Don't Show Again" },
  110. ...actions: MessageItem[]
  111. ): Promise<MessageItem | undefined> {
  112. Logger.log(`ShowMessage(${type}, '${message}', ${suppressionKey}, ${JSON.stringify(dontShowAgain)})`);
  113. if (suppressionKey !== undefined && configuration.get('advanced', 'messages', suppressionKey)) {
  114. Logger.log(
  115. `ShowMessage(${type}, '${message}', ${suppressionKey}, ${JSON.stringify(dontShowAgain)}) skipped`,
  116. );
  117. return undefined;
  118. }
  119. if (suppressionKey !== undefined && dontShowAgain !== null) {
  120. actions.push(dontShowAgain);
  121. }
  122. let result: MessageItem | undefined = undefined;
  123. switch (type) {
  124. case 'info':
  125. result = await window.showInformationMessage(message, ...actions);
  126. break;
  127. case 'warn':
  128. result = await window.showWarningMessage(message, ...actions);
  129. break;
  130. case 'error':
  131. result = await window.showErrorMessage(message, ...actions);
  132. break;
  133. }
  134. if ((suppressionKey !== undefined && dontShowAgain === null) || result === dontShowAgain) {
  135. Logger.log(
  136. `ShowMessage(${type}, '${message}', ${suppressionKey}, ${JSON.stringify(
  137. dontShowAgain,
  138. )}) don't show again requested`,
  139. );
  140. await this.suppressedMessage(suppressionKey!);
  141. if (result === dontShowAgain) return undefined;
  142. }
  143. Logger.log(
  144. `ShowMessage(${type}, '${message}', ${suppressionKey}, ${JSON.stringify(dontShowAgain)}) returned ${
  145. result != null ? result.title : result
  146. }`,
  147. );
  148. return result;
  149. }
  150. private static suppressedMessage(suppressionKey: SuppressedMessages) {
  151. const messages: Record<string, boolean | undefined> = configuration.get('advanced', 'messages');
  152. messages[suppressionKey] = true;
  153. for (const [key, value] of Object.entries(messages)) {
  154. if (value !== true) {
  155. messages[key] = undefined;
  156. }
  157. }
  158. return configuration.update('advanced', 'messages', messages as any, ConfigurationTarget.Global);
  159. }
  160. }