diff --git a/package.json b/package.json index f7370f0..4395fce 100644 --- a/package.json +++ b/package.json @@ -872,6 +872,11 @@ "command": "gitlens.stashSave", "title": "Stash Changes", "category": "GitLens" + }, + { + "command": "gitlens.resetSuppressedWarnings", + "title": "Reset Suppressed Warnings", + "category": "GitLens" } ], "menus": { @@ -1003,6 +1008,10 @@ { "command": "gitlens.stashSave", "when": "gitlens:enabled" + }, + { + "command": "gitlens.resetSuppressedWarnings", + "when": "gitlens:enabled" } ], "editor/context": [ diff --git a/src/commands.ts b/src/commands.ts index a84e773..88aa41d 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -19,6 +19,7 @@ export * from './commands/openCommitInRemote'; export * from './commands/openFileInRemote'; export * from './commands/openInRemote'; export * from './commands/openRepoInRemote'; +export * from './commands/resetSuppressedWarnings'; export * from './commands/showBlameHistory'; export * from './commands/showFileBlame'; export * from './commands/showFileHistory'; diff --git a/src/commands/closeUnchangedFiles.ts b/src/commands/closeUnchangedFiles.ts index ed69ff7..020eca1 100644 --- a/src/commands/closeUnchangedFiles.ts +++ b/src/commands/closeUnchangedFiles.ts @@ -6,6 +6,7 @@ import { TextEditorComparer, UriComparer } from '../comparers'; import { BuiltInCommands } from '../constants'; import { GitService } from '../gitService'; import { Logger } from '../logger'; +import { Messages } from '../messages'; export interface CloseUnchangedFilesCommandArgs { uris?: Uri[]; @@ -23,7 +24,7 @@ export class CloseUnchangedFilesCommand extends ActiveEditorCommand { try { if (args.uris === undefined) { const repoPath = await this.git.getRepoPathFromUri(uri); - if (!repoPath) return window.showWarningMessage(`Unable to close unchanged files`); + if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to close unchanged files`); const status = await this.git.getStatusForRepo(repoPath); if (status === undefined) return window.showWarningMessage(`Unable to close unchanged files`); diff --git a/src/commands/common.ts b/src/commands/common.ts index af95eb6..7d326bf 100644 --- a/src/commands/common.ts +++ b/src/commands/common.ts @@ -20,6 +20,7 @@ export type Commands = 'gitlens.closeUnchangedFiles' | 'gitlens.openFileInRemote' | 'gitlens.openInRemote' | 'gitlens.openRepoInRemote' | + 'gitlens.resetSuppressedWarnings' | 'gitlens.showBlameHistory' | 'gitlens.showCommitSearch' | 'gitlens.showFileBlame' | @@ -56,6 +57,7 @@ export const Commands = { OpenFileInRemote: 'gitlens.openFileInRemote' as Commands, OpenInRemote: 'gitlens.openInRemote' as Commands, OpenRepoInRemote: 'gitlens.openRepoInRemote' as Commands, + ResetSuppressedWarnings: 'gitlens.resetSuppressedWarnings' as Commands, ShowBlameHistory: 'gitlens.showBlameHistory' as Commands, ShowCommitSearch: 'gitlens.showCommitSearch' as Commands, ShowFileBlame: 'gitlens.showFileBlame' as Commands, diff --git a/src/commands/diffDirectory.ts b/src/commands/diffDirectory.ts index 8461186..7dc5767 100644 --- a/src/commands/diffDirectory.ts +++ b/src/commands/diffDirectory.ts @@ -5,6 +5,7 @@ import { ActiveEditorCommand, Commands, getCommandUri } from './common'; import { BuiltInCommands } from '../constants'; import { GitService } from '../gitService'; import { Logger } from '../logger'; +import { Messages } from '../messages'; import { BranchesQuickPick, CommandQuickPickItem } from '../quickPicks'; export interface DiffDirectoryCommandCommandArgs { @@ -31,7 +32,7 @@ export class DiffDirectoryCommand extends ActiveEditorCommand { try { const repoPath = await this.git.getRepoPathFromUri(uri); - if (!repoPath) return window.showWarningMessage(`Unable to open directory compare`); + if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to open directory compare`); if (!args.shaOrBranch1) { const branches = await this.git.getBranches(repoPath); diff --git a/src/commands/diffLineWithPrevious.ts b/src/commands/diffLineWithPrevious.ts index 82a43d5..972666e 100644 --- a/src/commands/diffLineWithPrevious.ts +++ b/src/commands/diffLineWithPrevious.ts @@ -6,6 +6,7 @@ import { DiffWithPreviousCommandArgs } from './diffWithPrevious'; import { DiffWithWorkingCommandArgs } from './diffWithWorking'; import { GitCommit, GitService, GitUri } from '../gitService'; import { Logger } from '../logger'; +import { Messages } from '../messages'; import * as path from 'path'; export interface DiffLineWithPreviousCommandArgs { @@ -35,7 +36,7 @@ export class DiffLineWithPreviousCommand extends ActiveEditorCommand { try { const blame = await this.git.getBlameForLine(gitUri, blameline); - if (blame === undefined) return window.showWarningMessage(`Unable to open compare. File is probably not under source control`); + if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); args.commit = blame.commit; diff --git a/src/commands/diffLineWithWorking.ts b/src/commands/diffLineWithWorking.ts index de7db94..4626a4a 100644 --- a/src/commands/diffLineWithWorking.ts +++ b/src/commands/diffLineWithWorking.ts @@ -3,6 +3,7 @@ import { commands, TextDocumentShowOptions, TextEditor, Uri, window } from 'vsco import { ActiveEditorCommand, Commands, getCommandUri } from './common'; import { DiffWithWorkingCommandArgs } from './diffWithWorking'; import { GitCommit, GitService, GitUri } from '../gitService'; +import { Messages } from '../messages'; import { Logger } from '../logger'; export interface DiffLineWithWorkingCommandArgs { @@ -32,7 +33,7 @@ export class DiffLineWithWorkingCommand extends ActiveEditorCommand { try { const blame = await this.git.getBlameForLine(gitUri, blameline); - if (blame === undefined) return window.showWarningMessage(`Unable to open compare. File is probably not under source control`); + if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); args.commit = blame.commit; // If the line is uncommitted, find the previous commit diff --git a/src/commands/diffWithBranch.ts b/src/commands/diffWithBranch.ts index 716a7e3..2fec80a 100644 --- a/src/commands/diffWithBranch.ts +++ b/src/commands/diffWithBranch.ts @@ -4,6 +4,7 @@ import { ActiveEditorCommand, Commands, getCommandUri } from './common'; import { BuiltInCommands } from '../constants'; import { GitService, GitUri } from '../gitService'; import { Logger } from '../logger'; +import { Messages } from '../messages'; import { BranchesQuickPick, CommandQuickPickItem } from '../quickPicks'; import * as path from 'path'; @@ -27,7 +28,7 @@ export class DiffWithBranchCommand extends ActiveEditorCommand { args.line = args.line || (editor === undefined ? 0 : editor.selection.active.line); const gitUri = await GitUri.fromUri(uri, this.git); - if (!gitUri.repoPath) return window.showWarningMessage(`Unable to open branch compare`); + if (!gitUri.repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to open branch compare`); const branches = await this.git.getBranches(gitUri.repoPath); const pick = await BranchesQuickPick.show(branches, `Compare ${path.basename(gitUri.fsPath)} to \u2026`, args.goBackCommand); diff --git a/src/commands/diffWithNext.ts b/src/commands/diffWithNext.ts index 5903862..f4809d5 100644 --- a/src/commands/diffWithNext.ts +++ b/src/commands/diffWithNext.ts @@ -5,6 +5,7 @@ import { ActiveEditorCommand, Commands, getCommandUri } from './common'; import { BuiltInCommands } from '../constants'; import { GitLogCommit, GitService, GitUri } from '../gitService'; import { Logger } from '../logger'; +import { Messages } from '../messages'; import * as path from 'path'; export interface DiffWithNextCommandArgs { @@ -38,7 +39,7 @@ export class DiffWithNextCommand extends ActiveEditorCommand { const sha = args.commit === undefined ? gitUri.sha : args.commit.sha; const log = await this.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, undefined, sha !== undefined ? undefined : 2, args.range!); - if (log === undefined) return window.showWarningMessage(`Unable to open compare. File is probably not under source control`); + if (log === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); args.commit = (sha && log.commits.get(sha)) || Iterables.first(log.commits.values()); } diff --git a/src/commands/diffWithPrevious.ts b/src/commands/diffWithPrevious.ts index 3e7205d..2b0727f 100644 --- a/src/commands/diffWithPrevious.ts +++ b/src/commands/diffWithPrevious.ts @@ -6,7 +6,7 @@ import { BuiltInCommands } from '../constants'; import { DiffWithWorkingCommandArgs } from './diffWithWorking'; import { GitCommit, GitService, GitUri } from '../gitService'; import { Logger } from '../logger'; -import * as moment from 'moment'; +import { Messages } from '../messages'; import * as path from 'path'; export interface DiffWithPreviousCommandArgs { @@ -35,7 +35,7 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand { const sha = args.commit === undefined ? gitUri.sha : args.commit.sha; const log = await this.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, undefined, sha !== undefined ? undefined : 2, args.range!); - if (log === undefined) return window.showWarningMessage(`Unable to open compare. File is probably not under source control`); + if (log === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); args.commit = (sha && log.commits.get(sha)) || Iterables.first(log.commits.values()); @@ -48,7 +48,7 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand { } } - if (args.commit.previousSha === undefined) return window.showInformationMessage(`Commit ${args.commit.shortSha} (${args.commit.author}, ${moment(args.commit.date).fromNow()}) has no previous commit`); + if (args.commit.previousSha === undefined) return Messages.showCommitHasNoPreviousCommitWarningMessage(args.commit); try { const [rhs, lhs] = await Promise.all([ diff --git a/src/commands/diffWithWorking.ts b/src/commands/diffWithWorking.ts index 629f0eb..ae3edac 100644 --- a/src/commands/diffWithWorking.ts +++ b/src/commands/diffWithWorking.ts @@ -4,6 +4,7 @@ import { ActiveEditorCommand, Commands, getCommandUri } from './common'; import { BuiltInCommands } from '../constants'; import { GitCommit, GitService, GitUri } from '../gitService'; import { Logger } from '../logger'; +import { Messages } from '../messages'; import * as path from 'path'; export interface DiffWithWorkingCommandArgs { @@ -31,7 +32,7 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand { try { args.commit = await this.git.getLogCommit(gitUri.repoPath, gitUri.fsPath, gitUri.sha, { firstIfMissing: true }); - if (args.commit === undefined) return window.showWarningMessage(`Unable to open compare. File is probably not under source control`); + if (args.commit === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); } catch (ex) { Logger.error(ex, 'DiffWithWorkingCommand', `getLogCommit(${gitUri.repoPath}, ${gitUri.fsPath}, ${gitUri.sha})`); diff --git a/src/commands/openChangedFiles.ts b/src/commands/openChangedFiles.ts index 164a971..0341a02 100644 --- a/src/commands/openChangedFiles.ts +++ b/src/commands/openChangedFiles.ts @@ -3,6 +3,7 @@ import { TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode'; import { ActiveEditorCommand, Commands, getCommandUri, openEditor } from './common'; import { GitService } from '../gitService'; import { Logger } from '../logger'; +import { Messages } from '../messages'; export interface OpenChangedFilesCommandArgs { uris?: Uri[]; @@ -20,7 +21,7 @@ export class OpenChangedFilesCommand extends ActiveEditorCommand { try { if (args.uris === undefined) { const repoPath = await this.git.getRepoPathFromUri(uri); - if (!repoPath) return window.showWarningMessage(`Unable to open changed files`); + if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to open changed files`); const status = await this.git.getStatusForRepo(repoPath); if (status === undefined) return window.showWarningMessage(`Unable to open changed files`); diff --git a/src/commands/openCommitInRemote.ts b/src/commands/openCommitInRemote.ts index 9e683dc..90bc170 100644 --- a/src/commands/openCommitInRemote.ts +++ b/src/commands/openCommitInRemote.ts @@ -4,6 +4,7 @@ import { commands, TextEditor, TextEditorEdit, Uri, window } from 'vscode'; import { ActiveEditorCommand, Commands, getCommandUri } from './common'; import { GitCommit, GitService, GitUri } from '../gitService'; import { Logger } from '../logger'; +import { Messages } from '../messages'; import { OpenInRemoteCommandArgs } from './openInRemote'; export class OpenCommitInRemoteCommand extends ActiveEditorCommand { @@ -27,7 +28,7 @@ export class OpenCommitInRemoteCommand extends ActiveEditorCommand { if (blameline < 0) return undefined; const blame = await this.git.getBlameForLine(gitUri, blameline); - if (blame === undefined) return window.showWarningMessage(`Unable to open commit in remote provider. File is probably not under source control`); + if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open commit in remote provider'); let commit = blame.commit; // If the line is uncommitted, find the previous commit diff --git a/src/commands/resetSuppressedWarnings.ts b/src/commands/resetSuppressedWarnings.ts new file mode 100644 index 0000000..999f66a --- /dev/null +++ b/src/commands/resetSuppressedWarnings.ts @@ -0,0 +1,18 @@ +'use strict'; +import { Objects } from '../system'; +import { ExtensionContext } from 'vscode'; +import { Command, Commands } from './common'; +import { SuppressedKeys } from '../messages'; + +export class ResetSuppressedWarningsCommand extends Command { + + constructor(private context: ExtensionContext) { + super(Commands.ResetSuppressedWarnings); + } + + async execute() { + for (const key of Objects.values(SuppressedKeys)) { + await this.context.globalState.update(key, false); + } + } +} \ No newline at end of file diff --git a/src/commands/showBlameHistory.ts b/src/commands/showBlameHistory.ts index cd7b8a6..d55c41b 100644 --- a/src/commands/showBlameHistory.ts +++ b/src/commands/showBlameHistory.ts @@ -3,6 +3,7 @@ import { commands, Position, Range, TextEditor, TextEditorEdit, Uri, window } fr import { Commands, EditorCommand, getCommandUri } from './common'; import { BuiltInCommands } from '../constants'; import { GitService, GitUri } from '../gitService'; +import { Messages } from '../messages'; import { Logger } from '../logger'; export interface ShowBlameHistoryCommandArgs { @@ -32,7 +33,7 @@ export class ShowBlameHistoryCommand extends EditorCommand { try { const locations = await this.git.getBlameLocations(gitUri, args.range, args.sha, args.line); - if (locations === undefined) return window.showWarningMessage(`Unable to show blame history. File is probably not under source control`); + if (locations === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show blame history'); return commands.executeCommand(BuiltInCommands.ShowReferences, uri, args.position, locations); } diff --git a/src/commands/showCommitSearch.ts b/src/commands/showCommitSearch.ts index b4810e5..f6adfca 100644 --- a/src/commands/showCommitSearch.ts +++ b/src/commands/showCommitSearch.ts @@ -3,6 +3,7 @@ import { commands, InputBoxOptions, TextEditor, Uri, window } from 'vscode'; import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common'; import { GitRepoSearchBy, GitService, GitUri } from '../gitService'; import { Logger } from '../logger'; +import { Messages } from '../messages'; import { CommandQuickPickItem, CommitsQuickPick } from '../quickPicks'; import { ShowQuickCommitDetailsCommandArgs } from './showQuickCommitDetails'; import { paste } from 'copy-paste'; @@ -33,7 +34,7 @@ export class ShowCommitSearchCommand extends ActiveEditorCachedCommand { const gitUri = uri === undefined ? undefined : await GitUri.fromUri(uri, this.git); const repoPath = gitUri === undefined ? this.git.repoPath : gitUri.repoPath; - if (!repoPath) return window.showWarningMessage(`Unable to show commit search`); + if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to show commit search`); if (!args.search || args.searchBy == null) { try { diff --git a/src/commands/showFileHistory.ts b/src/commands/showFileHistory.ts index f4c2003..5627b08 100644 --- a/src/commands/showFileHistory.ts +++ b/src/commands/showFileHistory.ts @@ -3,6 +3,7 @@ import { commands, Position, Range, TextEditor, TextEditorEdit, Uri, window } fr import { Commands, EditorCommand, getCommandUri } from './common'; import { BuiltInCommands } from '../constants'; import { GitService, GitUri } from '../gitService'; +import { Messages } from '../messages'; import { Logger } from '../logger'; export interface ShowFileHistoryCommandArgs { @@ -30,7 +31,7 @@ export class ShowFileHistoryCommand extends EditorCommand { try { const locations = await this.git.getLogLocations(gitUri, args.sha, args.line); - if (locations === undefined) return window.showWarningMessage(`Unable to show file history. File is probably not under source control`); + if (locations === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show file history'); return commands.executeCommand(BuiltInCommands.ShowReferences, uri, args.position, locations); } diff --git a/src/commands/showQuickBranchHistory.ts b/src/commands/showQuickBranchHistory.ts index 0f2d9e9..ef9a7e0 100644 --- a/src/commands/showQuickBranchHistory.ts +++ b/src/commands/showQuickBranchHistory.ts @@ -3,6 +3,7 @@ import { commands, TextEditor, Uri, window } from 'vscode'; import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common'; import { GitService, GitUri, IGitLog } from '../gitService'; import { Logger } from '../logger'; +import { Messages } from '../messages'; import { BranchesQuickPick, BranchHistoryQuickPick, CommandQuickPickItem } from '../quickPicks'; import { ShowQuickCommitDetailsCommandArgs } from './showQuickCommitDetails'; @@ -33,7 +34,7 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand { let progressCancellation = args.branch === undefined ? undefined : BranchHistoryQuickPick.showProgress(args.branch); try { const repoPath = gitUri === undefined ? this.git.repoPath : gitUri.repoPath; - if (!repoPath) return window.showWarningMessage(`Unable to show branch history`); + if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to show branch history`); if (args.branch === undefined) { const branches = await this.git.getBranches(repoPath); diff --git a/src/commands/showQuickCommitDetails.ts b/src/commands/showQuickCommitDetails.ts index 681bb4d..269633a 100644 --- a/src/commands/showQuickCommitDetails.ts +++ b/src/commands/showQuickCommitDetails.ts @@ -5,6 +5,7 @@ import { GitCommit, GitLogCommit, GitService, GitUri, IGitLog } from '../gitServ import { Logger } from '../logger'; import { CommandQuickPickItem, CommitDetailsQuickPick, CommitWithFileStatusQuickPickItem } from '../quickPicks'; import { ShowQuickCommitFileDetailsCommandArgs } from './showQuickCommitFileDetails'; +import { Messages } from '../messages'; import * as path from 'path'; export interface ShowQuickCommitDetailsCommandArgs { @@ -38,9 +39,12 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand { try { const blame = await this.git.getBlameForLine(gitUri, blameline); - if (blame === undefined) return window.showWarningMessage(`Unable to show commit details. File is probably not under source control`); + if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show commit details'); - args.sha = blame.commit.isUncommitted ? blame.commit.previousSha : blame.commit.sha; + // Because the previous sha of an uncommitted file isn't trust worthy we just have to kick out + if (blame.commit.isUncommitted) return Messages.showLineUncommittedWarningMessage('Unable to show commit details'); + + args.sha = blame.commit.sha; repoPath = blame.commit.repoPath; workingFileName = blame.commit.fileName; @@ -64,13 +68,13 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand { if (args.repoLog === undefined) { const log = await this.git.getLogForRepo(repoPath!, args.sha, 2); - if (log === undefined) return window.showWarningMessage(`Unable to show commit details`); + if (log === undefined) return Messages.showCommitNotFoundWarningMessage(`Unable to show commit details`); args.commit = log.commits.get(args.sha!); } } - if (args.commit === undefined) return window.showWarningMessage(`Unable to show commit details`); + if (args.commit === undefined) return Messages.showCommitNotFoundWarningMessage(`Unable to show commit details`); if (args.commit.workingFileName === undefined) { args.commit.workingFileName = workingFileName; diff --git a/src/commands/showQuickCommitFileDetails.ts b/src/commands/showQuickCommitFileDetails.ts index d56ca01..11dd8f3 100644 --- a/src/commands/showQuickCommitFileDetails.ts +++ b/src/commands/showQuickCommitFileDetails.ts @@ -5,6 +5,7 @@ import { GitCommit, GitLogCommit, GitService, GitUri, IGitLog } from '../gitServ import { Logger } from '../logger'; import { CommandQuickPickItem, CommitFileDetailsQuickPick } from '../quickPicks'; import { ShowQuickCommitDetailsCommandArgs } from './showQuickCommitDetails'; +import { Messages } from '../messages'; import * as path from 'path'; export interface ShowQuickCommitFileDetailsCommandArgs { @@ -37,9 +38,12 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCachedCommand try { const blame = await this.git.getBlameForLine(gitUri, blameline); - if (blame === undefined) return window.showWarningMessage(`Unable to show commit file details. File is probably not under source control`); + if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show commit file details'); - args.sha = blame.commit.isUncommitted ? blame.commit.previousSha : blame.commit.sha; + // Because the previous sha of an uncommitted file isn't trust worthy we just have to kick out + if (blame.commit.isUncommitted) return Messages.showLineUncommittedWarningMessage('Unable to show commit file details'); + + args.sha = blame.commit.sha; args.commit = blame.commit; workingFileName = path.relative(args.commit.repoPath, gitUri.fsPath); @@ -65,12 +69,12 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCachedCommand } if (args.fileLog === undefined) { - args.commit = await this.git.getLogCommit(args.commit ? args.commit.repoPath : gitUri.repoPath, gitUri.fsPath, args.sha, { previous: true }); - if (args.commit === undefined) return window.showWarningMessage(`Unable to show commit file details`); + args.commit = await this.git.getLogCommit(args.commit === undefined ? gitUri.repoPath : args.commit.repoPath, gitUri.fsPath, args.sha, { previous: true }); + if (args.commit === undefined) return Messages.showCommitNotFoundWarningMessage(`Unable to show commit file details`); } } - if (args.commit === undefined) return window.showWarningMessage(`Unable to show commit file details`); + if (args.commit === undefined) return Messages.showCommitNotFoundWarningMessage(`Unable to show commit file details`); // Attempt to the most recent commit -- so that we can find the real working filename if there was a rename args.commit.workingFileName = workingFileName; diff --git a/src/commands/showQuickCurrentBranchHistory.ts b/src/commands/showQuickCurrentBranchHistory.ts index 24eb71f..9973acf 100644 --- a/src/commands/showQuickCurrentBranchHistory.ts +++ b/src/commands/showQuickCurrentBranchHistory.ts @@ -4,6 +4,7 @@ import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common'; import { ShowQuickBranchHistoryCommandArgs } from './showQuickBranchHistory'; import { GitService } from '../gitService'; import { Logger } from '../logger'; +import { Messages } from '../messages'; import { CommandQuickPickItem } from '../quickPicks'; export interface ShowQuickCurrentBranchHistoryCommandArgs { @@ -21,7 +22,7 @@ export class ShowQuickCurrentBranchHistoryCommand extends ActiveEditorCachedComm try { const repoPath = await this.git.getRepoPathFromUri(uri); - if (!repoPath) return window.showWarningMessage(`Unable to show branch history`); + if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to show branch history`); const branch = await this.git.getBranch(repoPath); if (branch === undefined) return undefined; diff --git a/src/commands/showQuickFileHistory.ts b/src/commands/showQuickFileHistory.ts index 0cf16cf..4a6d84b 100644 --- a/src/commands/showQuickFileHistory.ts +++ b/src/commands/showQuickFileHistory.ts @@ -5,6 +5,7 @@ import { GitService, GitUri, IGitLog } from '../gitService'; import { Logger } from '../logger'; import { CommandQuickPickItem, FileHistoryQuickPick } from '../quickPicks'; import { ShowQuickCommitFileDetailsCommandArgs } from './showQuickCommitFileDetails'; +import { Messages } from '../messages'; import * as path from 'path'; export interface ShowQuickFileHistoryCommandArgs { @@ -36,7 +37,7 @@ export class ShowQuickFileHistoryCommand extends ActiveEditorCachedCommand { try { if (args.log === undefined) { args.log = await this.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, gitUri.sha, args.maxCount, args.range); - if (args.log === undefined) return window.showWarningMessage(`Unable to show file history. File is probably not under source control`); + if (args.log === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show file history'); } if (progressCancellation.token.isCancellationRequested) return undefined; diff --git a/src/commands/showQuickRepoStatus.ts b/src/commands/showQuickRepoStatus.ts index 57a2659..a4cd30d 100644 --- a/src/commands/showQuickRepoStatus.ts +++ b/src/commands/showQuickRepoStatus.ts @@ -3,6 +3,7 @@ import { TextEditor, Uri, window } from 'vscode'; import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common'; import { GitService } from '../gitService'; import { Logger } from '../logger'; +import { Messages } from '../messages'; import { CommandQuickPickItem, RepoStatusQuickPick } from '../quickPicks'; export interface ShowQuickRepoStatusCommandArgs { @@ -20,7 +21,7 @@ export class ShowQuickRepoStatusCommand extends ActiveEditorCachedCommand { try { const repoPath = await this.git.getRepoPathFromUri(uri); - if (!repoPath) return window.showWarningMessage(`Unable to show repository status`); + if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to show repository status`); const status = await this.git.getStatusForRepo(repoPath); if (status === undefined) return window.showWarningMessage(`Unable to show repository status`); diff --git a/src/commands/showQuickStashList.ts b/src/commands/showQuickStashList.ts index ef43190..9864554 100644 --- a/src/commands/showQuickStashList.ts +++ b/src/commands/showQuickStashList.ts @@ -3,6 +3,7 @@ import { commands, TextEditor, Uri, window } from 'vscode'; import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common'; import { GitService, GitUri } from '../gitService'; import { Logger } from '../logger'; +import { Messages } from '../messages'; import { CommandQuickPickItem, StashListQuickPick } from '../quickPicks'; import { ShowQuickCommitDetailsCommandArgs } from './showQuickCommitDetails'; @@ -21,7 +22,7 @@ export class ShowQuickStashListCommand extends ActiveEditorCachedCommand { try { const repoPath = await this.git.getRepoPathFromUri(uri); - if (!repoPath) return window.showWarningMessage(`Unable to show stashed changes`); + if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to show stashed changes`); const stash = await this.git.getStashList(repoPath); if (stash === undefined) return window.showWarningMessage(`Unable to show stashed changes`); diff --git a/src/constants.ts b/src/constants.ts index 67c155d..93bf413 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,12 +1,12 @@ -'use strict'; - -export const ExtensionId = 'gitlens'; -export const ExtensionKey = ExtensionId; -export const ExtensionOutputChannelName = 'GitLens'; -export const QualifiedExtensionId = `eamodio.${ExtensionId}`; - -export const ApplicationInsightsKey = 'a9c302f8-6483-4d01-b92c-c159c799c679'; - +'use strict'; + +export const ExtensionId = 'gitlens'; +export const ExtensionKey = ExtensionId; +export const ExtensionOutputChannelName = 'GitLens'; +export const QualifiedExtensionId = `eamodio.${ExtensionId}`; + +export const ApplicationInsightsKey = 'a9c302f8-6483-4d01-b92c-c159c799c679'; + export type BuiltInCommands = 'cursorMove' | 'editor.action.showReferences' | 'editor.action.toggleRenderWhitespace' | @@ -21,34 +21,31 @@ export type BuiltInCommands = 'cursorMove' | 'workbench.action.closeActiveEditor' | 'workbench.action.closeAllEditors' | 'workbench.action.nextEditor'; -export const BuiltInCommands = { - CloseActiveEditor: 'workbench.action.closeActiveEditor' as BuiltInCommands, - CloseAllEditors: 'workbench.action.closeAllEditors' as BuiltInCommands, - CursorMove: 'cursorMove' as BuiltInCommands, - Diff: 'vscode.diff' as BuiltInCommands, - EditorScroll: 'editorScroll' as BuiltInCommands, - ExecuteDocumentSymbolProvider: 'vscode.executeDocumentSymbolProvider' as BuiltInCommands, - ExecuteCodeLensProvider: 'vscode.executeCodeLensProvider' as BuiltInCommands, - Open: 'vscode.open' as BuiltInCommands, - NextEditor: 'workbench.action.nextEditor' as BuiltInCommands, - PreviewHtml: 'vscode.previewHtml' as BuiltInCommands, - RevealLine: 'revealLine' as BuiltInCommands, - SetContext: 'setContext' as BuiltInCommands, - ShowReferences: 'editor.action.showReferences' as BuiltInCommands, - ToggleRenderWhitespace: 'editor.action.toggleRenderWhitespace' as BuiltInCommands -}; - -export type DocumentSchemes = 'file' | 'git' | 'gitlens-git'; -export const DocumentSchemes = { - File: 'file' as DocumentSchemes, - Git: 'git' as DocumentSchemes, - GitLensGit: 'gitlens-git' as DocumentSchemes -}; - -export type WorkspaceState = 'repoPath' | 'suppressGitVersionWarning' | 'suppressUpdateNotice' | 'suppressWelcomeNotice'; -export const WorkspaceState = { - GitLensVersion: 'gitlensVersion' as WorkspaceState, - SuppressGitVersionWarning: 'suppressGitVersionWarning' as WorkspaceState, - SuppressUpdateNotice: 'suppressUpdateNotice' as WorkspaceState, - SuppressWelcomeNotice: 'suppressWelcomeNotice' as WorkspaceState +export const BuiltInCommands = { + CloseActiveEditor: 'workbench.action.closeActiveEditor' as BuiltInCommands, + CloseAllEditors: 'workbench.action.closeAllEditors' as BuiltInCommands, + CursorMove: 'cursorMove' as BuiltInCommands, + Diff: 'vscode.diff' as BuiltInCommands, + EditorScroll: 'editorScroll' as BuiltInCommands, + ExecuteDocumentSymbolProvider: 'vscode.executeDocumentSymbolProvider' as BuiltInCommands, + ExecuteCodeLensProvider: 'vscode.executeCodeLensProvider' as BuiltInCommands, + Open: 'vscode.open' as BuiltInCommands, + NextEditor: 'workbench.action.nextEditor' as BuiltInCommands, + PreviewHtml: 'vscode.previewHtml' as BuiltInCommands, + RevealLine: 'revealLine' as BuiltInCommands, + SetContext: 'setContext' as BuiltInCommands, + ShowReferences: 'editor.action.showReferences' as BuiltInCommands, + ToggleRenderWhitespace: 'editor.action.toggleRenderWhitespace' as BuiltInCommands +}; + +export type DocumentSchemes = 'file' | 'git' | 'gitlens-git'; +export const DocumentSchemes = { + File: 'file' as DocumentSchemes, + Git: 'git' as DocumentSchemes, + GitLensGit: 'gitlens-git' as DocumentSchemes +}; + +export type WorkspaceState = 'gitlensVersion'; +export const WorkspaceState = { + GitLensVersion: 'gitlensVersion' as WorkspaceState }; \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index 1835ec9..ddb7780 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,12 +1,13 @@ 'use strict'; // import { Objects } from './system'; -import { commands, ExtensionContext, extensions, languages, Uri, window, workspace } from 'vscode'; +import { ExtensionContext, extensions, languages, window, workspace } from 'vscode'; import { AnnotationController } from './annotations/annotationController'; import { CommandContext, setCommandContext } from './commands'; import { CloseUnchangedFilesCommand, OpenChangedFilesCommand } from './commands'; import { OpenBranchInRemoteCommand, OpenCommitInRemoteCommand, OpenFileInRemoteCommand, OpenInRemoteCommand, OpenRepoInRemoteCommand } from './commands'; import { CopyMessageToClipboardCommand, CopyShaToClipboardCommand } from './commands'; import { DiffDirectoryCommand, DiffLineWithPreviousCommand, DiffLineWithWorkingCommand, DiffWithBranchCommand, DiffWithNextCommand, DiffWithPreviousCommand, DiffWithWorkingCommand} from './commands'; +import { ResetSuppressedWarningsCommand } from './commands'; import { ShowFileBlameCommand, ShowLineBlameCommand, ToggleFileBlameCommand, ToggleLineBlameCommand } from './commands'; import { ShowBlameHistoryCommand, ShowFileHistoryCommand } from './commands'; import { ShowLastQuickPickCommand } from './commands'; @@ -17,17 +18,19 @@ import { StashApplyCommand, StashDeleteCommand, StashSaveCommand } from './comma import { ToggleCodeLensCommand } from './commands'; import { Keyboard } from './commands'; import { BlameLineHighlightLocations, CodeLensLocations, IConfig, LineAnnotationType } from './configuration'; -import { ApplicationInsightsKey, BuiltInCommands, ExtensionKey, QualifiedExtensionId, WorkspaceState } from './constants'; +import { ApplicationInsightsKey, ExtensionKey, QualifiedExtensionId, WorkspaceState } from './constants'; import { CurrentLineController } from './currentLineController'; import { GitContentProvider } from './gitContentProvider'; import { GitContextTracker, GitService } from './gitService'; import { GitRevisionCodeLensProvider } from './gitRevisionCodeLensProvider'; import { Logger } from './logger'; +import { Messages, SuppressedKeys } from './messages'; import { Telemetry } from './telemetry'; // this method is called when your extension is activated export async function activate(context: ExtensionContext) { Logger.configure(context); + Messages.configure(context); Telemetry.configure(ApplicationInsightsKey); const gitlens = extensions.getExtension(QualifiedExtensionId)!; @@ -105,6 +108,7 @@ export async function activate(context: ExtensionContext) { context.subscriptions.push(new ShowLineBlameCommand(currentLineController)); context.subscriptions.push(new ToggleFileBlameCommand(annotationController)); context.subscriptions.push(new ToggleLineBlameCommand(currentLineController)); + context.subscriptions.push(new ResetSuppressedWarningsCommand(context)); context.subscriptions.push(new ShowBlameHistoryCommand(git)); context.subscriptions.push(new ShowFileHistoryCommand(git)); context.subscriptions.push(new ShowLastQuickPickCommand()); @@ -253,49 +257,25 @@ async function migrateSettings(context: ExtensionContext) { } async function notifyOnNewGitLensVersion(context: ExtensionContext, version: string) { - if (context.globalState.get(WorkspaceState.SuppressUpdateNotice, false)) return; + if (context.globalState.get(SuppressedKeys.UpdateNotice, false)) return; const previousVersion = context.globalState.get(WorkspaceState.GitLensVersion); - if (!context.globalState.get(WorkspaceState.SuppressWelcomeNotice, false)) { - await context.globalState.update(WorkspaceState.SuppressWelcomeNotice, true); - - if (previousVersion === undefined) { - const result = await window.showInformationMessage(`Thank you for choosing GitLens! GitLens is powerful, feature rich, and highly configurable, so please be sure to view the docs and tailor it to suit your needs.`, 'View Docs'); - if (result === 'View Docs') { - // TODO: Reset before release - // commands.executeCommand(BuiltInCommands.Open, Uri.parse('https://marketplace.visualstudio.com/items/eamodio.gitlens')); - commands.executeCommand(BuiltInCommands.Open, Uri.parse('https://github.com/eamodio/vscode-gitlens/blob/develop/README.md')); - } - return; - } + if (previousVersion === undefined) { + await Messages.showWelcomeMessage(); + return; } - if (previousVersion) { - const [major, minor] = version.split('.'); - const [prevMajor, prevMinor] = previousVersion.split('.'); - if (major === prevMajor && minor === prevMinor) return; - } + const [major, minor] = version.split('.'); + const [prevMajor, prevMinor] = previousVersion.split('.'); + if (major === prevMajor && minor === prevMinor) return; - const result = await window.showInformationMessage(`GitLens has been updated to v${version}`, 'View Release Notes', `Don't Show Again`); - if (result === 'View Release Notes') { - // TODO: Reset before release - // commands.executeCommand(BuiltInCommands.Open, Uri.parse('https://marketplace.visualstudio.com/items/eamodio.gitlens/changelog')); - commands.executeCommand(BuiltInCommands.Open, Uri.parse('https://github.com/eamodio/vscode-gitlens/blob/develop/CHANGELOG.md')); - } - else if (result === `Don't Show Again`) { - context.globalState.update(WorkspaceState.SuppressUpdateNotice, true); - } + await Messages.showUpdateMessage(version); } async function notifyOnUnsupportedGitVersion(context: ExtensionContext, version: string) { - if (context.globalState.get(WorkspaceState.SuppressGitVersionWarning, false)) return; + if (GitService.validateGitVersion(2, 2)) return; // If git is less than v2.2.0 - if (!GitService.validateGitVersion(2, 2)) { - const result = await window.showErrorMessage(`GitLens requires a newer version of Git (>= 2.2.0) than is currently installed (${version}). Please install a more recent version of Git.`, `Don't Show Again`); - if (result === `Don't Show Again`) { - context.globalState.update(WorkspaceState.SuppressGitVersionWarning, true); - } - } + await Messages.showUnsupportedGitVersionErrorMessage(version); } \ No newline at end of file diff --git a/src/messages.ts b/src/messages.ts new file mode 100644 index 0000000..7549d87 --- /dev/null +++ b/src/messages.ts @@ -0,0 +1,103 @@ +'use strict'; +import { commands, ExtensionContext, Uri, window } from 'vscode'; +import { BuiltInCommands } from './constants'; +import { GitCommit } from './gitService'; +import * as moment from 'moment'; + +export type SuppressedKeys = 'suppressCommitHasNoPreviousCommitWarning' | + 'suppressCommitNotFoundWarning' | + 'suppressFileNotUnderSourceControlWarning' | + 'suppressGitVersionWarning' | + 'suppressLineUncommittedWarning' | + 'suppressNoRepositoryWarning' | + 'suppressUpdateNotice'; +export const SuppressedKeys = { + CommitHasNoPreviousCommitWarning: 'suppressCommitHasNoPreviousCommitWarning' as SuppressedKeys, + CommitNotFoundWarning: 'suppressCommitNotFoundWarning' as SuppressedKeys, + FileNotUnderSourceControlWarning: 'suppressFileNotUnderSourceControlWarning' as SuppressedKeys, + GitVersionWarning: 'suppressGitVersionWarning' as SuppressedKeys, + LineUncommittedWarning: 'suppressLineUncommittedWarning' as SuppressedKeys, + NoRepositoryWarning: 'suppressNoRepositoryWarning' as SuppressedKeys, + UpdateNotice: 'suppressUpdateNotice' as SuppressedKeys +}; + +export class Messages { + + static context: ExtensionContext; + + static configure(context: ExtensionContext) { + this.context = context; + } + + static showCommitHasNoPreviousCommitWarningMessage(commit: GitCommit): Promise { + return Messages._showMessage('info', `Commit ${commit.shortSha} (${commit.author}, ${moment(commit.date).fromNow()}) has no previous commit`, SuppressedKeys.CommitHasNoPreviousCommitWarning); + } + + static showCommitNotFoundWarningMessage(message: string): Promise { + return Messages._showMessage('warn', `${message}. The commit could not be found`, SuppressedKeys.CommitNotFoundWarning); + } + + static showFileNotUnderSourceControlWarningMessage(message: string): Promise { + return Messages._showMessage('warn', `${message}. The file is probably not under source control`, SuppressedKeys.FileNotUnderSourceControlWarning); + } + + static showLineUncommittedWarningMessage(message: string): Promise { + return Messages._showMessage('warn', `${message}. The line has uncommitted changes`, SuppressedKeys.LineUncommittedWarning); + } + + static showNoRepositoryWarningMessage(message: string): Promise { + return Messages._showMessage('warn', `${message}. No repository could be found`, SuppressedKeys.NoRepositoryWarning); + } + + static showUnsupportedGitVersionErrorMessage(version: string): Promise { + return Messages._showMessage('error', `GitLens requires a newer version of Git (>= 2.2.0) than is currently installed (${version}). Please install a more recent version of Git.`, SuppressedKeys.GitVersionWarning); + } + + static async showUpdateMessage(version: string): Promise { + const viewReleaseNotes = 'View Release Notes'; + const result = await Messages._showMessage('info', `GitLens has been updated to v${version}`, SuppressedKeys.UpdateNotice, undefined, viewReleaseNotes); + if (result === viewReleaseNotes) { + commands.executeCommand(BuiltInCommands.Open, Uri.parse('https://marketplace.visualstudio.com/items/eamodio.gitlens/changelog')); + } + return result; + } + + static async showWelcomeMessage(): Promise { + const viewDocs = 'View Docs'; + const result = await window.showInformationMessage(`Thank you for choosing GitLens! GitLens is powerful, feature rich, and highly configurable, so please be sure to view the docs and tailor it to suit your needs.`, viewDocs); + if (result === viewDocs) { + commands.executeCommand(BuiltInCommands.Open, Uri.parse('https://marketplace.visualstudio.com/items/eamodio.gitlens')); + } + return result; + } + + private static async _showMessage(type: 'info' | 'warn' | 'error', message: string, suppressionKey: SuppressedKeys, dontShowAgain: string | null = 'Don\'t Show Again', ...actions: any[]): Promise { + if (Messages.context.globalState.get(suppressionKey, false)) return undefined; + + if (dontShowAgain !== null) { + actions.push(dontShowAgain); + } + + let result: string | undefined = undefined; + switch (type) { + case 'info': + result = await window.showInformationMessage(message, ...actions); + break; + + case 'warn': + result = await window.showWarningMessage(message, ...actions); + break; + + case 'error': + result = await window.showErrorMessage(message, ...actions); + break; + } + + if (dontShowAgain === null || result === dontShowAgain) { + await Messages.context.globalState.update(suppressionKey, true); + return undefined; + } + + return result; + } +} \ No newline at end of file diff --git a/src/system/object.ts b/src/system/object.ts index 01244be..4e3efaa 100644 --- a/src/system/object.ts +++ b/src/system/object.ts @@ -56,9 +56,9 @@ export namespace Objects { } } - export function* values(o: any): IterableIterator<[any]> { + export function* values(o: any): IterableIterator { for (const key in o) { - yield [o[key]]; + yield o[key]; } } } \ No newline at end of file