From d790e9db047769de079f6838c3578f3a47bf5930 Mon Sep 17 00:00:00 2001 From: Eric Amodio <eamodio@gmail.com> Date: Tue, 10 Jul 2018 19:10:24 -0400 Subject: [PATCH] Prettier all-the-things --- .prettierignore | 2 + .prettierrc | 16 + .vscode/settings.json | 15 + BACKERS.md | 1 - CODE_OF_CONDUCT.md | 20 +- package-lock.json | 41 +- package.json | 7 +- src/@types/applicationinsights/index.d.ts | 124 +++-- src/annotations/annotationProvider.ts | 44 +- src/annotations/annotations.ts | 138 ++++-- src/annotations/blameAnnotationProvider.ts | 93 +++- src/annotations/fileAnnotationController.ts | 134 ++++-- src/annotations/gutterBlameAnnotationProvider.ts | 28 +- src/annotations/heatmapBlameAnnotationProvider.ts | 3 +- src/annotations/hoverBlameAnnotationProvider.ts | 2 +- src/annotations/lineAnnotationController.ts | 28 +- src/annotations/lineHoverController.ts | 68 ++- src/annotations/recentChangesAnnotationProvider.ts | 20 +- src/codeLensController.ts | 18 +- src/commands.ts | 2 +- src/commands/clearFileAnnotations.ts | 3 +- src/commands/closeUnchangedFiles.ts | 16 +- src/commands/common.ts | 113 ++++- src/commands/copyMessageToClipboard.ts | 20 +- src/commands/copyShaToClipboard.ts | 16 +- src/commands/diffBranchWithBranch.ts | 15 +- src/commands/diffDirectory.ts | 30 +- src/commands/diffLineWithPrevious.ts | 14 +- src/commands/diffLineWithWorking.ts | 19 +- src/commands/diffWith.ts | 41 +- src/commands/diffWithBranch.ts | 10 +- src/commands/diffWithNext.ts | 15 +- src/commands/diffWithPrevious.ts | 22 +- src/commands/diffWithRevision.ts | 75 ++- src/commands/diffWithWorking.ts | 16 +- src/commands/externalDiff.ts | 39 +- src/commands/openBranchInRemote.ts | 29 +- src/commands/openBranchesInRemote.ts | 24 +- src/commands/openChangedFiles.ts | 12 +- src/commands/openCommitInRemote.ts | 24 +- src/commands/openFileInRemote.ts | 40 +- src/commands/openFileRevision.ts | 80 +++- src/commands/openInRemote.ts | 15 +- src/commands/openRepoInRemote.ts | 24 +- src/commands/openWorkingFile.ts | 8 +- src/commands/resetSuppressedWarnings.ts | 9 +- src/commands/showCommitSearch.ts | 82 ++-- src/commands/showGitExplorer.ts | 3 +- src/commands/showHistoryExplorer.ts | 3 +- src/commands/showLastQuickPick.ts | 3 +- src/commands/showQuickBranchHistory.ts | 78 ++- src/commands/showQuickCommitDetails.ts | 89 ++-- src/commands/showQuickCommitFileDetails.ts | 96 ++-- src/commands/showQuickCurrentBranchHistory.ts | 21 +- src/commands/showQuickFileHistory.ts | 115 +++-- src/commands/showQuickRepoStatus.ts | 9 +- src/commands/showQuickStashList.ts | 43 +- src/commands/showResultsExplorer.ts | 3 +- src/commands/stashApply.ts | 79 ++- src/commands/stashDelete.ts | 28 +- src/commands/stashSave.ts | 17 +- src/commands/switchMode.ts | 3 - src/commands/toggleCodeLens.ts | 1 - src/commands/toggleFileBlame.ts | 13 +- src/commands/toggleFileHeatmap.ts | 7 +- src/commands/toggleFileRecentChanges.ts | 7 +- src/commands/toggleLineBlame.ts | 7 +- src/comparers.ts | 11 +- src/configuration.ts | 94 +++- src/constants.ts | 13 +- src/container.ts | 45 +- src/extension.ts | 529 ++++++++++++++------- src/git/formatters/commitFormatter.ts | 18 +- src/git/formatters/formatter.ts | 22 +- src/git/formatters/statusFormatter.ts | 17 +- src/git/git.ts | 156 ++++-- src/git/gitLocator.ts | 11 +- src/git/gitUri.ts | 61 ++- src/git/models/blame.ts | 2 +- src/git/models/blameCommit.ts | 14 +- src/git/models/branch.ts | 23 +- src/git/models/commit.ts | 38 +- src/git/models/diff.ts | 9 +- src/git/models/log.ts | 4 +- src/git/models/logCommit.ts | 26 +- src/git/models/remote.ts | 7 +- src/git/models/repository.ts | 51 +- src/git/models/stash.ts | 2 +- src/git/models/stashCommit.ts | 16 +- src/git/models/status.ts | 60 ++- src/git/models/tag.ts | 9 +- src/git/parsers/blameParser.ts | 40 +- src/git/parsers/branchParser.ts | 8 +- src/git/parsers/diffParser.ts | 28 +- src/git/parsers/logParser.ts | 61 ++- src/git/parsers/remoteParser.ts | 14 +- src/git/parsers/stashParser.ts | 18 +- src/git/parsers/statusParser.ts | 32 +- src/git/parsers/tagParser.ts | 5 +- src/git/remotes/bitbucket-server.ts | 23 +- src/git/remotes/bitbucket.ts | 23 +- src/git/remotes/custom.ts | 25 +- src/git/remotes/factory.ts | 21 +- src/git/remotes/github.ts | 26 +- src/git/remotes/gitlab.ts | 11 +- src/git/remotes/provider.ts | 76 ++- src/git/remotes/visualStudio.ts | 10 +- src/git/shell.ts | 43 +- src/gitCodeLensProvider.ts | 351 +++++++++++--- src/gitContentProvider.ts | 10 +- src/gitRevisionCodeLensProvider.ts | 18 +- src/gitService.ts | 495 +++++++++++++------ src/keyboard.ts | 22 +- src/logger.ts | 33 +- src/messages.ts | 77 ++- src/quickPicks/branchHistoryQuickPick.ts | 147 ++++-- src/quickPicks/branchesAndTagsQuickPick.ts | 39 +- src/quickPicks/branchesQuickPick.ts | 19 +- src/quickPicks/commitFileQuickPick.ts | 345 +++++++++----- src/quickPicks/commitQuickPick.ts | 377 +++++++++------ src/quickPicks/commitsQuickPick.ts | 37 +- src/quickPicks/commonQuickPicks.ts | 83 ++-- src/quickPicks/fileHistoryQuickPick.ts | 175 ++++--- src/quickPicks/modesQuickPick.ts | 7 +- src/quickPicks/remotesQuickPick.ts | 94 ++-- src/quickPicks/repoStatusQuickPick.ts | 389 ++++++++++----- src/quickPicks/repositoriesQuickPick.ts | 13 +- src/quickPicks/stashListQuickPick.ts | 68 ++- src/statusBarController.ts | 36 +- src/system/array.ts | 65 ++- src/system/asyncIterable.ts | 2 +- src/system/date.ts | 11 +- src/system/function.ts | 48 +- src/system/iterable.ts | 35 +- src/system/object.ts | 2 +- src/system/searchTree.ts | 77 +-- src/system/string.ts | 54 ++- src/system/version.ts | 13 +- src/telemetry.ts | 2 +- src/trackers/activeEditorTracker.ts | 4 +- src/trackers/documentTracker.ts | 58 ++- src/trackers/gitDocumentTracker.ts | 5 +- src/trackers/gitLineTracker.ts | 11 +- src/trackers/lineTracker.ts | 24 +- src/trackers/trackedDocument.ts | 12 +- src/ui/config.ts | 66 +-- src/ui/ipc.ts | 5 +- src/ui/settings/app.ts | 18 +- src/ui/settings/index.ts | 2 +- src/ui/shared/app-base.ts | 108 +++-- src/ui/shared/colors.ts | 26 +- src/ui/shared/dom.ts | 2 +- src/ui/welcome/app.ts | 6 +- src/ui/welcome/index.ts | 2 +- src/views/activeRepositoryNode.ts | 12 +- src/views/branchNode.ts | 28 +- src/views/branchOrTagFolderNode.ts | 5 +- src/views/branchesNode.ts | 24 +- src/views/commitFileNode.ts | 44 +- src/views/commitNode.ts | 34 +- src/views/commitResultsNode.ts | 18 +- src/views/commitsNode.ts | 6 +- src/views/commitsResultsNode.ts | 15 +- src/views/comparisonResultsNode.ts | 17 +- src/views/explorerCommands.ts | 127 +++-- src/views/explorerNode.ts | 20 +- src/views/explorerNodes.ts | 2 +- src/views/fileHistoryNode.ts | 27 +- src/views/folderNode.ts | 27 +- src/views/gitExplorer.ts | 159 +++++-- src/views/historyExplorer.ts | 48 +- src/views/historyNode.ts | 7 +- src/views/remoteNode.ts | 130 ++--- src/views/remotesNode.ts | 53 +-- src/views/repositoriesNode.ts | 3 +- src/views/repositoryNode.ts | 24 +- src/views/resultsExplorer.ts | 123 +++-- src/views/stashFileNode.ts | 9 +- src/views/stashNode.ts | 29 +- src/views/stashesNode.ts | 3 +- src/views/statusFileCommitsNode.ts | 41 +- src/views/statusFileNode.ts | 16 +- src/views/statusFilesNode.ts | 188 ++++++-- src/views/statusFilesResultsNode.ts | 24 +- src/views/statusNode.ts | 35 +- src/views/statusUpstreamNode.ts | 34 +- src/views/tagNode.ts | 6 +- src/views/tagsNode.ts | 85 ++-- src/webviews/settingsEditor.ts | 5 +- src/webviews/webviewEditor.ts | 37 +- src/webviews/welcomeEditor.ts | 4 +- test/extension.test.ts | 3 +- test/index.ts | 4 +- tsconfig.json | 11 +- tslint.json | 88 +--- webpack.config.js | 6 +- 196 files changed, 6038 insertions(+), 2978 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..bf1c7d3 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +package*.json +*.md \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..0c30ac9 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,16 @@ +{ + "printWidth": 120, + "singleQuote": true, + "tabWidth": 4, + "useTabs": false, + "overrides": [ + { + "files": ".prettierrc", + "options": { "parser": "json" } + }, + { + "files": "*.md", + "options": { "tabWidth": 2 } + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index e88df1b..a4ce60e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -21,5 +21,20 @@ "properties-order": "alphabetical", "unspecified-properties-position": "bottom" }, + "tslint.autoFixOnSave": [ + "curly", + "eofline", + "linebreak-style", + "trailing-comma", + "no-consecutive-blank-lines", + "no-irregular-whitespace", + "object-literal-key-quotes", + "one-line", + "ordered-imports", + "prefer-method-signature", + "prettiest", + "quotemark", + "whitespace" + ], "typescript.tsdk": "./node_modules/typescript/lib" // we want to use the TS server from our node_modules folder to control its version } \ No newline at end of file diff --git a/BACKERS.md b/BACKERS.md index 923c14e..fc6c8e6 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -14,7 +14,6 @@ None yet — could be you! <h2 align="center">Silver Sponsors ($150+)</h2> None yet — could be you! - <h2 align="center">Bronze Sponsors ($50+)</h2> - Michael Duffy diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 517a3b8..45b3e89 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -8,19 +8,19 @@ In the interest of fostering an open and welcoming environment, we as contributo Examples of behavior that contributes to creating a positive environment include: -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members Examples of unacceptable behavior by participants include: -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities diff --git a/package-lock.json b/package-lock.json index 585261e..c87ecc9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -767,14 +767,15 @@ } }, "browserify-des": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.1.tgz", - "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", "dev": true, "requires": { "cipher-base": "^1.0.1", "des.js": "^1.0.0", - "inherits": "^2.0.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" } }, "browserify-rsa": { @@ -2499,9 +2500,9 @@ } }, "get-caller-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", - "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", "dev": true }, "get-stream": { @@ -3114,13 +3115,13 @@ } }, "hash.js": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.4.tgz", - "integrity": "sha512-A6RlQvvZEtFS5fLU43IDu0QUmBy+fDO9VMdTXvufKwIkt/rFfvICAViCax5fbDO4zdNzaC3/27ZhKUok5bAJyw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", + "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", "dev": true, "requires": { "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" + "minimalistic-assert": "^1.0.1" } }, "he": { @@ -4461,6 +4462,12 @@ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", "dev": true }, + "prettier": { + "version": "1.13.7", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.13.7.tgz", + "integrity": "sha512-KIU72UmYPGk4MujZGYMFwinB7lOf2LsDNGSOC8ufevsrPLISrZbNJlWstRi3m0AMuszbH+EFSQ/r6w56RSPK6w==", + "dev": true + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -5483,6 +5490,12 @@ "tsutils": "^2.12.1" } }, + "tslint-prettiest": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tslint-prettiest/-/tslint-prettiest-0.0.1.tgz", + "integrity": "sha512-zFmqDWCgHIswGksTPLplSSc/U2Y7HKZWZiJAOuyOLO1Oer0nPl0itEUa1hdu5LOeRShGHXywXML9SbYCOu1TqA==", + "dev": true + }, "tsutils": { "version": "2.27.2", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.27.2.tgz", @@ -5892,9 +5905,9 @@ } }, "webpack": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.15.1.tgz", - "integrity": "sha512-UwfFQ2plA5EMhhzwi/hl5xpLk7mNK7p0853Ml04z1Bqw553pY+oS8Xke3funcVy7eG/yMpZPvnlFTUyGKyKoyw==", + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.16.0.tgz", + "integrity": "sha512-oNx9djAd6uAcccyfqN3hyXLNMjZHiRySZmBQ4c8FNmf1SNJGhx7n9TSvHNyXxgToRdH65g/Q97s94Ip9N6F7xg==", "dev": true, "requires": { "@webassemblyjs/ast": "1.5.13", diff --git a/package.json b/package.json index 3242f9e..3e55c32 100644 --- a/package.json +++ b/package.json @@ -3348,8 +3348,9 @@ "build-ui": "webpack --context ./src/ui --config ./src/ui/webpack.config.js", "bundle": "npm run lint && webpack --env.production --context ./src/ui --config ./src/ui/webpack.config.js && webpack --env.production", "clean": "git clean -Xdf", - "lint": "tslint --project tsconfig.json", + "lint": "tslint --project tsconfig.json --fix", "pack": "vsce package", + "pretty": "prettier --config .prettierrc --loglevel warn --write \"./**/*.ts\"", "pub": "vsce publish", "rebuild": "npm run reset && npm run lint && tsc -m commonjs -p ./ && npm run build-ui", "reset": "npm run clean && npm install --no-save", @@ -3373,13 +3374,15 @@ "@types/node": "7.0.67", "@types/tmp": "0.0.33", "husky": "0.14.3", + "prettier": "1.13.7", "ts-loader": "4.4.2", "tslint": "5.10.0", + "tslint-prettiest": "0.0.1", "typescript": "2.9.2", "uglify-es": "3.3.9", "uglifyjs-webpack-plugin": "1.2.7", "vscode": "1.1.18", - "webpack": "4.15.1", + "webpack": "4.16.0", "webpack-cli": "3.0.8", "webpack-node-externals": "1.7.2" } diff --git a/src/@types/applicationinsights/index.d.ts b/src/@types/applicationinsights/index.d.ts index 5387257..c759e10 100644 --- a/src/@types/applicationinsights/index.d.ts +++ b/src/@types/applicationinsights/index.d.ts @@ -33,32 +33,31 @@ interface AutoCollectRequests { isInitialized(): boolean; } - declare namespace ContractsModule { enum DataPointType { Measurement = 0, - Aggregation = 1, + Aggregation = 1 } enum DependencyKind { SQL = 0, Http = 1, - Other = 2, + Other = 2 } enum DependencySourceType { Undefined = 0, Aic = 1, - Apmc = 2, + Apmc = 2 } enum SessionState { Start = 0, - End = 1, + End = 1 } enum SeverityLevel { Verbose = 0, Information = 1, Warning = 2, Error = 3, - Critical = 4, + Critical = 4 } interface ContextTagKeys { applicationVersion: string; @@ -279,9 +278,13 @@ declare namespace ContractsModule { } } - interface Channel { - constructor(isDisabled: () => boolean, getBatchSize: () => number, getBatchIntervalMs: () => number, sender: Sender): Channel; + constructor( + isDisabled: () => boolean, + getBatchSize: () => number, + getBatchIntervalMs: () => number, + sender: Sender + ): Channel; /** * Add a telemetry item to the send buffer */ @@ -315,28 +318,39 @@ interface Client { * @param properties map[string, string] - additional data used to filter events and metrics in the portal. Defaults to empty. * @param measurements map[string, number] - metrics associated with this event, displayed in Metrics Explorer on the portal. Defaults to empty. */ - trackEvent(name: string, properties?: { - [key: string]: string; - }, measurements?: { - [key: string]: number; - }): void; + trackEvent( + name: string, + properties?: { + [key: string]: string; + }, + measurements?: { + [key: string]: number; + } + ): void; /** * Log a trace message * @param message A string to identify this event in the portal. * @param properties map[string, string] - additional data used to filter events and metrics in the portal. Defaults to empty. */ - trackTrace(message: string, severityLevel?: ContractsModule.SeverityLevel, properties?: { - [key: string]: string; - }): void; + trackTrace( + message: string, + severityLevel?: ContractsModule.SeverityLevel, + properties?: { + [key: string]: string; + } + ): void; /** * Log an exception you have caught. * @param exception An Error from a catch clause, or the string error message. * @param properties map[string, string] - additional data used to filter events and metrics in the portal. Defaults to empty. * @param measurements map[string, number] - metrics associated with this event, displayed in Metrics Explorer on the portal. Defaults to empty. */ - trackException(exception: Error, properties?: { - [key: string]: string; - }): void; + trackException( + exception: Error, + properties?: { + [key: string]: string; + } + ): void; /** * Log a numeric value that is not associated with a specific event. Typically used to send regular reports of performance indicators. * To send a single measurement, use just the first two parameters. If you take measurements very frequently, you can reduce the @@ -348,9 +362,17 @@ interface Client { * @param max the max sample for this set * @param stdDev the standard deviation of the set */ - trackMetric(name: string, value: number, count?: number, min?: number, max?: number, stdDev?: number, properties?: { - [key: string]: string; - }): void; + trackMetric( + name: string, + value: number, + count?: number, + min?: number, + max?: number, + stdDev?: number, + properties?: { + [key: string]: string; + } + ): void; /** * Log an incoming http request to your server. The request data will be tracked during the response "finish" event if it is successful or the request "error" @@ -360,9 +382,13 @@ interface Client { * @param response The http.ServerResponse object for this request * @param properties map[string, string] - additional data used to filter requests in the portal. Defaults to empty. */ - trackRequest(request: any /* http.IncomingMessage */, response: any /* http.ServerResponse */, properties?: { - [key: string]: string; - }): void; + trackRequest( + request: any /* http.IncomingMessage */, + response: any /* http.ServerResponse */, + properties?: { + [key: string]: string; + } + ): void; /** * Log an incoming http request to your server. The request data is tracked synchronously rather than waiting for the response "finish"" or request "error"" events. @@ -373,9 +399,15 @@ interface Client { * @param properties map[string, string] - additional data used to filter requests in the portal. Defaults to empty. * @param error An error that was returned for this request if it was unsuccessful. Defaults to null. */ - trackRequestSync(request: any /*http.IncomingMessage */, response: any /*http.ServerResponse */, ellapsedMilliseconds?: number, properties?: { - [key: string]: string; - }, error?: any): void; + trackRequestSync( + request: any /*http.IncomingMessage */, + response: any /*http.ServerResponse */, + ellapsedMilliseconds?: number, + properties?: { + [key: string]: string; + }, + error?: any + ): void; /** * Log information about a dependency of your app. Typically used to track the time database calls or outgoing http requests take from your server. @@ -389,22 +421,38 @@ interface Client { * @param async True if the dependency was executed asynchronously, false otherwise. Defaults to false * @param dependencySource ContractsModule.DependencySourceType of this dependency. Defaults to Undefined. */ - trackDependency(name: string, commandName: string, elapsedTimeMs: number, success: boolean, dependencyTypeName?: string, properties?: {}, dependencyKind?: any, async?: boolean, dependencySource?: number): void; + trackDependency( + name: string, + commandName: string, + elapsedTimeMs: number, + success: boolean, + dependencyTypeName?: string, + properties?: {}, + dependencyKind?: any, + async?: boolean, + dependencySource?: number + ): void; /** * Immediately send all queued telemetry. */ sendPendingData(callback?: (response: string) => void): void; - getEnvelope(data: ContractsModule.Data<ContractsModule.Domain>, tagOverrides?: { - [key: string]: string; - }): ContractsModule.Envelope; + getEnvelope( + data: ContractsModule.Data<ContractsModule.Domain>, + tagOverrides?: { + [key: string]: string; + } + ): ContractsModule.Envelope; /** * Generic track method for all telemetry types * @param data the telemetry to send * @param tagOverrides the context tags to use for this telemetry which overwrite default context values */ - track(data: ContractsModule.Data<ContractsModule.Domain>, tagOverrides?: { - [key: string]: string; - }): void; + track( + data: ContractsModule.Data<ContractsModule.Domain>, + tagOverrides?: { + [key: string]: string; + } + ): void; } interface Config { @@ -428,7 +476,7 @@ interface Context { interface Sender { constructor(getUrl: () => string, onSuccess?: (response: string) => void, onError?: (error: Error) => void): Sender; - send(payload: any/* Buffer */): void; + send(payload: any /* Buffer */): void; saveOnCrash(payload: string): void; /** * enable caching events locally on error @@ -511,7 +559,7 @@ interface ApplicationInsights { setAutoDependencyCorrelation(value: boolean): ApplicationInsights; } -declare module "applicationinsights" { +declare module 'applicationinsights' { const applicationinsights: ApplicationInsights; export = applicationinsights; -} \ No newline at end of file +} diff --git a/src/annotations/annotationProvider.ts b/src/annotations/annotationProvider.ts index 6fd929c..f06bae6 100644 --- a/src/annotations/annotationProvider.ts +++ b/src/annotations/annotationProvider.ts @@ -1,6 +1,16 @@ 'use strict'; import { Functions } from '../system'; -import { DecorationOptions, Disposable, Range, TextDocument, TextEditor, TextEditorDecorationType, TextEditorSelectionChangeEvent, Uri, window } from 'vscode'; +import { + DecorationOptions, + Disposable, + Range, + TextDocument, + TextEditor, + TextEditorDecorationType, + TextEditorSelectionChangeEvent, + Uri, + window +} from 'vscode'; import { FileAnnotationType } from '../configuration'; import { TextDocumentComparer } from '../comparers'; import { CommandContext, setCommandContext } from '../constants'; @@ -14,7 +24,6 @@ export enum AnnotationStatus { export type TextEditorCorrelationKey = string; export abstract class AnnotationProviderBase extends Disposable { - static getCorrelationKey(editor: TextEditor | undefined): TextEditorCorrelationKey { return editor !== undefined ? (editor as any).id : ''; } @@ -65,7 +74,7 @@ export abstract class AnnotationProviderBase extends Disposable { return this.editor.document.uri; } - protected additionalDecorations: { decoration: TextEditorDecorationType, ranges: Range[] }[] | undefined; + protected additionalDecorations: { decoration: TextEditorDecorationType; ranges: Range[] }[] | undefined; async clear() { this.status = undefined; @@ -75,7 +84,7 @@ export abstract class AnnotationProviderBase extends Disposable { try { this.editor.setDecorations(this.decoration, []); } - catch { } + catch {} } if (this.additionalDecorations !== undefined && this.additionalDecorations.length > 0) { @@ -83,7 +92,7 @@ export abstract class AnnotationProviderBase extends Disposable { try { this.editor.setDecorations(d.decoration, []); } - catch { } + catch {} } this.additionalDecorations = undefined; @@ -93,13 +102,23 @@ export abstract class AnnotationProviderBase extends Disposable { try { this.editor.setDecorations(this.highlightDecoration, []); } - catch { } + catch {} } } - private _resetDebounced: ((changes?: { decoration: TextEditorDecorationType, highlightDecoration: TextEditorDecorationType | undefined }) => Promise<void>) | undefined; - - async reset(changes?: { decoration: TextEditorDecorationType, highlightDecoration: TextEditorDecorationType | undefined }) { + private _resetDebounced: + | (( + changes?: { + decoration: TextEditorDecorationType; + highlightDecoration: TextEditorDecorationType | undefined; + } + ) => Promise<void>) + | undefined; + + async reset(changes?: { + decoration: TextEditorDecorationType; + highlightDecoration: TextEditorDecorationType | undefined; + }) { if (this._resetDebounced === undefined) { this._resetDebounced = Functions.debounce(this.onReset, 250); } @@ -107,7 +126,10 @@ export abstract class AnnotationProviderBase extends Disposable { this._resetDebounced(changes); } - async onReset(changes?: { decoration: TextEditorDecorationType, highlightDecoration: TextEditorDecorationType | undefined }) { + async onReset(changes?: { + decoration: TextEditorDecorationType; + highlightDecoration: TextEditorDecorationType | undefined; + }) { if (changes !== undefined) { await this.clear(); @@ -163,4 +185,4 @@ export abstract class AnnotationProviderBase extends Disposable { abstract async onProvideAnnotation(shaOrLine?: string | number): Promise<boolean>; abstract async selection(shaOrLine?: string | number): Promise<void>; abstract async validate(): Promise<boolean>; - } \ No newline at end of file +} diff --git a/src/annotations/annotations.ts b/src/annotations/annotations.ts index 38180a1..d1b167a 100644 --- a/src/annotations/annotations.ts +++ b/src/annotations/annotations.ts @@ -1,15 +1,35 @@ import { Objects, Strings } from '../system'; -import { DecorationInstanceRenderOptions, DecorationOptions, MarkdownString, ThemableDecorationRenderOptions, ThemeColor } from 'vscode'; -import { DiffWithCommand, OpenCommitInRemoteCommand, OpenFileRevisionCommand, ShowQuickCommitDetailsCommand, ShowQuickCommitFileDetailsCommand } from '../commands'; +import { + DecorationInstanceRenderOptions, + DecorationOptions, + MarkdownString, + ThemableDecorationRenderOptions, + ThemeColor +} from 'vscode'; +import { + DiffWithCommand, + OpenCommitInRemoteCommand, + OpenFileRevisionCommand, + ShowQuickCommitDetailsCommand, + ShowQuickCommitFileDetailsCommand +} from '../commands'; import { FileAnnotationType } from './../configuration'; import { GlyphChars } from '../constants'; import { Container } from '../container'; -import { CommitFormatter, GitCommit, GitDiffChunkLine, GitRemote, GitService, GitUri, ICommitFormatOptions } from '../gitService'; +import { + CommitFormatter, + GitCommit, + GitDiffChunkLine, + GitRemote, + GitService, + GitUri, + ICommitFormatOptions +} from '../gitService'; import { toRgba } from '../ui/shared/colors'; export interface ComputedHeatmap { cold: boolean; - colors: { hot: string, cold: string }; + colors: { hot: string; cold: string }; median: number; newest: number; oldest: number; @@ -32,21 +52,18 @@ const escapeMarkdownRegEx = /[`\>\#\*\_\-\+\.]/g; // const sampleMarkdown = '## message `not code` *not important* _no underline_ \n> don\'t quote me \n- don\'t list me \n+ don\'t list me \n1. don\'t list me \nnot h1 \n=== \nnot h2 \n---\n***\n---\n___'; let computedHeatmapColor: { - color: string, - rgb: string + color: string; + rgb: string; }; export class Annotations { - static applyHeatmap(decoration: DecorationOptions, date: Date, heatmap: ComputedHeatmap) { const color = this.getHeatmapColor(date, heatmap); (decoration.renderOptions!.before! as any).borderColor = color; } private static getHeatmapColor(date: Date, heatmap: ComputedHeatmap) { - const baseColor = heatmap.cold - ? heatmap.colors.cold - : heatmap.colors.hot; + const baseColor = heatmap.cold ? heatmap.colors.cold : heatmap.colors.hot; const age = heatmap.computeAge(date); if (age === 0) return baseColor; @@ -64,11 +81,18 @@ export class Annotations { }; } - return `rgba(${computedHeatmapColor.rgb}, ${(1 - (age / 10)).toFixed(2)})`; + return `rgba(${computedHeatmapColor.rgb}, ${(1 - age / 10).toFixed(2)})`; } - private static getHoverCommandBar(commit: GitCommit, hasRemote: boolean, annotationType?: FileAnnotationType, line: number = 0) { - let commandBar = `[\`${GlyphChars.MuchGreaterThan}\`](${DiffWithCommand.getMarkdownCommandArgs(commit)} "Open Changes") `; + private static getHoverCommandBar( + commit: GitCommit, + hasRemote: boolean, + annotationType?: FileAnnotationType, + line: number = 0 + ) { + let commandBar = `[\`${GlyphChars.MuchGreaterThan}\`](${DiffWithCommand.getMarkdownCommandArgs( + commit + )} "Open Changes") `; if (commit.previousSha !== undefined) { if (annotationType === FileAnnotationType.RecentChanges) { @@ -76,19 +100,33 @@ export class Annotations { } const uri = GitUri.toRevisionUri(commit.previousSha, commit.previousUri.fsPath, commit.repoPath); - commandBar += `[\`${GlyphChars.SquareWithTopShadow}\`](${OpenFileRevisionCommand.getMarkdownCommandArgs(uri, annotationType || FileAnnotationType.Blame, line)} "Blame Previous Revision") `; + commandBar += `[\`${GlyphChars.SquareWithTopShadow}\`](${OpenFileRevisionCommand.getMarkdownCommandArgs( + uri, + annotationType || FileAnnotationType.Blame, + line + )} "Blame Previous Revision") `; } if (hasRemote) { - commandBar += `[\`${GlyphChars.ArrowUpRight}\`](${OpenCommitInRemoteCommand.getMarkdownCommandArgs(commit.sha)} "Open in Remote") `; + commandBar += `[\`${GlyphChars.ArrowUpRight}\`](${OpenCommitInRemoteCommand.getMarkdownCommandArgs( + commit.sha + )} "Open in Remote") `; } - commandBar += `[\`${GlyphChars.MiddleEllipsis}\`](${ShowQuickCommitFileDetailsCommand.getMarkdownCommandArgs(commit.sha)} "Show More Actions")`; + commandBar += `[\`${GlyphChars.MiddleEllipsis}\`](${ShowQuickCommitFileDetailsCommand.getMarkdownCommandArgs( + commit.sha + )} "Show More Actions")`; return commandBar; } - static getHoverMessage(commit: GitCommit, dateFormat: string | null, remotes: GitRemote[], annotationType?: FileAnnotationType, line: number = 0): MarkdownString { + static getHoverMessage( + commit: GitCommit, + dateFormat: string | null, + remotes: GitRemote[], + annotationType?: FileAnnotationType, + line: number = 0 + ): MarkdownString { if (dateFormat === null) { dateFormat = 'MMMM Do, YYYY h:mma'; } @@ -99,7 +137,9 @@ export class Annotations { let avatar = ''; if (!commit.isUncommitted) { commandBar = `\n\n${this.getHoverCommandBar(commit, remotes.length !== 0, annotationType, line)}`; - showCommitDetailsCommand = `[\`${commit.shortSha}\`](${ShowQuickCommitDetailsCommand.getMarkdownCommandArgs(commit.sha)} "Show Commit Details")`; + showCommitDetailsCommand = `[\`${commit.shortSha}\`](${ShowQuickCommitDetailsCommand.getMarkdownCommandArgs( + commit.sha + )} "Show Commit Details")`; message = commit.message; for (const r of remotes) { @@ -126,12 +166,20 @@ export class Annotations { avatar = ` .toString()})`; } - const markdown = new MarkdownString(`${showCommitDetailsCommand}${avatar} __${commit.author}__, ${commit.fromNow()} _(${commit.formatDate(dateFormat)})_ ${message}${commandBar}`); + const markdown = new MarkdownString( + `${showCommitDetailsCommand}${avatar} __${ + commit.author + }__, ${commit.fromNow()} _(${commit.formatDate(dateFormat)})_ ${message}${commandBar}` + ); markdown.isTrusted = true; return markdown; } - static getHoverDiffMessage(commit: GitCommit, uri: GitUri, chunkLine: GitDiffChunkLine | undefined): MarkdownString | undefined { + static getHoverDiffMessage( + commit: GitCommit, + uri: GitUri, + chunkLine: GitDiffChunkLine | undefined + ): MarkdownString | undefined { if (chunkLine === undefined || commit.previousSha === undefined) return undefined; const codeDiff = this.getCodeDiff(chunkLine); @@ -139,14 +187,28 @@ export class Annotations { let message: string; if (commit.isUncommitted) { if (uri.sha !== undefined && GitService.isStagedUncommitted(uri.sha)) { - message = `[\`Changes\`](${DiffWithCommand.getMarkdownCommandArgs(commit)} "Open Changes") ${GlyphChars.Dash} [\`${commit.previousShortSha}\`](${ShowQuickCommitDetailsCommand.getMarkdownCommandArgs(commit.previousSha!)} "Show Commit Details") ${GlyphChars.ArrowLeftRightLong} _${uri.shortSha}_\n${codeDiff}`; + message = `[\`Changes\`](${DiffWithCommand.getMarkdownCommandArgs(commit)} "Open Changes") ${ + GlyphChars.Dash + } [\`${commit.previousShortSha}\`](${ShowQuickCommitDetailsCommand.getMarkdownCommandArgs( + commit.previousSha! + )} "Show Commit Details") ${GlyphChars.ArrowLeftRightLong} _${uri.shortSha}_\n${codeDiff}`; } else { - message = `[\`Changes\`](${DiffWithCommand.getMarkdownCommandArgs(commit)} "Open Changes") ${GlyphChars.Dash} _uncommitted changes_\n${codeDiff}`; + message = `[\`Changes\`](${DiffWithCommand.getMarkdownCommandArgs(commit)} "Open Changes") ${ + GlyphChars.Dash + } _uncommitted changes_\n${codeDiff}`; } } else { - message = `[\`Changes\`](${DiffWithCommand.getMarkdownCommandArgs(commit)} "Open Changes") ${GlyphChars.Dash} [\`${commit.previousShortSha}\`](${ShowQuickCommitDetailsCommand.getMarkdownCommandArgs(commit.previousSha!)} "Show Commit Details") ${GlyphChars.ArrowLeftRightLong} [\`${commit.shortSha}\`](${ShowQuickCommitDetailsCommand.getMarkdownCommandArgs(commit.sha)} "Show Commit Details")\n${codeDiff}`; + message = `[\`Changes\`](${DiffWithCommand.getMarkdownCommandArgs(commit)} "Open Changes") ${ + GlyphChars.Dash + } [\`${commit.previousShortSha}\`](${ShowQuickCommitDetailsCommand.getMarkdownCommandArgs( + commit.previousSha! + )} "Show Commit Details") ${GlyphChars.ArrowLeftRightLong} [\`${ + commit.shortSha + }\`](${ShowQuickCommitDetailsCommand.getMarkdownCommandArgs( + commit.sha + )} "Show Commit Details")\n${codeDiff}`; } const markdown = new MarkdownString(message); @@ -163,9 +225,10 @@ export class Annotations { } static async changesHover(commit: GitCommit, line: number, uri: GitUri): Promise<DecorationOptions> { - const sha = !commit.isUncommitted || (uri.sha !== undefined && GitService.isStagedUncommitted(uri.sha)) - ? commit.previousSha - : undefined; + const sha = + !commit.isUncommitted || (uri.sha !== undefined && GitService.isStagedUncommitted(uri.sha)) + ? commit.previousSha + : undefined; const chunkLine = await Container.git.getDiffForLine(uri, line, sha); const message = this.getHoverDiffMessage(commit, uri, chunkLine); @@ -181,7 +244,12 @@ export class Annotations { // } as DecorationOptions; // } - static gutter(commit: GitCommit, format: string, dateFormatOrFormatOptions: string | null | ICommitFormatOptions, renderOptions: IRenderOptions): DecorationOptions { + static gutter( + commit: GitCommit, + format: string, + dateFormatOrFormatOptions: string | null | ICommitFormatOptions, + renderOptions: IRenderOptions + ): DecorationOptions { const decoration = { renderOptions: { before: { ...renderOptions } @@ -198,7 +266,12 @@ export class Annotations { return decoration; } - static gutterRenderOptions(separateLines: boolean, heatmap: IHeatmapConfig, format: string, options: ICommitFormatOptions): IRenderOptions { + static gutterRenderOptions( + separateLines: boolean, + heatmap: IHeatmapConfig, + format: string, + options: ICommitFormatOptions + ): IRenderOptions { // Get the width of all the tokens, assuming there there is a cap (bail if not) let width = 0; for (const token of Objects.values(options.tokenOptions!)) { @@ -289,7 +362,12 @@ export class Annotations { // } as IRenderOptions; // } - static trailing(commit: GitCommit, format: string, dateFormat: string | null, scrollable: boolean = true): DecorationOptions { + static trailing( + commit: GitCommit, + format: string, + dateFormat: string | null, + scrollable: boolean = true + ): DecorationOptions { const message = CommitFormatter.fromTemplate(format, commit, { truncateMessageAtNewLine: true, dateFormat: dateFormat @@ -326,4 +404,4 @@ export class Annotations { // return { ...decoration, range: range }; // } -} \ No newline at end of file +} diff --git a/src/annotations/blameAnnotationProvider.ts b/src/annotations/blameAnnotationProvider.ts index 852389e..0b8f763 100644 --- a/src/annotations/blameAnnotationProvider.ts +++ b/src/annotations/blameAnnotationProvider.ts @@ -1,6 +1,17 @@ 'use strict'; import { Arrays, Iterables } from '../system'; -import { CancellationToken, Disposable, Hover, HoverProvider, languages, Position, Range, TextDocument, TextEditor, TextEditorDecorationType } from 'vscode'; +import { + CancellationToken, + Disposable, + Hover, + HoverProvider, + languages, + Position, + Range, + TextDocument, + TextEditor, + TextEditorDecorationType +} from 'vscode'; import { AnnotationProviderBase } from './annotationProvider'; import { Annotations, ComputedHeatmap } from './annotations'; import { Container } from '../container'; @@ -8,7 +19,6 @@ import { GitDocumentState, TrackedDocument } from '../trackers/gitDocumentTracke import { GitBlame, GitCommit, GitUri } from '../gitService'; export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase { - protected _blame: Promise<GitBlame | undefined>; protected _hoverProviderDisposable: Disposable | undefined; protected readonly _uri: GitUri; @@ -36,7 +46,10 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase super.clear(); } - async onReset(changes?: { decoration: TextEditorDecorationType, highlightDecoration: TextEditorDecorationType | undefined }) { + async onReset(changes?: { + decoration: TextEditorDecorationType; + highlightDecoration: TextEditorDecorationType | undefined; + }) { if (this.editor !== undefined) { this._blame = this.editor.document.isDirty ? Container.git.getBlameForFileContents(this._uri, this.editor.document.getText()) @@ -73,8 +86,13 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase return; } - const highlightDecorationRanges = Arrays.filterMap(blame.lines, - l => l.sha === sha ? this.editor.document.validateRange(new Range(l.line, 0, l.line, Number.MAX_SAFE_INTEGER)) : undefined); + const highlightDecorationRanges = Arrays.filterMap( + blame.lines, + l => + l.sha === sha + ? this.editor.document.validateRange(new Range(l.line, 0, l.line, Number.MAX_SAFE_INTEGER)) + : undefined + ); this.editor.setDecorations(this.highlightDecoration, highlightDecorationRanges); } @@ -109,16 +127,15 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase dates.sort((a, b) => a.getTime() - b.getTime()); const half = Math.floor(dates.length / 2); - const median = dates.length % 2 - ? dates[half].getTime() - : (dates[half - 1].getTime() + dates[half].getTime()) / 2.0; + const median = + dates.length % 2 ? dates[half].getTime() : (dates[half - 1].getTime() + dates[half].getTime()) / 2.0; const lookup: number[] = []; const newest = dates[dates.length - 1].getTime(); let step = (newest - median) / 5; for (let i = 5; i > 0; i--) { - lookup.push(median + (step * i)); + lookup.push(median + step * i); } lookup.push(median); @@ -126,7 +143,7 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase const oldest = dates[0].getTime(); step = (median - oldest) / 4; for (let i = 1; i <= 4; i++) { - lookup.push(median - (step * i)); + lookup.push(median - step * i); } const d = new Date(); @@ -154,28 +171,48 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase }; } - registerHoverProviders(providers: { details: boolean, changes: boolean }) { - if (!Container.config.hovers.enabled || !Container.config.hovers.annotations.enabled || (!providers.details && !providers.changes)) return; + registerHoverProviders(providers: { details: boolean; changes: boolean }) { + if ( + !Container.config.hovers.enabled || + !Container.config.hovers.annotations.enabled || + (!providers.details && !providers.changes) + ) { + return; + } const subscriptions: Disposable[] = []; if (providers.changes) { - subscriptions.push(languages.registerHoverProvider({ pattern: this.document.uri.fsPath }, { provideHover: this.provideChangesHover.bind(this) } as HoverProvider)); + subscriptions.push( + languages.registerHoverProvider({ pattern: this.document.uri.fsPath }, { + provideHover: this.provideChangesHover.bind(this) + } as HoverProvider) + ); } if (providers.details) { - subscriptions.push(languages.registerHoverProvider({ pattern: this.document.uri.fsPath }, { provideHover: this.provideDetailsHover.bind(this) } as HoverProvider)); + subscriptions.push( + languages.registerHoverProvider({ pattern: this.document.uri.fsPath }, { + provideHover: this.provideDetailsHover.bind(this) + } as HoverProvider) + ); } this._hoverProviderDisposable = Disposable.from(...subscriptions); } - async provideDetailsHover(document: TextDocument, position: Position, token: CancellationToken): Promise<Hover | undefined> { + async provideDetailsHover( + document: TextDocument, + position: Position, + token: CancellationToken + ): Promise<Hover | undefined> { const commit = await this.getCommitForHover(position); if (commit === undefined) return undefined; // Get the full commit message -- since blame only returns the summary let logCommit: GitCommit | undefined = undefined; if (!commit.isUncommitted) { - logCommit = await Container.git.getLogCommitForFile(commit.repoPath, commit.uri.fsPath, { ref: commit.sha }); + logCommit = await Container.git.getLogCommitForFile(commit.repoPath, commit.uri.fsPath, { + ref: commit.sha + }); if (logCommit !== undefined) { // Preserve the previous commit from the blame commit logCommit.previousFileName = commit.previousFileName; @@ -183,18 +220,34 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase } } - const message = Annotations.getHoverMessage(logCommit || commit, Container.config.defaultDateFormat, await Container.git.getRemotes(commit.repoPath), this.annotationType, this.editor.selection.active.line); - return new Hover(message, document.validateRange(new Range(position.line, 0, position.line, Number.MAX_SAFE_INTEGER))); + const message = Annotations.getHoverMessage( + logCommit || commit, + Container.config.defaultDateFormat, + await Container.git.getRemotes(commit.repoPath), + this.annotationType, + this.editor.selection.active.line + ); + return new Hover( + message, + document.validateRange(new Range(position.line, 0, position.line, Number.MAX_SAFE_INTEGER)) + ); } - async provideChangesHover(document: TextDocument, position: Position, token: CancellationToken): Promise<Hover | undefined> { + async provideChangesHover( + document: TextDocument, + position: Position, + token: CancellationToken + ): Promise<Hover | undefined> { const commit = await this.getCommitForHover(position); if (commit === undefined) return undefined; const hover = await Annotations.changesHover(commit, position.line, await GitUri.fromUri(document.uri)); if (hover.hoverMessage === undefined) return undefined; - return new Hover(hover.hoverMessage, document.validateRange(new Range(position.line, 0, position.line, Number.MAX_SAFE_INTEGER))); + return new Hover( + hover.hoverMessage, + document.validateRange(new Range(position.line, 0, position.line, Number.MAX_SAFE_INTEGER)) + ); } private async getCommitForHover(position: Position): Promise<GitCommit | undefined> { diff --git a/src/annotations/fileAnnotationController.ts b/src/annotations/fileAnnotationController.ts index 36cf8a5..37b422d 100644 --- a/src/annotations/fileAnnotationController.ts +++ b/src/annotations/fileAnnotationController.ts @@ -1,11 +1,32 @@ 'use strict'; import { Functions, Iterables } from '../system'; -import { ConfigurationChangeEvent, DecorationRangeBehavior, DecorationRenderOptions, Disposable, Event, EventEmitter, OverviewRulerLane, Progress, ProgressLocation, TextDocument, TextEditor, TextEditorDecorationType, TextEditorViewColumnChangeEvent, ThemeColor, window, workspace } from 'vscode'; +import { + ConfigurationChangeEvent, + DecorationRangeBehavior, + DecorationRenderOptions, + Disposable, + Event, + EventEmitter, + OverviewRulerLane, + Progress, + ProgressLocation, + TextDocument, + TextEditor, + TextEditorDecorationType, + TextEditorViewColumnChangeEvent, + ThemeColor, + window, + workspace +} from 'vscode'; import { AnnotationProviderBase, AnnotationStatus, TextEditorCorrelationKey } from './annotationProvider'; import { AnnotationsToggleMode, configuration, FileAnnotationType, HighlightLocations } from '../configuration'; import { CommandContext, isTextEditor, setCommandContext } from '../constants'; import { Container } from '../container'; -import { DocumentBlameStateChangeEvent, DocumentDirtyStateChangeEvent, GitDocumentState } from '../trackers/gitDocumentTracker'; +import { + DocumentBlameStateChangeEvent, + DocumentDirtyStateChangeEvent, + GitDocumentState +} from '../trackers/gitDocumentTracker'; import { GutterBlameAnnotationProvider } from './gutterBlameAnnotationProvider'; import { HeatmapBlameAnnotationProvider } from './heatmapBlameAnnotationProvider'; import { KeyboardScope, KeyCommand, Keys } from '../keyboard'; @@ -35,7 +56,6 @@ export const Decorations = { }; export class FileAnnotationController extends Disposable { - private _onDidToggleAnnotations = new EventEmitter<void>(); get onDidToggleAnnotations(): Event<void> { return this._onDidToggleAnnotations.event; @@ -52,9 +72,7 @@ export class FileAnnotationController extends Disposable { constructor() { super(() => this.dispose()); - this._disposable = Disposable.from( - configuration.onDidChange(this.onConfigurationChanged, this) - ); + this._disposable = Disposable.from(configuration.onDidChange(this.onConfigurationChanged, this)); this._toggleModes = new Map(); this.onConfigurationChanged(configuration.initializingChangeEvent); @@ -159,19 +177,27 @@ export class FileAnnotationController extends Disposable { if (initializing) return; - if (configuration.changed(e, configuration.name('blame').value) || + if ( + configuration.changed(e, configuration.name('blame').value) || configuration.changed(e, configuration.name('recentChanges').value) || configuration.changed(e, configuration.name('heatmap').value) || - configuration.changed(e, configuration.name('hovers').value)) { + configuration.changed(e, configuration.name('hovers').value) + ) { // Since the configuration has changed -- reset any visible annotations for (const provider of this._annotationProviders.values()) { if (provider === undefined) continue; if (provider.annotationType === FileAnnotationType.RecentChanges) { - provider.reset({ decoration: Decorations.recentChangesAnnotation!, highlightDecoration: Decorations.recentChangesHighlight }); + provider.reset({ + decoration: Decorations.recentChangesAnnotation!, + highlightDecoration: Decorations.recentChangesHighlight + }); } else if (provider.annotationType === FileAnnotationType.Blame) { - provider.reset({ decoration: Decorations.blameAnnotation, highlightDecoration: Decorations.blameHighlight }); + provider.reset({ + decoration: Decorations.blameAnnotation, + highlightDecoration: Decorations.blameHighlight + }); } else { this.show(provider.editor, FileAnnotationType.Heatmap); @@ -236,7 +262,10 @@ export class FileAnnotationController extends Disposable { const provider = this.getProvider(e.textEditor); if (provider === undefined) { // If we don't find an exact match, do a fuzzy match (since we can't properly track editors) - const fuzzyProvider = Iterables.find(this._annotationProviders.values(), p => p.editor.document === e.textEditor.document); + const fuzzyProvider = Iterables.find( + this._annotationProviders.values(), + p => p.editor.document === e.textEditor.document + ); if (fuzzyProvider == null) return; this.clearCore(fuzzyProvider.correlationKey, AnnotationClearReason.ColumnChanged); @@ -297,7 +326,11 @@ export class FileAnnotationController extends Disposable { return this._annotationProviders.get(AnnotationProviderBase.getCorrelationKey(editor)); } - async show(editor: TextEditor | undefined, type: FileAnnotationType, shaOrLine?: string | number): Promise<boolean> { + async show( + editor: TextEditor | undefined, + type: FileAnnotationType, + shaOrLine?: string | number + ): Promise<boolean> { if (this.getToggleMode(type) === AnnotationsToggleMode.Window) { let first = this._annotationType === undefined; const reset = !first && this._annotationType !== type; @@ -330,26 +363,44 @@ export class FileAnnotationController extends Disposable { return true; } - const provider = await window.withProgress({ location: ProgressLocation.Window }, async (progress: Progress<{ message: string }>) => { - await setCommandContext(CommandContext.AnnotationStatus, AnnotationStatus.Computing); - - const computingAnnotations = this.showAnnotationsCore(currentProvider, editor, type, shaOrLine, progress); - const provider = await computingAnnotations; + const provider = await window.withProgress( + { location: ProgressLocation.Window }, + async (progress: Progress<{ message: string }>) => { + await setCommandContext(CommandContext.AnnotationStatus, AnnotationStatus.Computing); + + const computingAnnotations = this.showAnnotationsCore( + currentProvider, + editor, + type, + shaOrLine, + progress + ); + const provider = await computingAnnotations; + + if (editor === this._editor) { + await setCommandContext(CommandContext.AnnotationStatus, provider && provider.status); + } - if (editor === this._editor) { - await setCommandContext(CommandContext.AnnotationStatus, provider && provider.status); + return computingAnnotations; } - - return computingAnnotations; - }); + ); return provider !== undefined; } - async toggle(editor: TextEditor | undefined, type: FileAnnotationType, shaOrLine?: string | number): Promise<boolean> { + async toggle( + editor: TextEditor | undefined, + type: FileAnnotationType, + shaOrLine?: string | number + ): Promise<boolean> { if (editor !== undefined) { const trackedDocument = await Container.tracker.getOrAdd(editor.document); - if ((type === FileAnnotationType.RecentChanges && !trackedDocument.isTracked) || !trackedDocument.isBlameable) return false; + if ( + (type === FileAnnotationType.RecentChanges && !trackedDocument.isTracked) || + !trackedDocument.isBlameable + ) { + return false; + } } const provider = this.getProvider(editor); @@ -417,7 +468,13 @@ export class FileAnnotationController extends Disposable { this._keyboardScope = undefined; } - private async showAnnotationsCore(currentProvider: AnnotationProviderBase | undefined, editor: TextEditor, type: FileAnnotationType, shaOrLine?: string | number, progress?: Progress<{ message: string }>): Promise<AnnotationProviderBase | undefined> { + private async showAnnotationsCore( + currentProvider: AnnotationProviderBase | undefined, + editor: TextEditor, + type: FileAnnotationType, + shaOrLine?: string | number, + progress?: Progress<{ message: string }> + ): Promise<AnnotationProviderBase | undefined> { if (progress !== undefined) { let annotationsLabel = 'annotations'; switch (type) { @@ -434,7 +491,9 @@ export class FileAnnotationController extends Disposable { break; } - progress!.report({ message: `Computing ${annotationsLabel} for ${path.basename(editor.document.fileName)}` }); + progress!.report({ + message: `Computing ${annotationsLabel} for ${path.basename(editor.document.fileName)}` + }); } // Allows pressing escape to exit the annotations @@ -445,15 +504,30 @@ export class FileAnnotationController extends Disposable { let provider: AnnotationProviderBase | undefined = undefined; switch (type) { case FileAnnotationType.Blame: - provider = new GutterBlameAnnotationProvider(editor, trackedDocument, Decorations.blameAnnotation, Decorations.blameHighlight); + provider = new GutterBlameAnnotationProvider( + editor, + trackedDocument, + Decorations.blameAnnotation, + Decorations.blameHighlight + ); break; case FileAnnotationType.Heatmap: - provider = new HeatmapBlameAnnotationProvider(editor, trackedDocument, Decorations.heatmapAnnotation, Decorations.heatmapHighlight); + provider = new HeatmapBlameAnnotationProvider( + editor, + trackedDocument, + Decorations.heatmapAnnotation, + Decorations.heatmapHighlight + ); break; case FileAnnotationType.RecentChanges: - provider = new RecentChangesAnnotationProvider(editor, trackedDocument, Decorations.recentChangesAnnotation!, Decorations.recentChangesHighlight); + provider = new RecentChangesAnnotationProvider( + editor, + trackedDocument, + Decorations.recentChangesAnnotation!, + Decorations.recentChangesHighlight + ); break; } if (provider === undefined || !(await provider.validate())) return undefined; @@ -483,4 +557,4 @@ export class FileAnnotationController extends Disposable { return undefined; } -} \ No newline at end of file +} diff --git a/src/annotations/gutterBlameAnnotationProvider.ts b/src/annotations/gutterBlameAnnotationProvider.ts index 96e9e05..39d7fc5 100644 --- a/src/annotations/gutterBlameAnnotationProvider.ts +++ b/src/annotations/gutterBlameAnnotationProvider.ts @@ -10,7 +10,6 @@ import { GitBlameCommit, ICommitFormatOptions } from '../gitService'; import { Logger } from '../logger'; export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase { - async onProvideAnnotation(shaOrLine?: string | number, type?: FileAnnotationType): Promise<boolean> { this.annotationType = FileAnnotationType.Blame; @@ -22,11 +21,13 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase { const cfg = Container.config.blame; // Precalculate the formatting options so we don't need to do it on each iteration - const tokenOptions = Strings.getTokensFromTemplate(cfg.format) - .reduce((map, token) => { + const tokenOptions = Strings.getTokensFromTemplate(cfg.format).reduce( + (map, token) => { map[token.key] = token.options as ICommitFormatOptions; return map; - }, {} as { [token: string]: ICommitFormatOptions }); + }, + {} as { [token: string]: ICommitFormatOptions } + ); const options: ICommitFormatOptions = { dateFormat: cfg.dateFormat === null ? Container.config.defaultDateFormat : cfg.dateFormat, @@ -40,7 +41,9 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase { this.decorations = []; const decorationsMap: { [sha: string]: DecorationOptions | undefined } = Object.create(null); - const avatarDecorationsMap: { [email: string]: { decoration: TextEditorDecorationType, ranges: Range[] } } | undefined = avatars ? Object.create(null) : undefined; + const avatarDecorationsMap: + | { [email: string]: { decoration: TextEditorDecorationType; ranges: Range[] } } + | undefined = avatars ? Object.create(null) : undefined; let commit: GitBlameCommit | undefined; let compacted = false; @@ -64,7 +67,9 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase { gutter.renderOptions = { before: { ...gutter.renderOptions!.before, - contentText: GlyphChars.Space.repeat(Strings.width(gutter.renderOptions!.before!.contentText!)) + contentText: GlyphChars.Space.repeat( + Strings.width(gutter.renderOptions!.before!.contentText!) + ) } }; @@ -138,14 +143,19 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase { } const duration = process.hrtime(start); - Logger.log(`${(duration[0] * 1000) + Math.floor(duration[1] / 1000000)} ms to compute gutter blame annotations`); + Logger.log(`${duration[0] * 1000 + Math.floor(duration[1] / 1000000)} ms to compute gutter blame annotations`); this.registerHoverProviders(Container.config.hovers.annotations); this.selection(shaOrLine, blame); return true; } - addOrUpdateGravatarDecoration(commit: GitBlameCommit, range: Range, gravatarDefault: GravatarDefaultStyle, map: { [email: string]: { decoration: TextEditorDecorationType, ranges: Range[] } }) { + addOrUpdateGravatarDecoration( + commit: GitBlameCommit, + range: Range, + gravatarDefault: GravatarDefaultStyle, + map: { [email: string]: { decoration: TextEditorDecorationType; ranges: Range[] } } + ) { const avatarDecoration = map[commit.email!]; if (avatarDecoration !== undefined) { avatarDecoration.ranges.push(range); @@ -161,4 +171,4 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase { ranges: [range] }; } -} \ No newline at end of file +} diff --git a/src/annotations/heatmapBlameAnnotationProvider.ts b/src/annotations/heatmapBlameAnnotationProvider.ts index c5f6330..2070cc8 100644 --- a/src/annotations/heatmapBlameAnnotationProvider.ts +++ b/src/annotations/heatmapBlameAnnotationProvider.ts @@ -8,7 +8,6 @@ import { GitBlameCommit } from '../gitService'; import { Logger } from '../logger'; export class HeatmapBlameAnnotationProvider extends BlameAnnotationProviderBase { - async onProvideAnnotation(shaOrLine?: string | number, type?: FileAnnotationType): Promise<boolean> { this.annotationType = FileAnnotationType.Heatmap; @@ -57,7 +56,7 @@ export class HeatmapBlameAnnotationProvider extends BlameAnnotationProviderBase } const duration = process.hrtime(start); - Logger.log(`${(duration[0] * 1000) + Math.floor(duration[1] / 1000000)} ms to compute heatmap annotations`); + Logger.log(`${duration[0] * 1000 + Math.floor(duration[1] / 1000000)} ms to compute heatmap annotations`); this.registerHoverProviders(Container.config.hovers.annotations); this.selection(shaOrLine, blame); diff --git a/src/annotations/hoverBlameAnnotationProvider.ts b/src/annotations/hoverBlameAnnotationProvider.ts index 96c7661..29e1f9c 100644 --- a/src/annotations/hoverBlameAnnotationProvider.ts +++ b/src/annotations/hoverBlameAnnotationProvider.ts @@ -68,4 +68,4 @@ // this.selection(shaOrLine, blame); // return true; // } -// } \ No newline at end of file +// } diff --git a/src/annotations/lineAnnotationController.ts b/src/annotations/lineAnnotationController.ts index a52b92c..dc3b1df 100644 --- a/src/annotations/lineAnnotationController.ts +++ b/src/annotations/lineAnnotationController.ts @@ -1,5 +1,15 @@ 'use strict'; -import { ConfigurationChangeEvent, debug, DecorationRangeBehavior, DecorationRenderOptions, Disposable, Range, TextEditor, TextEditorDecorationType, window } from 'vscode'; +import { + ConfigurationChangeEvent, + debug, + DecorationRangeBehavior, + DecorationRenderOptions, + Disposable, + Range, + TextEditor, + TextEditorDecorationType, + window +} from 'vscode'; import { Annotations } from './annotations'; import { configuration } from './../configuration'; import { isTextEditor } from './../constants'; @@ -15,7 +25,6 @@ const annotationDecoration: TextEditorDecorationType = window.createTextEditorDe } as DecorationRenderOptions); export class LineAnnotationController extends Disposable { - private _disposable: Disposable; private _debugSessionEndDisposable: Disposable | undefined; private _editor: TextEditor | undefined; @@ -190,8 +199,15 @@ export class LineAnnotationController extends Disposable { const state = Container.lineTracker.getState(l); if (state === undefined || state.commit === undefined) continue; - const decoration = Annotations.trailing(state.commit, cfg.format, cfg.dateFormat === null ? Container.config.defaultDateFormat : cfg.dateFormat, scrollable); - decoration.range = editor.document.validateRange(new Range(l, Number.MAX_SAFE_INTEGER, l, Number.MAX_SAFE_INTEGER)); + const decoration = Annotations.trailing( + state.commit, + cfg.format, + cfg.dateFormat === null ? Container.config.defaultDateFormat : cfg.dateFormat, + scrollable + ); + decoration.range = editor.document.validateRange( + new Range(l, Number.MAX_SAFE_INTEGER, l, Number.MAX_SAFE_INTEGER) + ); decorations.push(decoration); } @@ -203,9 +219,7 @@ export class LineAnnotationController extends Disposable { if (!Container.lineTracker.isSubscribed(this)) { Container.lineTracker.start( this, - Disposable.from( - Container.lineTracker.onDidChangeActiveLines(this.onActiveLinesChanged, this) - ) + Disposable.from(Container.lineTracker.onDidChangeActiveLines(this.onActiveLinesChanged, this)) ); } diff --git a/src/annotations/lineHoverController.ts b/src/annotations/lineHoverController.ts index a0c77d0..c1a8da8 100644 --- a/src/annotations/lineHoverController.ts +++ b/src/annotations/lineHoverController.ts @@ -1,12 +1,24 @@ 'use strict'; -import { CancellationToken, ConfigurationChangeEvent, debug, Disposable, Hover, HoverProvider, languages, Position, Range, TextDocument, TextEditor, window } from 'vscode'; +import { + CancellationToken, + ConfigurationChangeEvent, + debug, + Disposable, + Hover, + HoverProvider, + languages, + Position, + Range, + TextDocument, + TextEditor, + window +} from 'vscode'; import { Annotations } from './annotations'; import { configuration } from './../configuration'; import { Container } from './../container'; import { LinesChangeEvent } from './../trackers/gitLineTracker'; export class LineHoverController extends Disposable { - private _debugSessionEndDisposable: Disposable | undefined; private _disposable: Disposable; private _hoverProviderDisposable: Disposable | undefined; @@ -33,9 +45,13 @@ export class LineHoverController extends Disposable { private onConfigurationChanged(e: ConfigurationChangeEvent) { const initializing = configuration.initializing(e); - if (!initializing && + if ( + !initializing && !configuration.changed(e, configuration.name('hovers')('enabled').value) && - !configuration.changed(e, configuration.name('hovers')('currentLine')('enabled').value)) return; + !configuration.changed(e, configuration.name('hovers')('currentLine')('enabled').value) + ) { + return; + } if (Container.config.hovers.enabled && Container.config.hovers.currentLine.enabled) { Container.lineTracker.start( @@ -80,7 +96,11 @@ export class LineHoverController extends Disposable { } } - async provideDetailsHover(document: TextDocument, position: Position, token: CancellationToken): Promise<Hover | undefined> { + async provideDetailsHover( + document: TextDocument, + position: Position, + token: CancellationToken + ): Promise<Hover | undefined> { if (!Container.lineTracker.includes(position.line)) return undefined; const lineState = Container.lineTracker.getState(position.line); @@ -95,13 +115,17 @@ export class LineHoverController extends Disposable { // If we aren't showing the hover over the whole line, make sure the annotation is on if (!wholeLine && Container.lineAnnotations.suspended) return undefined; - const range = document.validateRange(new Range(position.line, wholeLine ? 0 : Number.MAX_SAFE_INTEGER, position.line, Number.MAX_SAFE_INTEGER)); + const range = document.validateRange( + new Range(position.line, wholeLine ? 0 : Number.MAX_SAFE_INTEGER, position.line, Number.MAX_SAFE_INTEGER) + ); if (!wholeLine && range.start.character !== position.character) return undefined; // Get the full commit message -- since blame only returns the summary let logCommit = lineState !== undefined ? lineState.logCommit : undefined; if (logCommit === undefined && !commit.isUncommitted) { - logCommit = await Container.git.getLogCommitForFile(commit.repoPath, commit.uri.fsPath, { ref: commit.sha }); + logCommit = await Container.git.getLogCommitForFile(commit.repoPath, commit.uri.fsPath, { + ref: commit.sha + }); if (logCommit !== undefined) { // Preserve the previous commit from the blame commit logCommit.previousSha = commit.previousSha; @@ -116,11 +140,21 @@ export class LineHoverController extends Disposable { const trackedDocument = await Container.tracker.get(document); if (trackedDocument === undefined) return undefined; - const message = Annotations.getHoverMessage(logCommit || commit, Container.config.defaultDateFormat, await Container.git.getRemotes(commit.repoPath), fileAnnotations, position.line); + const message = Annotations.getHoverMessage( + logCommit || commit, + Container.config.defaultDateFormat, + await Container.git.getRemotes(commit.repoPath), + fileAnnotations, + position.line + ); return new Hover(message, range); } - async provideChangesHover(document: TextDocument, position: Position, token: CancellationToken): Promise<Hover | undefined> { + async provideChangesHover( + document: TextDocument, + position: Position, + token: CancellationToken + ): Promise<Hover | undefined> { if (!Container.lineTracker.includes(position.line)) return undefined; const lineState = Container.lineTracker.getState(position.line); @@ -137,7 +171,9 @@ export class LineHoverController extends Disposable { // If we aren't showing the hover over the whole line, make sure the annotation is on if (!wholeLine && Container.lineAnnotations.suspended) return undefined; - const range = document.validateRange(new Range(position.line, wholeLine ? 0 : Number.MAX_SAFE_INTEGER, position.line, Number.MAX_SAFE_INTEGER)); + const range = document.validateRange( + new Range(position.line, wholeLine ? 0 : Number.MAX_SAFE_INTEGER, position.line, Number.MAX_SAFE_INTEGER) + ); if (!wholeLine && range.start.character !== position.character) return undefined; const trackedDocument = await Container.tracker.get(document); @@ -159,10 +195,18 @@ export class LineHoverController extends Disposable { const subscriptions = []; if (cfg.currentLine.changes) { - subscriptions.push(languages.registerHoverProvider({ pattern: editor.document.uri.fsPath }, { provideHover: this.provideChangesHover.bind(this) } as HoverProvider)); + subscriptions.push( + languages.registerHoverProvider({ pattern: editor.document.uri.fsPath }, { + provideHover: this.provideChangesHover.bind(this) + } as HoverProvider) + ); } if (cfg.currentLine.details) { - subscriptions.push(languages.registerHoverProvider({ pattern: editor.document.uri.fsPath }, { provideHover: this.provideDetailsHover.bind(this) } as HoverProvider)); + subscriptions.push( + languages.registerHoverProvider({ pattern: editor.document.uri.fsPath }, { + provideHover: this.provideDetailsHover.bind(this) + } as HoverProvider) + ); } this._hoverProviderDisposable = Disposable.from(...subscriptions); diff --git a/src/annotations/recentChangesAnnotationProvider.ts b/src/annotations/recentChangesAnnotationProvider.ts index 7c11201..e80b6c8 100644 --- a/src/annotations/recentChangesAnnotationProvider.ts +++ b/src/annotations/recentChangesAnnotationProvider.ts @@ -9,7 +9,6 @@ import { GitUri } from '../gitService'; import { Logger } from '../logger'; export class RecentChangesAnnotationProvider extends AnnotationProviderBase { - private readonly _uri: GitUri; constructor( @@ -48,14 +47,22 @@ export class RecentChangesAnnotationProvider extends AnnotationProviderBase { if (line.state === 'unchanged') continue; - const range = this.editor.document.validateRange(new Range(new Position(count, 0), new Position(count, Number.MAX_SAFE_INTEGER))); + const range = this.editor.document.validateRange( + new Range(new Position(count, 0), new Position(count, Number.MAX_SAFE_INTEGER)) + ); let message: MarkdownString | undefined = undefined; if (cfg.hovers.enabled && cfg.hovers.annotations.enabled) { if (cfg.hovers.annotations.details) { this.decorations.push({ - hoverMessage: Annotations.getHoverMessage(commit, dateFormat, await Container.git.getRemotes(commit.repoPath), this.annotationType, this.editor.selection.active.line), + hoverMessage: Annotations.getHoverMessage( + commit, + dateFormat, + await Container.git.getRemotes(commit.repoPath), + this.annotationType, + this.editor.selection.active.line + ), range: range } as DecorationOptions); } @@ -76,13 +83,14 @@ export class RecentChangesAnnotationProvider extends AnnotationProviderBase { this.editor.setDecorations(this.decoration, this.decorations); const duration = process.hrtime(start); - Logger.log(`${(duration[0] * 1000) + Math.floor(duration[1] / 1000000)} ms to compute recent changes annotations`); + Logger.log( + `${duration[0] * 1000 + Math.floor(duration[1] / 1000000)} ms to compute recent changes annotations` + ); return true; } - async selection(shaOrLine?: string | number): Promise<void> { - } + async selection(shaOrLine?: string | number): Promise<void> {} async validate(): Promise<boolean> { return true; diff --git a/src/codeLensController.ts b/src/codeLensController.ts index b6e0397..a8970b9 100644 --- a/src/codeLensController.ts +++ b/src/codeLensController.ts @@ -3,12 +3,15 @@ import { ConfigurationChangeEvent, Disposable, languages } from 'vscode'; import { configuration } from './configuration'; import { CommandContext, setCommandContext } from './constants'; import { Container } from './container'; -import { DocumentBlameStateChangeEvent, DocumentDirtyIdleTriggerEvent, GitDocumentState } from './trackers/gitDocumentTracker'; +import { + DocumentBlameStateChangeEvent, + DocumentDirtyIdleTriggerEvent, + GitDocumentState +} from './trackers/gitDocumentTracker'; import { GitCodeLensProvider } from './gitCodeLensProvider'; import { Logger } from './logger'; export class CodeLensController extends Disposable { - private _canToggle: boolean = false; private _disposable: Disposable | undefined; private _provider: GitCodeLensProvider | undefined; @@ -17,9 +20,7 @@ export class CodeLensController extends Disposable { constructor() { super(() => this.dispose()); - this._disposable = Disposable.from( - configuration.onDidChange(this.onConfigurationChanged, this) - ); + this._disposable = Disposable.from(configuration.onDidChange(this.onConfigurationChanged, this)); this.onConfigurationChanged(configuration.initializingChangeEvent); } @@ -32,9 +33,12 @@ export class CodeLensController extends Disposable { const initializing = configuration.initializing(e); const section = configuration.name('codeLens').value; - if (initializing || configuration.changed(e, section, null) || + if ( + initializing || + configuration.changed(e, section, null) || configuration.changed(e, configuration.name('defaultDateStyle').value) || - configuration.changed(e, configuration.name('defaultDateFormat').value)) { + configuration.changed(e, configuration.name('defaultDateFormat').value) + ) { if (!initializing) { Logger.log('CodeLens config changed; resetting CodeLens provider'); } diff --git a/src/commands.ts b/src/commands.ts index a586990..2f0afc0 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -104,4 +104,4 @@ export function configureCommands(): void { Container.context.subscriptions.push(new Commands.ToggleLineBlameCommand()); Container.context.subscriptions.push(new Commands.ToggleReviewModeCommand()); Container.context.subscriptions.push(new Commands.ToggleZenModeCommand()); -} \ No newline at end of file +} diff --git a/src/commands/clearFileAnnotations.ts b/src/commands/clearFileAnnotations.ts index c72bf8b..8448167 100644 --- a/src/commands/clearFileAnnotations.ts +++ b/src/commands/clearFileAnnotations.ts @@ -6,7 +6,6 @@ import { Container } from '../container'; import { Logger } from '../logger'; export class ClearFileAnnotationsCommand extends EditorCommand { - constructor() { super([Commands.ClearFileAnnotations, Commands.ComputingFileAnnotations]); } @@ -30,4 +29,4 @@ export class ClearFileAnnotationsCommand extends EditorCommand { return window.showErrorMessage(`Unable to clear file annotations. See output channel for more details`); } } -} \ No newline at end of file +} diff --git a/src/commands/closeUnchangedFiles.ts b/src/commands/closeUnchangedFiles.ts index cd35a02..5d20827 100644 --- a/src/commands/closeUnchangedFiles.ts +++ b/src/commands/closeUnchangedFiles.ts @@ -12,7 +12,6 @@ export interface CloseUnchangedFilesCommandArgs { } export class CloseUnchangedFilesCommand extends ActiveEditorCommand { - constructor() { super(Commands.CloseUnchangedFiles); } @@ -24,7 +23,11 @@ export class CloseUnchangedFilesCommand extends ActiveEditorCommand { if (args.uris === undefined) { args = { ...args }; - const repoPath = await getRepoPathOrActiveOrPrompt(uri, editor, `Close unchanged files in which repository${GlyphChars.Ellipsis}`); + const repoPath = await getRepoPathOrActiveOrPrompt( + uri, + editor, + `Close unchanged files in which repository${GlyphChars.Ellipsis}` + ); if (!repoPath) return undefined; const status = await Container.git.getStatusForRepo(repoPath); @@ -46,8 +49,11 @@ export class CloseUnchangedFilesCommand extends ActiveEditorCommand { break; } - if (editor.document !== undefined && - (editor.document.isDirty || args.uris.some(uri => UriComparer.equals(uri, editor!.document && editor!.document.uri)))) { + if ( + editor.document !== undefined && + (editor.document.isDirty || + args.uris.some(uri => UriComparer.equals(uri, editor!.document && editor!.document.uri))) + ) { const lastPrevious = previous; previous = editor; editor = await editorTracker.awaitNext(500); @@ -83,4 +89,4 @@ export class CloseUnchangedFilesCommand extends ActiveEditorCommand { return window.showErrorMessage(`Unable to close unchanged files. See output channel for more details`); } } -} \ No newline at end of file +} diff --git a/src/commands/common.ts b/src/commands/common.ts index d620ea7..ec5b069 100644 --- a/src/commands/common.ts +++ b/src/commands/common.ts @@ -1,5 +1,17 @@ 'use strict'; -import { commands, Disposable, SourceControlResourceGroup, SourceControlResourceState, TextDocumentShowOptions, TextEditor, TextEditorEdit, Uri, ViewColumn, window, workspace } from 'vscode'; +import { + commands, + Disposable, + SourceControlResourceGroup, + SourceControlResourceState, + TextDocumentShowOptions, + TextEditor, + TextEditorEdit, + Uri, + ViewColumn, + window, + workspace +} from 'vscode'; import { BuiltInCommands, DocumentSchemes, ImageExtensions } from '../constants'; import { Container } from '../container'; import { ExplorerNode, ExplorerRefNode } from '../views/explorerNodes'; @@ -78,7 +90,12 @@ export function getCommandUri(uri?: Uri, editor?: TextEditor): Uri | undefined { return document.uri; } -export async function getRepoPathOrActiveOrPrompt(uri: Uri | undefined, editor: TextEditor | undefined, placeholder: string, goBackCommand?: CommandQuickPickItem) { +export async function getRepoPathOrActiveOrPrompt( + uri: Uri | undefined, + editor: TextEditor | undefined, + placeholder: string, + goBackCommand?: CommandQuickPickItem +) { let repoPath = await Container.git.getRepoPathOrActive(uri, editor); if (!repoPath) { const pick = await RepositoriesQuickPick.show(placeholder, goBackCommand); @@ -133,28 +150,52 @@ export interface CommandViewContext extends CommandBaseContext { node: ExplorerNode; } -export function isCommandViewContextWithBranch(context: CommandContext): context is CommandViewContext & { node: (ExplorerNode & { branch: GitBranch }) } { - return context.type === 'view' && (context.node as (ExplorerNode & { branch?: GitBranch })).branch instanceof GitBranch; +export function isCommandViewContextWithBranch( + context: CommandContext +): context is CommandViewContext & { node: ExplorerNode & { branch: GitBranch } } { + return ( + context.type === 'view' && (context.node as ExplorerNode & { branch?: GitBranch }).branch instanceof GitBranch + ); } -export function isCommandViewContextWithCommit<T extends GitCommit>(context: CommandContext): context is CommandViewContext & { node: (ExplorerNode & { commit: T }) } { - return context.type === 'view' && (context.node as (ExplorerNode & { commit?: GitCommit })).commit instanceof GitCommit; +export function isCommandViewContextWithCommit<T extends GitCommit>( + context: CommandContext +): context is CommandViewContext & { node: ExplorerNode & { commit: T } } { + return ( + context.type === 'view' && (context.node as ExplorerNode & { commit?: GitCommit }).commit instanceof GitCommit + ); } -export function isCommandViewContextWithRef(context: CommandContext): context is CommandViewContext & { node: (ExplorerNode & { ref: string }) } { - return context.type === 'view' && (context.node instanceof ExplorerRefNode); +export function isCommandViewContextWithRef( + context: CommandContext +): context is CommandViewContext & { node: ExplorerNode & { ref: string } } { + return context.type === 'view' && context.node instanceof ExplorerRefNode; } -export function isCommandViewContextWithRemote(context: CommandContext): context is CommandViewContext & { node: (ExplorerNode & { remote: GitRemote }) } { - return context.type === 'view' && (context.node as (ExplorerNode & { remote?: GitRemote })).remote instanceof GitRemote; +export function isCommandViewContextWithRemote( + context: CommandContext +): context is CommandViewContext & { node: ExplorerNode & { remote: GitRemote } } { + return ( + context.type === 'view' && (context.node as ExplorerNode & { remote?: GitRemote }).remote instanceof GitRemote + ); } -export type CommandContext = CommandScmGroupsContext | CommandScmStatesContext | CommandUnknownContext | CommandUriContext | CommandViewContext; +export type CommandContext = + | CommandScmGroupsContext + | CommandScmStatesContext + | CommandUnknownContext + | CommandUriContext + | CommandViewContext; function isScmResourceGroup(group: any): group is SourceControlResourceGroup { if (group == null) return false; - return (group as SourceControlResourceGroup).id !== undefined && (group.handle !== undefined || (group as SourceControlResourceGroup).label !== undefined || (group as SourceControlResourceGroup).resourceStates !== undefined); + return ( + (group as SourceControlResourceGroup).id !== undefined && + (group.handle !== undefined || + (group as SourceControlResourceGroup).label !== undefined || + (group as SourceControlResourceGroup).resourceStates !== undefined) + ); } function isScmResourceState(state: any): state is SourceControlResourceState { @@ -166,11 +207,13 @@ function isScmResourceState(state: any): state is SourceControlResourceState { function isTextEditor(editor: any): editor is TextEditor { if (editor == null) return false; - return editor.id !== undefined && ((editor as TextEditor).edit !== undefined || (editor as TextEditor).document !== undefined); + return ( + editor.id !== undefined && + ((editor as TextEditor).edit !== undefined || (editor as TextEditor).document !== undefined) + ); } export abstract class Command extends Disposable { - static getMarkdownCommandArgsCore<T>(command: Commands, args: T): string { return `command:${command}?${encodeURIComponent(JSON.stringify(args))}`; } @@ -183,12 +226,18 @@ export abstract class Command extends Disposable { super(() => this.dispose()); if (typeof command === 'string') { - this._disposable = commands.registerCommand(command, (...args: any[]) => this._execute(command, ...args), this); + this._disposable = commands.registerCommand( + command, + (...args: any[]) => this._execute(command, ...args), + this + ); return; } - const subscriptions = command.map(cmd => commands.registerCommand(cmd, (...args: any[]) => this._execute(cmd, ...args), this)); + const subscriptions = command.map(cmd => + commands.registerCommand(cmd, (...args: any[]) => this._execute(cmd, ...args), this) + ); this._disposable = Disposable.from(...subscriptions); } @@ -209,7 +258,11 @@ export abstract class Command extends Disposable { return this.preExecute(context, ...rest); } - private static parseContext(command: string, options: CommandContextParsingOptions, ...args: any[]): [CommandContext, any[]] { + private static parseContext( + command: string, + options: CommandContextParsingOptions, + ...args: any[] + ): [CommandContext, any[]] { let editor: TextEditor | undefined = undefined; let firstArg = args[0]; @@ -239,7 +292,10 @@ export abstract class Command extends Disposable { states.push(arg); } - return [{ command: command, type: 'scm-states', scmResourceStates: states, uri: states[0].resourceUri }, args.slice(count)]; + return [ + { command: command, type: 'scm-states', scmResourceStates: states, uri: states[0].resourceUri }, + args.slice(count) + ]; } if (isScmResourceGroup(firstArg)) { @@ -260,7 +316,6 @@ export abstract class Command extends Disposable { } export abstract class ActiveEditorCommand extends Command { - protected readonly contextParsingOptions: CommandContextParsingOptions = { editor: true, uri: true }; constructor(command: Commands | Commands[]) { @@ -278,13 +333,12 @@ export abstract class ActiveEditorCommand extends Command { abstract execute(editor?: TextEditor, ...args: any[]): any; } -let lastCommand: { command: string, args: any[] } | undefined = undefined; +let lastCommand: { command: string; args: any[] } | undefined = undefined; export function getLastCommand() { return lastCommand; } export abstract class ActiveEditorCachedCommand extends ActiveEditorCommand { - constructor(command: Commands | Commands[]) { super(command); } @@ -301,7 +355,6 @@ export abstract class ActiveEditorCachedCommand extends ActiveEditorCommand { } export abstract class EditorCommand extends Disposable { - private _disposable: Disposable; constructor(command: Commands | Commands[]) { @@ -313,7 +366,14 @@ export abstract class EditorCommand extends Disposable { const subscriptions = []; for (const cmd of command) { - subscriptions.push(commands.registerTextEditorCommand(cmd, (editor: TextEditor, edit: TextEditorEdit, ...args: any[]) => this.executeCore(cmd, editor, edit, ...args), this)); + subscriptions.push( + commands.registerTextEditorCommand( + cmd, + (editor: TextEditor, edit: TextEditorEdit, ...args: any[]) => + this.executeCore(cmd, editor, edit, ...args), + this + ) + ); } this._disposable = Disposable.from(...subscriptions); } @@ -330,7 +390,10 @@ export abstract class EditorCommand extends Disposable { abstract execute(editor: TextEditor, edit: TextEditorEdit, ...args: any[]): any; } -export async function openEditor(uri: Uri, options: TextDocumentShowOptions & { rethrow?: boolean } = {}): Promise<TextEditor | undefined> { +export async function openEditor( + uri: Uri, + options: TextDocumentShowOptions & { rethrow?: boolean } = {} +): Promise<TextEditor | undefined> { const { rethrow, ...opts } = options; try { if (uri instanceof GitUri) { @@ -373,4 +436,4 @@ export async function openEditor(uri: Uri, options: TextDocumentShowOptions & { Logger.error(ex, 'openEditor'); return undefined; } -} \ No newline at end of file +} diff --git a/src/commands/copyMessageToClipboard.ts b/src/commands/copyMessageToClipboard.ts index 8089803..27653ca 100644 --- a/src/commands/copyMessageToClipboard.ts +++ b/src/commands/copyMessageToClipboard.ts @@ -12,7 +12,6 @@ export interface CopyMessageToClipboardCommandArgs { } export class CopyMessageToClipboardCommand extends ActiveEditorCommand { - constructor() { super(Commands.CopyMessageToClipboard); } @@ -53,9 +52,14 @@ export class CopyMessageToClipboardCommand extends ActiveEditorCommand { if (blameline < 0) return undefined; try { - const blame = editor && editor.document && editor.document.isDirty - ? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText()) - : await Container.git.getBlameForLine(gitUri, blameline); + const blame = + editor && editor.document && editor.document.isDirty + ? await Container.git.getBlameForLineContents( + gitUri, + blameline, + editor.document.getText() + ) + : await Container.git.getBlameForLine(gitUri, blameline); if (!blame) return undefined; if (blame.commit.isUncommitted) return undefined; @@ -78,12 +82,14 @@ export class CopyMessageToClipboardCommand extends ActiveEditorCommand { args.message = commit.message; } - void await clipboard.write(args.message); + void (await clipboard.write(args.message)); return undefined; } catch (ex) { - if (ex.message.includes('Couldn\'t find the required `xsel` binary')) { - window.showErrorMessage(`Unable to copy message, xsel is not installed. You can install it via \`sudo apt install xsel\``); + if (ex.message.includes("Couldn't find the required `xsel` binary")) { + window.showErrorMessage( + `Unable to copy message, xsel is not installed. You can install it via \`sudo apt install xsel\`` + ); return; } diff --git a/src/commands/copyShaToClipboard.ts b/src/commands/copyShaToClipboard.ts index 63ded39..d94a688 100644 --- a/src/commands/copyShaToClipboard.ts +++ b/src/commands/copyShaToClipboard.ts @@ -11,7 +11,6 @@ export interface CopyShaToClipboardCommandArgs { } export class CopyShaToClipboardCommand extends ActiveEditorCommand { - constructor() { super(Commands.CopyShaToClipboard); } @@ -50,9 +49,10 @@ export class CopyShaToClipboardCommand extends ActiveEditorCommand { try { const gitUri = await GitUri.fromUri(uri); - const blame = editor && editor.document && editor.document.isDirty - ? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText()) - : await Container.git.getBlameForLine(gitUri, blameline); + const blame = + editor && editor.document && editor.document.isDirty + ? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText()) + : await Container.git.getBlameForLine(gitUri, blameline); if (blame === undefined) return undefined; args.sha = blame.commit.sha; @@ -63,12 +63,14 @@ export class CopyShaToClipboardCommand extends ActiveEditorCommand { } } - void await clipboard.write(args.sha); + void (await clipboard.write(args.sha)); return undefined; } catch (ex) { - if (ex.message.includes('Couldn\'t find the required `xsel` binary')) { - window.showErrorMessage(`Unable to copy commit id, xsel is not installed. You can install it via \`sudo apt install xsel\``); + if (ex.message.includes("Couldn't find the required `xsel` binary")) { + window.showErrorMessage( + `Unable to copy commit id, xsel is not installed. You can install it via \`sudo apt install xsel\`` + ); return; } diff --git a/src/commands/diffBranchWithBranch.ts b/src/commands/diffBranchWithBranch.ts index 8163aaa..934b91c 100644 --- a/src/commands/diffBranchWithBranch.ts +++ b/src/commands/diffBranchWithBranch.ts @@ -12,7 +12,6 @@ export interface DiffBranchWithBranchCommandArgs { } export class DiffBranchWithBranchCommand extends ActiveEditorCommand { - constructor() { super([Commands.DiffHeadWithBranch, Commands.DiffWorkingWithBranch]); } @@ -39,7 +38,11 @@ export class DiffBranchWithBranchCommand extends ActiveEditorCommand { let progressCancellation: CancellationTokenSource | undefined; try { - const repoPath = await getRepoPathOrActiveOrPrompt(uri, editor, `Compare with branch or tag in which repository${GlyphChars.Ellipsis}`); + const repoPath = await getRepoPathOrActiveOrPrompt( + uri, + editor, + `Compare with branch or tag in which repository${GlyphChars.Ellipsis}` + ); if (!repoPath) return undefined; if (!args.ref1) { @@ -56,7 +59,7 @@ export class DiffBranchWithBranchCommand extends ActiveEditorCommand { break; } - progressCancellation = BranchesAndTagsQuickPick.showProgress(placeHolder); + progressCancellation = BranchesAndTagsQuickPick.showProgress(placeHolder); const [branches, tags] = await Promise.all([ Container.git.getBranches(repoPath), @@ -65,7 +68,9 @@ export class DiffBranchWithBranchCommand extends ActiveEditorCommand { if (progressCancellation.token.isCancellationRequested) return undefined; - const pick = await BranchesAndTagsQuickPick.show(branches, tags, placeHolder, { progressCancellation: progressCancellation }); + const pick = await BranchesAndTagsQuickPick.show(branches, tags, placeHolder, { + progressCancellation: progressCancellation + }); if (pick === undefined) return undefined; if (pick instanceof CommandQuickPickItem) return pick.execute(); @@ -86,4 +91,4 @@ export class DiffBranchWithBranchCommand extends ActiveEditorCommand { progressCancellation && progressCancellation.cancel(); } } -} \ No newline at end of file +} diff --git a/src/commands/diffDirectory.ts b/src/commands/diffDirectory.ts index a9c9d0a..4383fb5 100644 --- a/src/commands/diffDirectory.ts +++ b/src/commands/diffDirectory.ts @@ -14,9 +14,13 @@ export interface DiffDirectoryCommandArgs { } export class DiffDirectoryCommand extends ActiveEditorCommand { - constructor() { - super([Commands.DiffDirectory, Commands.ExternalDiffAll, Commands.ExplorersOpenDirectoryDiff, Commands.ExplorersOpenDirectoryDiffWithWorking]); + super([ + Commands.DiffDirectory, + Commands.ExternalDiffAll, + Commands.ExplorersOpenDirectoryDiff, + Commands.ExplorersOpenDirectoryDiffWithWorking + ]); } protected async preExecute(context: CommandContext, args: DiffDirectoryCommandArgs = {}): Promise<any> { @@ -50,7 +54,11 @@ export class DiffDirectoryCommand extends ActiveEditorCommand { let progressCancellation: CancellationTokenSource | undefined; try { - const repoPath = await getRepoPathOrActiveOrPrompt(uri, editor, `Compare directory in which repository${GlyphChars.Ellipsis}`); + const repoPath = await getRepoPathOrActiveOrPrompt( + uri, + editor, + `Compare directory in which repository${GlyphChars.Ellipsis}` + ); if (!repoPath) return undefined; if (!args.ref1) { @@ -67,7 +75,9 @@ export class DiffDirectoryCommand extends ActiveEditorCommand { if (progressCancellation.token.isCancellationRequested) return undefined; - const pick = await BranchesAndTagsQuickPick.show(branches, tags, placeHolder, { progressCancellation: progressCancellation }); + const pick = await BranchesAndTagsQuickPick.show(branches, tags, placeHolder, { + progressCancellation: progressCancellation + }); if (pick === undefined) return undefined; if (pick instanceof CommandQuickPickItem) return pick.execute(); @@ -82,10 +92,16 @@ export class DiffDirectoryCommand extends ActiveEditorCommand { catch (ex) { const msg = ex && ex.toString(); if (msg === 'No diff tool found') { - const result = await window.showWarningMessage(`Unable to open directory compare because there is no Git diff tool configured`, 'View Git Docs'); + const result = await window.showWarningMessage( + `Unable to open directory compare because there is no Git diff tool configured`, + 'View Git Docs' + ); if (!result) return undefined; - return commands.executeCommand(BuiltInCommands.Open, Uri.parse('https://git-scm.com/docs/git-config#git-config-difftool')); + return commands.executeCommand( + BuiltInCommands.Open, + Uri.parse('https://git-scm.com/docs/git-config#git-config-difftool') + ); } Logger.error(ex, 'DiffDirectoryCommand'); @@ -95,4 +111,4 @@ export class DiffDirectoryCommand extends ActiveEditorCommand { progressCancellation && progressCancellation.cancel(); } } -} \ No newline at end of file +} diff --git a/src/commands/diffLineWithPrevious.ts b/src/commands/diffLineWithPrevious.ts index 5108f7e..a057586 100644 --- a/src/commands/diffLineWithPrevious.ts +++ b/src/commands/diffLineWithPrevious.ts @@ -15,7 +15,6 @@ export interface DiffLineWithPreviousCommandArgs { } export class DiffLineWithPreviousCommand extends ActiveEditorCommand { - constructor() { super(Commands.DiffLineWithPrevious); } @@ -36,10 +35,13 @@ export class DiffLineWithPreviousCommand extends ActiveEditorCommand { if (blameline < 0) return undefined; try { - const blame = editor && editor.document && editor.document.isDirty - ? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText()) - : await Container.git.getBlameForLine(gitUri, blameline); - if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); + const blame = + editor && editor.document && editor.document.isDirty + ? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText()) + : await Container.git.getBlameForLine(gitUri, blameline); + if (blame === undefined) { + return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); + } args.commit = blame.commit; @@ -74,4 +76,4 @@ export class DiffLineWithPreviousCommand extends ActiveEditorCommand { }; return commands.executeCommand(Commands.DiffWith, diffArgs); } -} \ No newline at end of file +} diff --git a/src/commands/diffLineWithWorking.ts b/src/commands/diffLineWithWorking.ts index f35055b..8707bb2 100644 --- a/src/commands/diffLineWithWorking.ts +++ b/src/commands/diffLineWithWorking.ts @@ -15,7 +15,6 @@ export interface DiffLineWithWorkingCommandArgs { } export class DiffLineWithWorkingCommand extends ActiveEditorCommand { - constructor() { super(Commands.DiffLineWithWorking); } @@ -36,10 +35,13 @@ export class DiffLineWithWorkingCommand extends ActiveEditorCommand { if (blameline < 0) return undefined; try { - const blame = editor && editor.document && editor.document.isDirty - ? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText()) - : await Container.git.getBlameForLine(gitUri, blameline); - if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); + const blame = + editor && editor.document && editor.document.isDirty + ? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText()) + : await Container.git.getBlameForLine(gitUri, blameline); + if (blame === undefined) { + return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); + } args.commit = blame.commit; @@ -47,9 +49,10 @@ export class DiffLineWithWorkingCommand extends ActiveEditorCommand { if (args.commit.isUncommitted) { const status = await Container.git.getStatusForFile(gitUri.repoPath!, gitUri.fsPath); args.commit = args.commit.with({ - sha: status !== undefined && status.indexStatus !== undefined - ? GitService.stagedUncommittedSha - : args.commit.previousSha!, + sha: + status !== undefined && status.indexStatus !== undefined + ? GitService.stagedUncommittedSha + : args.commit.previousSha!, fileName: args.commit.previousFileName!, originalFileName: null, previousSha: null, diff --git a/src/commands/diffWith.ts b/src/commands/diffWith.ts index ef757db..1824d03 100644 --- a/src/commands/diffWith.ts +++ b/src/commands/diffWith.ts @@ -23,7 +23,6 @@ export interface DiffWithCommandArgs { } export class DiffWithCommand extends ActiveEditorCommand { - static getMarkdownCommandArgs(args: DiffWithCommandArgs): string; static getMarkdownCommandArgs(commit1: GitCommit, commit2: GitCommit): string; static getMarkdownCommandArgs(argsOrCommit1: DiffWithCommandArgs | GitCommit, commit2?: GitCommit): string { @@ -85,7 +84,12 @@ export class DiffWithCommand extends ActiveEditorCommand { } async execute(editor?: TextEditor, uri?: Uri, args: DiffWithCommandArgs = {}): Promise<any> { - args = { ...args, lhs: { ...args.lhs }, rhs: { ...args.rhs }, showOptions: { ...args.showOptions} } as DiffWithCommandArgs; + args = { + ...args, + lhs: { ...args.lhs }, + rhs: { ...args.rhs }, + showOptions: { ...args.showOptions } + } as DiffWithCommandArgs; if (args.repoPath === undefined || args.lhs === undefined || args.rhs === undefined) return undefined; try { @@ -105,9 +109,7 @@ export class DiffWithCommand extends ActiveEditorCommand { let rhsPrefix = ''; if (rhs === undefined) { - rhsPrefix = GitService.isUncommitted(args.rhs.sha) - ? ' (deleted)' - : 'deleted in '; + rhsPrefix = GitService.isUncommitted(args.rhs.sha) ? ' (deleted)' : 'deleted in '; } else if (lhs === undefined || args.lhs.sha === GitService.deletedSha) { rhsPrefix = 'added in '; @@ -124,18 +126,27 @@ export class DiffWithCommand extends ActiveEditorCommand { } } - if (args.lhs.title === undefined && args.lhs.sha !== GitService.deletedSha && (lhs !== undefined || lhsPrefix !== '')) { + if ( + args.lhs.title === undefined && + args.lhs.sha !== GitService.deletedSha && + (lhs !== undefined || lhsPrefix !== '') + ) { const suffix = GitService.shortenSha(args.lhs.sha) || ''; - args.lhs.title = `${path.basename(args.lhs.uri.fsPath)}${suffix !== '' ? ` (${lhsPrefix}${suffix})` : ''}`; + args.lhs.title = `${path.basename(args.lhs.uri.fsPath)}${ + suffix !== '' ? ` (${lhsPrefix}${suffix})` : '' + }`; } if (args.rhs.title === undefined && args.rhs.sha !== GitService.deletedSha) { const suffix = GitService.shortenSha(args.rhs.sha, { uncommitted: 'working tree' }) || ''; - args.rhs.title = `${path.basename(args.rhs.uri.fsPath)}${suffix !== '' ? ` (${rhsPrefix}${suffix})` : rhsPrefix}`; + args.rhs.title = `${path.basename(args.rhs.uri.fsPath)}${ + suffix !== '' ? ` (${rhsPrefix}${suffix})` : rhsPrefix + }`; } - const title = (args.lhs.title !== undefined && args.rhs.title !== undefined) - ? `${args.lhs.title} ${GlyphChars.ArrowLeftRightLong} ${args.rhs.title}` - : args.lhs.title || args.rhs.title; + const title = + args.lhs.title !== undefined && args.rhs.title !== undefined + ? `${args.lhs.title} ${GlyphChars.ArrowLeftRightLong} ${args.rhs.title}` + : args.lhs.title || args.rhs.title; if (args.showOptions === undefined) { args.showOptions = {}; @@ -149,7 +160,8 @@ export class DiffWithCommand extends ActiveEditorCommand { args.showOptions.selection = new Range(args.line, 0, args.line, 0); } - return await commands.executeCommand(BuiltInCommands.Diff, + return await commands.executeCommand( + BuiltInCommands.Diff, lhs === undefined ? GitUri.toRevisionUri(GitService.deletedSha, args.lhs.uri.fsPath, args.repoPath) : Uri.file(lhs), @@ -157,11 +169,12 @@ export class DiffWithCommand extends ActiveEditorCommand { ? GitUri.toRevisionUri(GitService.deletedSha, args.rhs.uri.fsPath, args.repoPath) : Uri.file(rhs), title, - args.showOptions); + args.showOptions + ); } catch (ex) { Logger.error(ex, 'DiffWithCommand', 'getVersionedFile'); return window.showErrorMessage(`Unable to open compare. See output channel for more details`); } } -} \ No newline at end of file +} diff --git a/src/commands/diffWithBranch.ts b/src/commands/diffWithBranch.ts index d40a9cc..35c922f 100644 --- a/src/commands/diffWithBranch.ts +++ b/src/commands/diffWithBranch.ts @@ -18,7 +18,6 @@ export interface DiffWithBranchCommandArgs { } export class DiffWithBranchCommand extends ActiveEditorCommand { - constructor() { super(Commands.DiffWithBranch); } @@ -46,7 +45,10 @@ export class DiffWithBranchCommand extends ActiveEditorCommand { if (progressCancellation.token.isCancellationRequested) return undefined; - const pick = await BranchesAndTagsQuickPick.show(branches, tags, placeHolder, { progressCancellation: progressCancellation, goBackCommand: args.goBackCommand }); + const pick = await BranchesAndTagsQuickPick.show(branches, tags, placeHolder, { + progressCancellation: progressCancellation, + goBackCommand: args.goBackCommand + }); if (pick === undefined) return undefined; if (pick instanceof CommandQuickPickItem) return pick.execute(); @@ -72,7 +74,7 @@ export class DiffWithBranchCommand extends ActiveEditorCommand { repoPath: gitUri.repoPath, lhs: { sha: pick.remote ? `remotes/${ref}` : ref, - uri: renamedUri || gitUri as Uri, + uri: renamedUri || (gitUri as Uri), title: renamedTitle || `${path.basename(gitUri.fsPath)} (${ref})` }, rhs: { @@ -88,4 +90,4 @@ export class DiffWithBranchCommand extends ActiveEditorCommand { progressCancellation.cancel(); } } -} \ No newline at end of file +} diff --git a/src/commands/diffWithNext.ts b/src/commands/diffWithNext.ts index 472e266..c30d513 100644 --- a/src/commands/diffWithNext.ts +++ b/src/commands/diffWithNext.ts @@ -17,7 +17,6 @@ export interface DiffWithNextCommandArgs { } export class DiffWithNextCommand extends ActiveEditorCommand { - constructor() { super(Commands.DiffWithNext); } @@ -55,8 +54,14 @@ export class DiffWithNextCommand extends ActiveEditorCommand { return commands.executeCommand(Commands.DiffWith, diffArgs); } - const log = await Container.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { maxCount: sha !== undefined ? undefined : 2, range: args.range!, renames: true }); - if (log === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); + const log = await Container.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { + maxCount: sha !== undefined ? undefined : 2, + range: args.range!, + renames: true + }); + if (log === undefined) { + return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); + } args.commit = (sha && log.commits.get(sha)) || Iterables.first(log.commits.values()); @@ -74,7 +79,7 @@ export class DiffWithNextCommand extends ActiveEditorCommand { if (args.commit.nextSha === undefined) { // Check if the file is staged - status = status || await Container.git.getStatusForFile(gitUri.repoPath!, gitUri.fsPath); + status = status || (await Container.git.getStatusForFile(gitUri.repoPath!, gitUri.fsPath)); if (status !== undefined && status.indexStatus === 'M') { const diffArgs: DiffWithCommandArgs = { repoPath: args.commit.repoPath, @@ -111,4 +116,4 @@ export class DiffWithNextCommand extends ActiveEditorCommand { }; return commands.executeCommand(Commands.DiffWith, diffArgs); } -} \ No newline at end of file +} diff --git a/src/commands/diffWithPrevious.ts b/src/commands/diffWithPrevious.ts index 8d0bdac..70d0950 100644 --- a/src/commands/diffWithPrevious.ts +++ b/src/commands/diffWithPrevious.ts @@ -18,7 +18,6 @@ export interface DiffWithPreviousCommandArgs { } export class DiffWithPreviousCommand extends ActiveEditorCommand { - constructor() { super([Commands.DiffWithPrevious, Commands.DiffWithPreviousInDiff]); } @@ -59,8 +58,14 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand { sha = sha + '^'; } - const log = await Container.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { maxCount: 2, ref: sha, renames: true }); - if (log === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); + const log = await Container.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { + maxCount: 2, + ref: sha, + renames: true + }); + if (log === undefined) { + return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); + } args.commit = (sha && log.commits.get(sha)) || Iterables.first(log.commits.values()); @@ -73,7 +78,9 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand { const diffArgs: DiffWithCommandArgs = { repoPath: args.commit.repoPath, lhs: { - sha: args.inDiffEditor ? args.commit.previousSha || GitService.deletedSha : args.commit.sha, + sha: args.inDiffEditor + ? args.commit.previousSha || GitService.deletedSha + : args.commit.sha, uri: args.inDiffEditor ? args.commit.previousUri : args.commit.uri }, rhs: { @@ -106,7 +113,10 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand { } if (!args.inDiffEditor) { - return commands.executeCommand(Commands.DiffWithWorking, uri, { commit: args.commit, showOptions: args.showOptions } as DiffWithWorkingCommandArgs); + return commands.executeCommand(Commands.DiffWithWorking, uri, { + commit: args.commit, + showOptions: args.showOptions + } as DiffWithWorkingCommandArgs); } } } @@ -132,4 +142,4 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand { }; return commands.executeCommand(Commands.DiffWith, diffArgs); } -} \ No newline at end of file +} diff --git a/src/commands/diffWithRevision.ts b/src/commands/diffWithRevision.ts index e1296f1..08be1b3 100644 --- a/src/commands/diffWithRevision.ts +++ b/src/commands/diffWithRevision.ts @@ -19,7 +19,6 @@ export interface DiffWithRevisionCommandArgs { } export class DiffWithRevisionCommand extends ActiveEditorCommand { - constructor() { super(Commands.DiffWithRevision); } @@ -35,47 +34,75 @@ export class DiffWithRevisionCommand extends ActiveEditorCommand { const gitUri = await GitUri.fromUri(uri); - const placeHolder = `Compare ${gitUri.getFormattedPath()}${gitUri.sha ? ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${gitUri.shortSha}` : ''} with ${GlyphChars.Ellipsis}`; + const placeHolder = `Compare ${gitUri.getFormattedPath()}${ + gitUri.sha ? ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${gitUri.shortSha}` : '' + } with ${GlyphChars.Ellipsis}`; const progressCancellation = FileHistoryQuickPick.showProgress(placeHolder); try { - const log = await Container.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { maxCount: args.maxCount, ref: gitUri.sha }); - if (log === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open history compare'); + const log = await Container.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { + maxCount: args.maxCount, + ref: gitUri.sha + }); + if (log === undefined) { + return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open history compare'); + } if (progressCancellation.token.isCancellationRequested) return undefined; let previousPageCommand: CommandQuickPickItem | undefined = undefined; if (log.truncated) { - const npc = new CommandQuickPickItem({ - label: `$(arrow-right) Show Next Commits`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} newer commits` - }, Commands.DiffWithRevision, [uri, { ...args } as DiffWithRevisionCommandArgs]); + const npc = new CommandQuickPickItem( + { + label: `$(arrow-right) Show Next Commits`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} newer commits` + }, + Commands.DiffWithRevision, + [uri, { ...args } as DiffWithRevisionCommandArgs] + ); const last = Iterables.last(log.commits.values()); if (last != null) { - previousPageCommand = new CommandQuickPickItem({ - label: `$(arrow-left) Show Previous Commits`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} older commits` - }, Commands.DiffWithRevision, [new GitUri(uri, last), { ...args, nextPageCommand: npc } as DiffWithRevisionCommandArgs]); + previousPageCommand = new CommandQuickPickItem( + { + label: `$(arrow-left) Show Previous Commits`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} older commits` + }, + Commands.DiffWithRevision, + [new GitUri(uri, last), { ...args, nextPageCommand: npc } as DiffWithRevisionCommandArgs] + ); } } const pick = await FileHistoryQuickPick.show(log, gitUri, placeHolder, { pickerOnly: true, progressCancellation: progressCancellation, - currentCommand: new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to history of ${GlyphChars.Space}$(file-text) ${gitUri.getFormattedPath()}${gitUri.sha ? ` from ${GlyphChars.Space}$(git-commit) ${gitUri.shortSha}` : ''}` - }, Commands.DiffWithRevision, [uri, { ...args }]), + currentCommand: new CommandQuickPickItem( + { + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to history of ${ + GlyphChars.Space + }$(file-text) ${gitUri.getFormattedPath()}${ + gitUri.sha ? ` from ${GlyphChars.Space}$(git-commit) ${gitUri.shortSha}` : '' + }` + }, + Commands.DiffWithRevision, + [uri, { ...args }] + ), nextPageCommand: args.nextPageCommand, previousPageCommand: previousPageCommand, - showAllCommand: log !== undefined && log.truncated - ? new CommandQuickPickItem({ - label: `$(sync) Show All Commits`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} this may take a while` - }, Commands.DiffWithRevision, [uri, { ...args, maxCount: 0 }]) - : undefined + showAllCommand: + log !== undefined && log.truncated + ? new CommandQuickPickItem( + { + label: `$(sync) Show All Commits`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} this may take a while` + }, + Commands.DiffWithRevision, + [uri, { ...args, maxCount: 0 }] + ) + : undefined }); if (pick === undefined) return undefined; @@ -117,5 +144,5 @@ export class DiffWithRevisionCommand extends ActiveEditorCommand { finally { progressCancellation.cancel(); } - } -} \ No newline at end of file + } +} diff --git a/src/commands/diffWithWorking.ts b/src/commands/diffWithWorking.ts index 4fa109b..91d8d07 100644 --- a/src/commands/diffWithWorking.ts +++ b/src/commands/diffWithWorking.ts @@ -15,7 +15,6 @@ export interface DiffWithWorkingCommandArgs { } export class DiffWithWorkingCommand extends ActiveEditorCommand { - constructor() { super(Commands.DiffWithWorking); } @@ -60,11 +59,20 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand { } try { - args.commit = await Container.git.getLogCommitForFile(gitUri.repoPath, gitUri.fsPath, { ref: gitUri.sha, firstIfNotFound: true }); - if (args.commit === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); + args.commit = await Container.git.getLogCommitForFile(gitUri.repoPath, gitUri.fsPath, { + ref: gitUri.sha, + firstIfNotFound: true + }); + if (args.commit === undefined) { + return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); + } } catch (ex) { - Logger.error(ex, 'DiffWithWorkingCommand', `getLogCommit(${gitUri.repoPath}, ${gitUri.fsPath}, ${gitUri.sha})`); + Logger.error( + ex, + 'DiffWithWorkingCommand', + `getLogCommit(${gitUri.repoPath}, ${gitUri.fsPath}, ${gitUri.sha})` + ); return window.showErrorMessage(`Unable to open compare. See output channel for more details`); } } diff --git a/src/commands/externalDiff.ts b/src/commands/externalDiff.ts index 9630ffe..20350af 100644 --- a/src/commands/externalDiff.ts +++ b/src/commands/externalDiff.ts @@ -40,11 +40,10 @@ interface Resource extends SourceControlResourceState { } class ExternalDiffFile { - constructor( public readonly uri: Uri, public readonly staged: boolean - ) { } + ) {} } export interface ExternalDiffCommandArgs { @@ -52,7 +51,6 @@ export interface ExternalDiffCommandArgs { } export class ExternalDiffCommand extends Command { - constructor() { super(Commands.ExternalDiff); } @@ -60,15 +58,24 @@ export class ExternalDiffCommand extends Command { protected async preExecute(context: CommandContext, args: ExternalDiffCommandArgs = {}): Promise<any> { if (context.type === 'scm-states') { args = { ...args }; - args.files = context.scmResourceStates - .map(r => new ExternalDiffFile(r.resourceUri, (r as Resource).resourceGroupType === ResourceGroupType.Index)); + args.files = context.scmResourceStates.map( + r => new ExternalDiffFile(r.resourceUri, (r as Resource).resourceGroupType === ResourceGroupType.Index) + ); return this.execute(args); } else if (context.type === 'scm-groups') { args = { ...args }; - args.files = Arrays.filterMap(context.scmResourceGroups[0].resourceStates, - r => this.isModified(r) ? new ExternalDiffFile(r.resourceUri, (r as Resource).resourceGroupType === ResourceGroupType.Index) : undefined); + args.files = Arrays.filterMap( + context.scmResourceGroups[0].resourceStates, + r => + this.isModified(r) + ? new ExternalDiffFile( + r.resourceUri, + (r as Resource).resourceGroupType === ResourceGroupType.Index + ) + : undefined + ); return this.execute(args); } @@ -83,15 +90,25 @@ export class ExternalDiffCommand extends Command { async execute(args: ExternalDiffCommandArgs = {}) { try { - const repoPath = await getRepoPathOrActiveOrPrompt(undefined, undefined, `Open changes from which repository${GlyphChars.Ellipsis}`); + const repoPath = await getRepoPathOrActiveOrPrompt( + undefined, + undefined, + `Open changes from which repository${GlyphChars.Ellipsis}` + ); if (!repoPath) return undefined; const tool = await Container.git.getDiffTool(repoPath); if (tool === undefined) { - const result = await window.showWarningMessage(`Unable to open changes in diff tool because there is no Git diff tool configured`, 'View Git Docs'); + const result = await window.showWarningMessage( + `Unable to open changes in diff tool because there is no Git diff tool configured`, + 'View Git Docs' + ); if (!result) return undefined; - return commands.executeCommand(BuiltInCommands.Open, Uri.parse('https://git-scm.com/docs/git-config#git-config-difftool')); + return commands.executeCommand( + BuiltInCommands.Open, + Uri.parse('https://git-scm.com/docs/git-config#git-config-difftool') + ); } if (args.files === undefined) { @@ -122,4 +139,4 @@ export class ExternalDiffCommand extends Command { return window.showErrorMessage(`Unable to open changes in diff tool. See output channel for more details`); } } -} \ No newline at end of file +} diff --git a/src/commands/openBranchInRemote.ts b/src/commands/openBranchInRemote.ts index 2fe86fd..c0bec83 100644 --- a/src/commands/openBranchInRemote.ts +++ b/src/commands/openBranchInRemote.ts @@ -1,6 +1,13 @@ 'use strict'; import { commands, TextEditor, Uri, window } from 'vscode'; -import { ActiveEditorCommand, CommandContext, Commands, getCommandUri, getRepoPathOrActiveOrPrompt, isCommandViewContextWithBranch } from './common'; +import { + ActiveEditorCommand, + CommandContext, + Commands, + getCommandUri, + getRepoPathOrActiveOrPrompt, + isCommandViewContextWithBranch +} from './common'; import { GlyphChars } from '../constants'; import { Container } from '../container'; import { GitUri } from '../gitService'; @@ -14,7 +21,6 @@ export interface OpenBranchInRemoteCommandArgs { } export class OpenBranchInRemoteCommand extends ActiveEditorCommand { - constructor() { super(Commands.OpenBranchInRemote); } @@ -32,9 +38,13 @@ export class OpenBranchInRemoteCommand extends ActiveEditorCommand { async execute(editor?: TextEditor, uri?: Uri, args: OpenBranchInRemoteCommandArgs = {}) { uri = getCommandUri(uri, editor); - const gitUri = uri && await GitUri.fromUri(uri); + const gitUri = uri && (await GitUri.fromUri(uri)); - const repoPath = await getRepoPathOrActiveOrPrompt(gitUri, editor, `Open branch in remote for which repository${GlyphChars.Ellipsis}`); + const repoPath = await getRepoPathOrActiveOrPrompt( + gitUri, + editor, + `Open branch in remote for which repository${GlyphChars.Ellipsis}` + ); if (!repoPath) return undefined; try { @@ -43,7 +53,10 @@ export class OpenBranchInRemoteCommand extends ActiveEditorCommand { const branches = (await Container.git.getBranches(repoPath)).filter(b => b.tracking !== undefined); if (branches.length > 1) { - const pick = await BranchesQuickPick.show(branches, `Open which branch in remote${GlyphChars.Ellipsis}`); + const pick = await BranchesQuickPick.show( + branches, + `Open which branch in remote${GlyphChars.Ellipsis}` + ); if (pick === undefined) return undefined; if (pick instanceof CommandQuickPickItem) return undefined; @@ -68,7 +81,9 @@ export class OpenBranchInRemoteCommand extends ActiveEditorCommand { } catch (ex) { Logger.error(ex, 'OpenBranchInRemoteCommandArgs'); - return window.showErrorMessage(`Unable to open branch in remote provider. See output channel for more details`); + return window.showErrorMessage( + `Unable to open branch in remote provider. See output channel for more details` + ); } } -} \ No newline at end of file +} diff --git a/src/commands/openBranchesInRemote.ts b/src/commands/openBranchesInRemote.ts index d073fbd..128636f 100644 --- a/src/commands/openBranchesInRemote.ts +++ b/src/commands/openBranchesInRemote.ts @@ -1,6 +1,13 @@ 'use strict'; import { commands, TextEditor, Uri, window } from 'vscode'; -import { ActiveEditorCommand, CommandContext, Commands, getCommandUri, getRepoPathOrActiveOrPrompt, isCommandViewContextWithRemote } from './common'; +import { + ActiveEditorCommand, + CommandContext, + Commands, + getCommandUri, + getRepoPathOrActiveOrPrompt, + isCommandViewContextWithRemote +} from './common'; import { GlyphChars } from '../constants'; import { Container } from '../container'; import { GitUri } from '../gitService'; @@ -12,7 +19,6 @@ export interface OpenBranchesInRemoteCommandArgs { } export class OpenBranchesInRemoteCommand extends ActiveEditorCommand { - constructor() { super(Commands.OpenBranchesInRemote); } @@ -29,9 +35,13 @@ export class OpenBranchesInRemoteCommand extends ActiveEditorCommand { async execute(editor?: TextEditor, uri?: Uri, args: OpenBranchesInRemoteCommandArgs = {}) { uri = getCommandUri(uri, editor); - const gitUri = uri && await GitUri.fromUri(uri); + const gitUri = uri && (await GitUri.fromUri(uri)); - const repoPath = await getRepoPathOrActiveOrPrompt(gitUri, editor, `Open branches in remote for which repository${GlyphChars.Ellipsis}`); + const repoPath = await getRepoPathOrActiveOrPrompt( + gitUri, + editor, + `Open branches in remote for which repository${GlyphChars.Ellipsis}` + ); if (!repoPath) return undefined; try { @@ -47,7 +57,9 @@ export class OpenBranchesInRemoteCommand extends ActiveEditorCommand { } catch (ex) { Logger.error(ex, 'OpenBranchesInRemoteCommand'); - return window.showErrorMessage(`Unable to open branches in remote provider. See output channel for more details`); + return window.showErrorMessage( + `Unable to open branches in remote provider. See output channel for more details` + ); } } -} \ No newline at end of file +} diff --git a/src/commands/openChangedFiles.ts b/src/commands/openChangedFiles.ts index 3d7d75a..030e38b 100644 --- a/src/commands/openChangedFiles.ts +++ b/src/commands/openChangedFiles.ts @@ -11,7 +11,6 @@ export interface OpenChangedFilesCommandArgs { } export class OpenChangedFilesCommand extends ActiveEditorCommand { - constructor() { super(Commands.OpenChangedFiles); } @@ -23,14 +22,17 @@ export class OpenChangedFilesCommand extends ActiveEditorCommand { if (args.uris === undefined) { args = { ...args }; - const repoPath = await getRepoPathOrActiveOrPrompt(uri, editor, `Open changed files in which repository${GlyphChars.Ellipsis}`); + const repoPath = await getRepoPathOrActiveOrPrompt( + uri, + editor, + `Open changed files in which repository${GlyphChars.Ellipsis}` + ); if (!repoPath) return undefined; const status = await Container.git.getStatusForRepo(repoPath); if (status === undefined) return window.showWarningMessage(`Unable to open changed files`); - args.uris = Arrays.filterMap(status.files, - f => f.status !== 'D' ? f.uri : undefined); + args.uris = Arrays.filterMap(status.files, f => (f.status !== 'D' ? f.uri : undefined)); } for (const uri of args.uris) { @@ -44,4 +46,4 @@ export class OpenChangedFilesCommand extends ActiveEditorCommand { return window.showErrorMessage(`Unable to open changed files. See output channel for more details`); } } -} \ No newline at end of file +} diff --git a/src/commands/openCommitInRemote.ts b/src/commands/openCommitInRemote.ts index 211bf8c..0eab9dc 100644 --- a/src/commands/openCommitInRemote.ts +++ b/src/commands/openCommitInRemote.ts @@ -12,13 +12,10 @@ export interface OpenCommitInRemoteCommandArgs { } export class OpenCommitInRemoteCommand extends ActiveEditorCommand { - static getMarkdownCommandArgs(sha: string): string; static getMarkdownCommandArgs(args: OpenCommitInRemoteCommandArgs): string; static getMarkdownCommandArgs(argsOrSha: OpenCommitInRemoteCommandArgs | string): string { - const args = typeof argsOrSha === 'string' - ? { sha: argsOrSha } - : argsOrSha; + const args = typeof argsOrSha === 'string' ? { sha: argsOrSha } : argsOrSha; return super.getMarkdownCommandArgsCore<OpenCommitInRemoteCommandArgs>(Commands.OpenCommitInRemote, args); } @@ -47,10 +44,15 @@ export class OpenCommitInRemoteCommand extends ActiveEditorCommand { const blameline = editor == null ? 0 : editor.selection.active.line; if (blameline < 0) return undefined; - const blame = editor && editor.document && editor.document.isDirty - ? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText()) - : await Container.git.getBlameForLine(gitUri, blameline); - if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open commit in remote provider'); + const blame = + editor && editor.document && editor.document.isDirty + ? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText()) + : await Container.git.getBlameForLine(gitUri, blameline); + 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 @@ -78,7 +80,9 @@ export class OpenCommitInRemoteCommand extends ActiveEditorCommand { } catch (ex) { Logger.error(ex, 'OpenCommitInRemoteCommand'); - return window.showErrorMessage(`Unable to open commit in remote provider. See output channel for more details`); + return window.showErrorMessage( + `Unable to open commit in remote provider. See output channel for more details` + ); } } -} \ No newline at end of file +} diff --git a/src/commands/openFileInRemote.ts b/src/commands/openFileInRemote.ts index f66561f..1bf9994 100644 --- a/src/commands/openFileInRemote.ts +++ b/src/commands/openFileInRemote.ts @@ -1,6 +1,13 @@ 'use strict'; import { commands, Range, TextEditor, Uri, window } from 'vscode'; -import { ActiveEditorCommand, CommandContext, Commands, getCommandUri, isCommandViewContextWithBranch, isCommandViewContextWithCommit } from './common'; +import { + ActiveEditorCommand, + CommandContext, + Commands, + getCommandUri, + isCommandViewContextWithBranch, + isCommandViewContextWithCommit +} from './common'; import { GlyphChars } from '../constants'; import { Container } from '../container'; import { GitUri } from '../gitService'; @@ -14,12 +21,14 @@ export interface OpenFileInRemoteCommandArgs { } export class OpenFileInRemoteCommand extends ActiveEditorCommand { - constructor() { super(Commands.OpenFileInRemote); } - protected async preExecute(context: CommandContext, args: OpenFileInRemoteCommandArgs = { range: true }): Promise<any> { + protected async preExecute( + context: CommandContext, + args: OpenFileInRemoteCommandArgs = { range: true } + ): Promise<any> { if (isCommandViewContextWithCommit(context)) { args = { ...args }; args.range = false; @@ -42,9 +51,14 @@ export class OpenFileInRemoteCommand extends ActiveEditorCommand { if (args.branch === undefined) { const branch = await Container.git.getBranch(gitUri.repoPath); if (branch === undefined || branch.tracking === undefined) { - const branches = (await Container.git.getBranches(gitUri.repoPath)).filter(b => b.tracking !== undefined); + const branches = (await Container.git.getBranches(gitUri.repoPath)).filter( + b => b.tracking !== undefined + ); if (branches.length > 1) { - const pick = await BranchesQuickPick.show(branches, `Open ${gitUri.getRelativePath()} in remote for which branch${GlyphChars.Ellipsis}`); + const pick = await BranchesQuickPick.show( + branches, + `Open ${gitUri.getRelativePath()} in remote for which branch${GlyphChars.Ellipsis}` + ); if (pick === undefined) return undefined; if (pick instanceof CommandQuickPickItem) return undefined; @@ -62,9 +76,13 @@ export class OpenFileInRemoteCommand extends ActiveEditorCommand { try { const remotes = await Container.git.getRemotes(gitUri.repoPath); - const range = (args.range && editor != null) - ? new Range(editor.selection.start.with({ line: editor.selection.start.line + 1 }), editor.selection.end.with({ line: editor.selection.end.line + 1 })) - : undefined; + const range = + args.range && editor != null + ? new Range( + editor.selection.start.with({ line: editor.selection.start.line + 1 }), + editor.selection.end.with({ line: editor.selection.end.line + 1 }) + ) + : undefined; return commands.executeCommand(Commands.OpenInRemote, uri, { resource: { @@ -79,7 +97,9 @@ export class OpenFileInRemoteCommand extends ActiveEditorCommand { } catch (ex) { Logger.error(ex, 'OpenFileInRemoteCommand'); - return window.showErrorMessage(`Unable to open file in remote provider. See output channel for more details`); + return window.showErrorMessage( + `Unable to open file in remote provider. See output channel for more details` + ); } } -} \ No newline at end of file +} diff --git a/src/commands/openFileRevision.ts b/src/commands/openFileRevision.ts index faa9fca..d72bd5b 100644 --- a/src/commands/openFileRevision.ts +++ b/src/commands/openFileRevision.ts @@ -21,10 +21,13 @@ export interface OpenFileRevisionCommandArgs { } export class OpenFileRevisionCommand extends ActiveEditorCommand { - static getMarkdownCommandArgs(args: OpenFileRevisionCommandArgs): string; static getMarkdownCommandArgs(uri: Uri, annotationType?: FileAnnotationType, line?: number): string; - static getMarkdownCommandArgs(argsOrUri: OpenFileRevisionCommandArgs | Uri, annotationType?: FileAnnotationType, line?: number): string { + static getMarkdownCommandArgs( + argsOrUri: OpenFileRevisionCommandArgs | Uri, + annotationType?: FileAnnotationType, + line?: number + ): string { let args: OpenFileRevisionCommandArgs | Uri; if (argsOrUri instanceof Uri) { const uri = argsOrUri; @@ -61,46 +64,74 @@ export class OpenFileRevisionCommand extends ActiveEditorCommand { const gitUri = await GitUri.fromUri(uri); - const placeHolder = `Open ${gitUri.getFormattedPath()}${gitUri.sha ? ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${gitUri.shortSha}` : ''} in revision ${GlyphChars.Ellipsis}`; + const placeHolder = `Open ${gitUri.getFormattedPath()}${ + gitUri.sha ? ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${gitUri.shortSha}` : '' + } in revision ${GlyphChars.Ellipsis}`; progressCancellation = FileHistoryQuickPick.showProgress(placeHolder); - const log = await Container.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { maxCount: args.maxCount, ref: gitUri.sha }); - if (log === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open history compare'); + const log = await Container.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { + maxCount: args.maxCount, + ref: gitUri.sha + }); + if (log === undefined) { + return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open history compare'); + } if (progressCancellation.token.isCancellationRequested) return undefined; let previousPageCommand: CommandQuickPickItem | undefined = undefined; if (log.truncated) { - const npc = new CommandQuickPickItem({ - label: `$(arrow-right) Show Next Commits`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} newer commits` - }, Commands.OpenFileRevision, [uri, { ...args } as OpenFileRevisionCommandArgs]); + const npc = new CommandQuickPickItem( + { + label: `$(arrow-right) Show Next Commits`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} newer commits` + }, + Commands.OpenFileRevision, + [uri, { ...args } as OpenFileRevisionCommandArgs] + ); const last = Iterables.last(log.commits.values()); if (last != null) { - previousPageCommand = new CommandQuickPickItem({ - label: `$(arrow-left) Show Previous Commits`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} older commits` - }, Commands.OpenFileRevision, [new GitUri(uri, last), { ...args, nextPageCommand: npc } as OpenFileRevisionCommandArgs]); + previousPageCommand = new CommandQuickPickItem( + { + label: `$(arrow-left) Show Previous Commits`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} older commits` + }, + Commands.OpenFileRevision, + [new GitUri(uri, last), { ...args, nextPageCommand: npc } as OpenFileRevisionCommandArgs] + ); } } const pick = await FileHistoryQuickPick.show(log, gitUri, placeHolder, { pickerOnly: true, progressCancellation: progressCancellation, - currentCommand: new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to history of ${GlyphChars.Space}$(file-text) ${gitUri.getFormattedPath()}${gitUri.sha ? ` from ${GlyphChars.Space}$(git-commit) ${gitUri.shortSha}` : ''}` - }, Commands.OpenFileRevision, [uri, { ...args }]), + currentCommand: new CommandQuickPickItem( + { + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to history of ${ + GlyphChars.Space + }$(file-text) ${gitUri.getFormattedPath()}${ + gitUri.sha ? ` from ${GlyphChars.Space}$(git-commit) ${gitUri.shortSha}` : '' + }` + }, + Commands.OpenFileRevision, + [uri, { ...args }] + ), nextPageCommand: args.nextPageCommand, previousPageCommand: previousPageCommand, - showAllCommand: log !== undefined && log.truncated - ? new CommandQuickPickItem({ - label: `$(sync) Show All Commits`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} this may take a while` - }, Commands.OpenFileRevision, [uri, { ...args, maxCount: 0 } as OpenFileRevisionCommandArgs]) - : undefined + showAllCommand: + log !== undefined && log.truncated + ? new CommandQuickPickItem( + { + label: `$(sync) Show All Commits`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} this may take a while` + }, + Commands.OpenFileRevision, + [uri, { ...args, maxCount: 0 } as OpenFileRevisionCommandArgs] + ) + : undefined }); if (pick === undefined) return undefined; @@ -117,7 +148,6 @@ export class OpenFileRevisionCommand extends ActiveEditorCommand { args.uri = GitUri.toRevisionUri(pick.commit.sha, pick.commit.uri.fsPath, pick.commit.repoPath); } - } if (args.line !== undefined && args.line !== 0) { @@ -140,4 +170,4 @@ export class OpenFileRevisionCommand extends ActiveEditorCommand { progressCancellation && progressCancellation.cancel(); } } -} \ No newline at end of file +} diff --git a/src/commands/openInRemote.ts b/src/commands/openInRemote.ts index 71b935c..7afba48 100644 --- a/src/commands/openInRemote.ts +++ b/src/commands/openInRemote.ts @@ -16,7 +16,6 @@ export interface OpenInRemoteCommandArgs { } export class OpenInRemoteCommand extends ActiveEditorCommand { - constructor() { super(Commands.OpenInRemote); } @@ -60,15 +59,20 @@ export class OpenInRemoteCommand extends ActiveEditorCommand { if (args.resource.commit !== undefined && args.resource.commit instanceof GitLogCommit) { if (args.resource.commit.status === 'D') { args.resource.sha = args.resource.commit.previousSha; - placeHolder = `open ${args.resource.fileName} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${args.resource.commit.previousShortSha} in${GlyphChars.Ellipsis}`; + placeHolder = `open ${args.resource.fileName} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${ + args.resource.commit.previousShortSha + } in${GlyphChars.Ellipsis}`; } else { args.resource.sha = args.resource.commit.sha; - placeHolder = `open ${args.resource.fileName} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${args.resource.commit.shortSha} in${GlyphChars.Ellipsis}`; + placeHolder = `open ${args.resource.fileName} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${ + args.resource.commit.shortSha + } in${GlyphChars.Ellipsis}`; } } else { - const shortFileSha = args.resource.sha === undefined ? '' : GitService.shortenSha(args.resource.sha); + const shortFileSha = + args.resource.sha === undefined ? '' : GitService.shortenSha(args.resource.sha); const shaSuffix = shortFileSha ? ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${shortFileSha}` : ''; placeHolder = `open ${args.resource.fileName}${shaSuffix} in${GlyphChars.Ellipsis}`; @@ -85,7 +89,6 @@ export class OpenInRemoteCommand extends ActiveEditorCommand { if (pick === undefined) return undefined; return await pick.execute(); - } catch (ex) { Logger.error(ex, 'OpenInRemoteCommand'); @@ -107,4 +110,4 @@ export class OpenInRemoteCommand extends ActiveEditorCommand { } } } -} \ No newline at end of file +} diff --git a/src/commands/openRepoInRemote.ts b/src/commands/openRepoInRemote.ts index fd88b8c..5da5227 100644 --- a/src/commands/openRepoInRemote.ts +++ b/src/commands/openRepoInRemote.ts @@ -1,6 +1,13 @@ 'use strict'; import { commands, TextEditor, Uri, window } from 'vscode'; -import { ActiveEditorCommand, CommandContext, Commands, getCommandUri, getRepoPathOrActiveOrPrompt, isCommandViewContextWithRemote } from './common'; +import { + ActiveEditorCommand, + CommandContext, + Commands, + getCommandUri, + getRepoPathOrActiveOrPrompt, + isCommandViewContextWithRemote +} from './common'; import { GlyphChars } from '../constants'; import { Container } from '../container'; import { GitUri } from '../gitService'; @@ -12,7 +19,6 @@ export interface OpenRepoInRemoteCommandArgs { } export class OpenRepoInRemoteCommand extends ActiveEditorCommand { - constructor() { super(Commands.OpenRepoInRemote); } @@ -29,9 +35,13 @@ export class OpenRepoInRemoteCommand extends ActiveEditorCommand { async execute(editor?: TextEditor, uri?: Uri, args: OpenRepoInRemoteCommandArgs = {}) { uri = getCommandUri(uri, editor); - const gitUri = uri && await GitUri.fromUri(uri); + const gitUri = uri && (await GitUri.fromUri(uri)); - const repoPath = await getRepoPathOrActiveOrPrompt(gitUri, editor, `Open which repository in remote${GlyphChars.Ellipsis}`); + const repoPath = await getRepoPathOrActiveOrPrompt( + gitUri, + editor, + `Open which repository in remote${GlyphChars.Ellipsis}` + ); if (!repoPath) return undefined; try { @@ -47,7 +57,9 @@ export class OpenRepoInRemoteCommand extends ActiveEditorCommand { } catch (ex) { Logger.error(ex, 'OpenRepoInRemoteCommand'); - return window.showErrorMessage(`Unable to open repository in remote provider. See output channel for more details`); + return window.showErrorMessage( + `Unable to open repository in remote provider. See output channel for more details` + ); } } -} \ No newline at end of file +} diff --git a/src/commands/openWorkingFile.ts b/src/commands/openWorkingFile.ts index 8d96b14..971d743 100644 --- a/src/commands/openWorkingFile.ts +++ b/src/commands/openWorkingFile.ts @@ -15,7 +15,6 @@ export interface OpenWorkingFileCommandArgs { } export class OpenWorkingFileCommand extends ActiveEditorCommand { - constructor() { super(Commands.OpenWorkingFile); } @@ -33,7 +32,10 @@ export class OpenWorkingFileCommand extends ActiveEditorCommand { args.uri = await GitUri.fromUri(uri); if (args.uri instanceof GitUri && args.uri.sha) { - const [fileName, repoPath] = await Container.git.findWorkingFileName(args.uri.fsPath, args.uri.repoPath); + const [fileName, repoPath] = await Container.git.findWorkingFileName( + args.uri.fsPath, + args.uri.repoPath + ); if (fileName !== undefined && repoPath !== undefined) { args.uri = new GitUri(Uri.file(path.resolve(repoPath, fileName)), repoPath); } @@ -57,4 +59,4 @@ export class OpenWorkingFileCommand extends ActiveEditorCommand { return window.showErrorMessage(`Unable to open working file. See output channel for more details`); } } -} \ No newline at end of file +} diff --git a/src/commands/resetSuppressedWarnings.ts b/src/commands/resetSuppressedWarnings.ts index 30f8ddf..ba5297c 100644 --- a/src/commands/resetSuppressedWarnings.ts +++ b/src/commands/resetSuppressedWarnings.ts @@ -4,12 +4,15 @@ import { Command, Commands } from './common'; import { configuration } from '../configuration'; export class ResetSuppressedWarningsCommand extends Command { - constructor() { super(Commands.ResetSuppressedWarnings); } async execute() { - await configuration.update(configuration.name('advanced')('messages').value, undefined, ConfigurationTarget.Global); + await configuration.update( + configuration.name('advanced')('messages').value, + undefined, + ConfigurationTarget.Global + ); } -} \ No newline at end of file +} diff --git a/src/commands/showCommitSearch.ts b/src/commands/showCommitSearch.ts index c7e60dc..8bb3010 100644 --- a/src/commands/showCommitSearch.ts +++ b/src/commands/showCommitSearch.ts @@ -6,7 +6,11 @@ import { GlyphChars } from '../constants'; import { Container } from '../container'; import { GitRepoSearchBy, GitService, GitUri } from '../gitService'; import { Logger } from '../logger'; -import { CommandQuickPickItem, CommitsQuickPick, ShowCommitsSearchInResultsQuickPickItem } from '../quickPicks/quickPicks'; +import { + CommandQuickPickItem, + CommitsQuickPick, + ShowCommitsSearchInResultsQuickPickItem +} from '../quickPicks/quickPicks'; import { ShowQuickCommitDetailsCommandArgs } from './showQuickCommitDetails'; const searchByRegex = /^([@~=:#])/; @@ -27,7 +31,6 @@ export interface ShowCommitSearchCommandArgs { } export class ShowCommitSearchCommand extends ActiveEditorCachedCommand { - constructor() { super(Commands.ShowCommitSearch); } @@ -35,9 +38,14 @@ export class ShowCommitSearchCommand extends ActiveEditorCachedCommand { async execute(editor?: TextEditor, uri?: Uri, args: ShowCommitSearchCommandArgs = {}) { uri = getCommandUri(uri, editor); - const gitUri = uri && await GitUri.fromUri(uri); + const gitUri = uri && (await GitUri.fromUri(uri)); - const repoPath = await getRepoPathOrActiveOrPrompt(gitUri, editor, `Search for commits in which repository${GlyphChars.Ellipsis}`, args.goBackCommand); + const repoPath = await getRepoPathOrActiveOrPrompt( + gitUri, + editor, + `Search for commits in which repository${GlyphChars.Ellipsis}`, + args.goBackCommand + ); if (!repoPath) return undefined; args = { ...args }; @@ -63,14 +71,16 @@ export class ShowCommitSearchCommand extends ActiveEditorCachedCommand { prompt: `Please enter a search string`, placeHolder: `search by message, author (@<pattern>), files (:<pattern>), commit id (#<sha>), changes (~<pattern>), or changed occurrences (=<string>)` } as InputBoxOptions); - if (args.search === undefined) return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute(); + if (args.search === undefined) { + return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute(); + } originalArgs.search = args.search; const match = searchByRegex.exec(args.search); if (match && match[1]) { args.searchBy = searchByMap.get(match[1]); - args.search = args.search.substring((args.search[1] === ' ') ? 2 : 1); + args.search = args.search.substring(args.search[1] === ' ' ? 2 : 1); } else if (GitService.isSha(args.search)) { args.searchBy = GitRepoSearchBy.Sha; @@ -113,41 +123,55 @@ export class ShowCommitSearchCommand extends ActiveEditorCachedCommand { const progressCancellation = CommitsQuickPick.showProgress(searchLabel!); try { - const log = await Container.git.getLogForSearch(repoPath, args.search, args.searchBy, { maxCount: args.maxCount }); + const log = await Container.git.getLogForSearch(repoPath, args.search, args.searchBy, { + maxCount: args.maxCount + }); if (progressCancellation.token.isCancellationRequested) return undefined; - const goBackCommand = args.goBackCommand || new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to commit search` - }, Commands.ShowCommitSearch, [uri, originalArgs]); + const goBackCommand = + args.goBackCommand || + new CommandQuickPickItem( + { + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to commit search` + }, + Commands.ShowCommitSearch, + [uri, originalArgs] + ); const pick = await CommitsQuickPick.show(log, searchLabel!, progressCancellation, { goBackCommand: goBackCommand, - showAllCommand: log !== undefined && log.truncated - ? new CommandQuickPickItem({ - label: `$(sync) Show All Commits`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} this may take a while` - }, Commands.ShowCommitSearch, [uri, { ...args, maxCount: 0, goBackCommand: goBackCommand }]) - : undefined, - showInResultsExplorerCommand: log !== undefined - ? new ShowCommitsSearchInResultsQuickPickItem(log, searchLabel!) - : undefined + showAllCommand: + log !== undefined && log.truncated + ? new CommandQuickPickItem( + { + label: `$(sync) Show All Commits`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} this may take a while` + }, + Commands.ShowCommitSearch, + [uri, { ...args, maxCount: 0, goBackCommand: goBackCommand }] + ) + : undefined, + showInResultsExplorerCommand: + log !== undefined ? new ShowCommitsSearchInResultsQuickPickItem(log, searchLabel!) : undefined }); if (pick === undefined) return undefined; if (pick instanceof CommandQuickPickItem) return pick.execute(); - return commands.executeCommand(Commands.ShowQuickCommitDetails, - pick.commit.toGitUri(), - { - sha: pick.commit.sha, - commit: pick.commit, - goBackCommand: new CommandQuickPickItem({ + return commands.executeCommand(Commands.ShowQuickCommitDetails, pick.commit.toGitUri(), { + sha: pick.commit.sha, + commit: pick.commit, + goBackCommand: new CommandQuickPickItem( + { label: `go back ${GlyphChars.ArrowBack}`, description: `${Strings.pad(GlyphChars.Dash, 2, 2)} to search for ${searchLabel}` - }, Commands.ShowCommitSearch, [ uri, args ]) - } as ShowQuickCommitDetailsCommandArgs); + }, + Commands.ShowCommitSearch, + [uri, args] + ) + } as ShowQuickCommitDetailsCommandArgs); } catch (ex) { Logger.error(ex, 'ShowCommitSearchCommand'); @@ -157,4 +181,4 @@ export class ShowCommitSearchCommand extends ActiveEditorCachedCommand { progressCancellation.cancel(); } } -} \ No newline at end of file +} diff --git a/src/commands/showGitExplorer.ts b/src/commands/showGitExplorer.ts index 3834190..357ec2c 100644 --- a/src/commands/showGitExplorer.ts +++ b/src/commands/showGitExplorer.ts @@ -4,7 +4,6 @@ import { GitExplorerView } from '../configuration'; import { Container } from '../container'; export class ShowGitExplorerCommand extends Command { - constructor() { super(Commands.ShowGitExplorer); } @@ -12,4 +11,4 @@ export class ShowGitExplorerCommand extends Command { execute() { return Container.gitExplorer.show(GitExplorerView.Repository); } -} \ No newline at end of file +} diff --git a/src/commands/showHistoryExplorer.ts b/src/commands/showHistoryExplorer.ts index 3aa5684..af3c279 100644 --- a/src/commands/showHistoryExplorer.ts +++ b/src/commands/showHistoryExplorer.ts @@ -4,7 +4,6 @@ import { GitExplorerView } from '../configuration'; import { Container } from '../container'; export class ShowHistoryExplorerCommand extends Command { - constructor() { super(Commands.ShowHistoryExplorer); } @@ -16,4 +15,4 @@ export class ShowHistoryExplorerCommand extends Command { return Container.gitExplorer.show(GitExplorerView.History); } -} \ No newline at end of file +} diff --git a/src/commands/showLastQuickPick.ts b/src/commands/showLastQuickPick.ts index 977c205..1813b74 100644 --- a/src/commands/showLastQuickPick.ts +++ b/src/commands/showLastQuickPick.ts @@ -4,7 +4,6 @@ import { Command, Commands, getLastCommand } from './common'; import { Logger } from '../logger'; export class ShowLastQuickPickCommand extends Command { - constructor() { super(Commands.ShowLastQuickPick); } @@ -21,4 +20,4 @@ export class ShowLastQuickPickCommand extends Command { return window.showErrorMessage(`Unable to show last quick pick. See output channel for more details`); } } -} \ No newline at end of file +} diff --git a/src/commands/showQuickBranchHistory.ts b/src/commands/showQuickBranchHistory.ts index 6f94e22..30bfa29 100644 --- a/src/commands/showQuickBranchHistory.ts +++ b/src/commands/showQuickBranchHistory.ts @@ -20,7 +20,6 @@ export interface ShowQuickBranchHistoryCommandArgs { } export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand { - constructor() { super(Commands.ShowQuickBranchHistory); } @@ -28,13 +27,20 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand { async execute(editor?: TextEditor, uri?: Uri, args: ShowQuickBranchHistoryCommandArgs = {}) { uri = getCommandUri(uri, editor); - const gitUri = uri && await GitUri.fromUri(uri); + const gitUri = uri && (await GitUri.fromUri(uri)); args = { ...args }; - let progressCancellation = args.branch === undefined ? undefined : BranchHistoryQuickPick.showProgress(args.branch); + let progressCancellation = + args.branch === undefined ? undefined : BranchHistoryQuickPick.showProgress(args.branch); try { - const repoPath = args.repoPath || await getRepoPathOrActiveOrPrompt(gitUri, editor, `Show branch history in which repository${GlyphChars.Ellipsis}`); + const repoPath = + args.repoPath || + (await getRepoPathOrActiveOrPrompt( + gitUri, + editor, + `Show branch history in which repository${GlyphChars.Ellipsis}` + )); if (!repoPath) return undefined; if (args.branch === undefined) { @@ -42,13 +48,19 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand { let goBackCommand; if (!(await Container.git.getRepoPathOrActive(uri, editor))) { - goBackCommand = new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to which repository` - }, Commands.ShowQuickBranchHistory, [uri, args]); + goBackCommand = new CommandQuickPickItem( + { + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to which repository` + }, + Commands.ShowQuickBranchHistory, + [uri, args] + ); } - const pick = await BranchesQuickPick.show(branches, `Show history for branch${GlyphChars.Ellipsis}`, { goBackCommand: goBackCommand }); + const pick = await BranchesQuickPick.show(branches, `Show history for branch${GlyphChars.Ellipsis}`, { + goBackCommand: goBackCommand + }); if (pick === undefined) return undefined; if (pick instanceof CommandQuickPickItem) return pick.execute(); @@ -60,31 +72,47 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand { } if (args.log === undefined) { - args.log = await Container.git.getLog(repoPath, { maxCount: args.maxCount, ref: (gitUri && gitUri.sha) || args.branch }); + args.log = await Container.git.getLog(repoPath, { + maxCount: args.maxCount, + ref: (gitUri && gitUri.sha) || args.branch + }); if (args.log === undefined) return window.showWarningMessage(`Unable to show branch history`); } - if (progressCancellation !== undefined && progressCancellation.token.isCancellationRequested) return undefined; + if (progressCancellation !== undefined && progressCancellation.token.isCancellationRequested) { + return undefined; + } - const pick = await BranchHistoryQuickPick.show(args.log, gitUri, args.branch, progressCancellation!, args.goBackCommand, args.nextPageCommand); + const pick = await BranchHistoryQuickPick.show( + args.log, + gitUri, + args.branch, + progressCancellation!, + args.goBackCommand, + args.nextPageCommand + ); if (pick === undefined) return undefined; if (pick instanceof CommandQuickPickItem) return pick.execute(); // Create a command to get back to here - const currentCommand = new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to ${GlyphChars.Space}$(git-branch) ${args.branch} history` - }, Commands.ShowQuickBranchHistory, [uri, { ...args }]); - - return commands.executeCommand(Commands.ShowQuickCommitDetails, - pick.commit.toGitUri(), + const currentCommand = new CommandQuickPickItem( { - sha: pick.commit.sha, - commit: pick.commit, - repoLog: args.log, - goBackCommand: currentCommand - } as ShowQuickCommitDetailsCommandArgs); + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to ${GlyphChars.Space}$(git-branch) ${ + args.branch + } history` + }, + Commands.ShowQuickBranchHistory, + [uri, { ...args }] + ); + + return commands.executeCommand(Commands.ShowQuickCommitDetails, pick.commit.toGitUri(), { + sha: pick.commit.sha, + commit: pick.commit, + repoLog: args.log, + goBackCommand: currentCommand + } as ShowQuickCommitDetailsCommandArgs); } catch (ex) { Logger.error(ex, 'ShowQuickBranchHistoryCommand'); @@ -94,4 +122,4 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand { progressCancellation && progressCancellation.cancel(); } } -} \ No newline at end of file +} diff --git a/src/commands/showQuickCommitDetails.ts b/src/commands/showQuickCommitDetails.ts index 9901bb0..30f9db4 100644 --- a/src/commands/showQuickCommitDetails.ts +++ b/src/commands/showQuickCommitDetails.ts @@ -1,7 +1,13 @@ 'use strict'; import { Strings } from '../system'; import { commands, TextEditor, Uri, window } from 'vscode'; -import { ActiveEditorCachedCommand, CommandContext, Commands, getCommandUri, isCommandViewContextWithCommit } from './common'; +import { + ActiveEditorCachedCommand, + CommandContext, + Commands, + getCommandUri, + isCommandViewContextWithCommit +} from './common'; import { GlyphChars } from '../constants'; import { GitCommit, GitLog, GitLogCommit, GitUri } from '../gitService'; import { Logger } from '../logger'; @@ -20,14 +26,14 @@ export interface ShowQuickCommitDetailsCommandArgs { } export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand { - static getMarkdownCommandArgs(sha: string): string; static getMarkdownCommandArgs(args: ShowQuickCommitDetailsCommandArgs): string; static getMarkdownCommandArgs(argsOrSha: ShowQuickCommitDetailsCommandArgs | string): string { - const args = typeof argsOrSha === 'string' - ? { sha: argsOrSha } - : argsOrSha; - return super.getMarkdownCommandArgsCore<ShowQuickCommitDetailsCommandArgs>(Commands.ShowQuickCommitDetails, args); + const args = typeof argsOrSha === 'string' ? { sha: argsOrSha } : argsOrSha; + return super.getMarkdownCommandArgsCore<ShowQuickCommitDetailsCommandArgs>( + Commands.ShowQuickCommitDetails, + args + ); } constructor() { @@ -64,10 +70,14 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand { try { const blame = await Container.git.getBlameForLine(gitUri, blameline); - if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show commit details'); + if (blame === undefined) { + return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show commit details'); + } // 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'); + if (blame.commit.isUncommitted) { + return Messages.showLineUncommittedWarningMessage('Unable to show commit details'); + } args.sha = blame.commit.sha; repoPath = blame.commit.repoPath; @@ -93,13 +103,17 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand { if (args.repoLog === undefined) { const log = await Container.git.getLog(repoPath!, { maxCount: 2, ref: args.sha }); - if (log === undefined) return Messages.showCommitNotFoundWarningMessage(`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 Messages.showCommitNotFoundWarningMessage(`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; @@ -109,40 +123,49 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand { const branch = await Container.git.getBranch(args.commit.repoPath); if (branch !== undefined) { // Create a command to get back to the branch history - args.goBackCommand = new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to ${branch.name} history` - }, Commands.ShowQuickCurrentBranchHistory, [ - args.commit.toGitUri() - ]); + args.goBackCommand = new CommandQuickPickItem( + { + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to ${branch.name} history` + }, + Commands.ShowQuickCurrentBranchHistory, + [args.commit.toGitUri()] + ); } } // Create a command to get back to where we are right now - const currentCommand = new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to details of ${GlyphChars.Space}$(git-commit) ${args.commit.shortSha}` - }, Commands.ShowQuickCommitDetails, [ - args.commit.toGitUri(), - args - ]); - - const pick = await CommitQuickPick.show(args.commit as GitLogCommit, uri, args.goBackCommand, currentCommand, args.repoLog); + const currentCommand = new CommandQuickPickItem( + { + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to details of ${ + GlyphChars.Space + }$(git-commit) ${args.commit.shortSha}` + }, + Commands.ShowQuickCommitDetails, + [args.commit.toGitUri(), args] + ); + + const pick = await CommitQuickPick.show( + args.commit as GitLogCommit, + uri, + args.goBackCommand, + currentCommand, + args.repoLog + ); if (pick === undefined) return undefined; if (!(pick instanceof CommitWithFileStatusQuickPickItem)) return pick.execute(); - return commands.executeCommand(Commands.ShowQuickCommitFileDetails, - pick.commit.toGitUri(), - { - commit: pick.commit, - sha: pick.sha, - goBackCommand: currentCommand - } as ShowQuickCommitFileDetailsCommandArgs); + return commands.executeCommand(Commands.ShowQuickCommitFileDetails, pick.commit.toGitUri(), { + commit: pick.commit, + sha: pick.sha, + goBackCommand: currentCommand + } as ShowQuickCommitFileDetailsCommandArgs); } catch (ex) { Logger.error(ex, 'ShowQuickCommitDetailsCommand'); return window.showErrorMessage(`Unable to show commit details. See output channel for more details`); } } -} \ No newline at end of file +} diff --git a/src/commands/showQuickCommitFileDetails.ts b/src/commands/showQuickCommitFileDetails.ts index 2dc15d0..ce0745a 100644 --- a/src/commands/showQuickCommitFileDetails.ts +++ b/src/commands/showQuickCommitFileDetails.ts @@ -1,7 +1,13 @@ 'use strict'; import { Strings } from '../system'; import { TextEditor, Uri, window } from 'vscode'; -import { ActiveEditorCachedCommand, CommandContext, Commands, getCommandUri, isCommandViewContextWithCommit } from './common'; +import { + ActiveEditorCachedCommand, + CommandContext, + Commands, + getCommandUri, + isCommandViewContextWithCommit +} from './common'; import { GlyphChars } from '../constants'; import { GitCommit, GitLog, GitLogCommit, GitService, GitUri } from '../gitService'; import { Logger } from '../logger'; @@ -20,21 +26,24 @@ export interface ShowQuickCommitFileDetailsCommandArgs { } export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCachedCommand { - static getMarkdownCommandArgs(sha: string): string; static getMarkdownCommandArgs(args: ShowQuickCommitFileDetailsCommandArgs): string; static getMarkdownCommandArgs(argsOrSha: ShowQuickCommitFileDetailsCommandArgs | string): string { - const args = typeof argsOrSha === 'string' - ? { sha: argsOrSha } - : argsOrSha; - return super.getMarkdownCommandArgsCore<ShowQuickCommitFileDetailsCommandArgs>(Commands.ShowQuickCommitFileDetails, args); + const args = typeof argsOrSha === 'string' ? { sha: argsOrSha } : argsOrSha; + return super.getMarkdownCommandArgsCore<ShowQuickCommitFileDetailsCommandArgs>( + Commands.ShowQuickCommitFileDetails, + args + ); } constructor() { super(Commands.ShowQuickCommitFileDetails); } - protected async preExecute(context: CommandContext, args: ShowQuickCommitFileDetailsCommandArgs = {}): Promise<any> { + protected async preExecute( + context: CommandContext, + args: ShowQuickCommitFileDetailsCommandArgs = {} + ): Promise<any> { if (context.type === 'view') { args = { ...args }; args.sha = context.node.uri.sha; @@ -63,10 +72,14 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCachedCommand try { const blame = await Container.git.getBlameForLine(gitUri, blameline); - if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show commit file details'); + if (blame === undefined) { + return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show commit file details'); + } // 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'); + if (blame.commit.isUncommitted) { + return Messages.showLineUncommittedWarningMessage('Unable to show commit file details'); + } args.sha = blame.commit.sha; @@ -75,7 +88,9 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCachedCommand } catch (ex) { Logger.error(ex, 'ShowQuickCommitFileDetailsCommand', `getBlameForLine(${blameline})`); - return window.showErrorMessage(`Unable to show commit file details. See output channel for more details`); + return window.showErrorMessage( + `Unable to show commit file details. See output channel for more details` + ); } } @@ -94,12 +109,20 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCachedCommand } if (args.fileLog === undefined) { - args.commit = await Container.git.getLogCommitForFile(args.commit === undefined ? gitUri.repoPath : args.commit.repoPath, gitUri.fsPath, { ref: args.sha }); - if (args.commit === undefined) return Messages.showCommitNotFoundWarningMessage(`Unable to show commit file details`); + args.commit = await Container.git.getLogCommitForFile( + args.commit === undefined ? gitUri.repoPath : args.commit.repoPath, + gitUri.fsPath, + { ref: args.sha } + ); + if (args.commit === undefined) { + return Messages.showCommitNotFoundWarningMessage(`Unable to show commit file details`); + } } } - if (args.commit === undefined) return Messages.showCommitNotFoundWarningMessage(`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; @@ -109,28 +132,45 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCachedCommand if (args.goBackCommand === undefined) { // Create a command to get back to the commit details - args.goBackCommand = new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to details of ${GlyphChars.Space}$(git-commit) ${shortSha}` - }, Commands.ShowQuickCommitDetails, [ + args.goBackCommand = new CommandQuickPickItem( + { + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to details of ${ + GlyphChars.Space + }$(git-commit) ${shortSha}` + }, + Commands.ShowQuickCommitDetails, + [ args.commit.toGitUri(), { commit: args.commit, sha: args.sha } as ShowQuickCommitDetailsCommandArgs - ]); + ] + ); } // Create a command to get back to where we are right now - const currentCommand = new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to details of ${GlyphChars.Space}$(file-text) ${path.basename(args.commit.fileName)} in ${GlyphChars.Space}$(git-commit) ${shortSha}` - }, Commands.ShowQuickCommitFileDetails, [ - args.commit.toGitUri(), - args - ]); - - const pick = await CommitFileQuickPick.show(args.commit as GitLogCommit, uri, args.goBackCommand, currentCommand, args.fileLog); + const currentCommand = new CommandQuickPickItem( + { + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to details of ${ + GlyphChars.Space + }$(file-text) ${path.basename(args.commit.fileName)} in ${ + GlyphChars.Space + }$(git-commit) ${shortSha}` + }, + Commands.ShowQuickCommitFileDetails, + [args.commit.toGitUri(), args] + ); + + const pick = await CommitFileQuickPick.show( + args.commit as GitLogCommit, + uri, + args.goBackCommand, + currentCommand, + args.fileLog + ); if (pick === undefined) return undefined; if (pick instanceof CommandQuickPickItem) return pick.execute(); @@ -142,4 +182,4 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCachedCommand return window.showErrorMessage(`Unable to show commit file details. See output channel for more details`); } } -} \ No newline at end of file +} diff --git a/src/commands/showQuickCurrentBranchHistory.ts b/src/commands/showQuickCurrentBranchHistory.ts index 0ba4e4c..411da5a 100644 --- a/src/commands/showQuickCurrentBranchHistory.ts +++ b/src/commands/showQuickCurrentBranchHistory.ts @@ -12,7 +12,6 @@ export interface ShowQuickCurrentBranchHistoryCommandArgs { } export class ShowQuickCurrentBranchHistoryCommand extends ActiveEditorCachedCommand { - constructor() { super(Commands.ShowQuickCurrentBranchHistory); } @@ -21,23 +20,25 @@ export class ShowQuickCurrentBranchHistoryCommand extends ActiveEditorCachedComm uri = getCommandUri(uri, editor); try { - const repoPath = await getRepoPathOrActiveOrPrompt(uri, editor, `Show current branch history for which repository${GlyphChars.Ellipsis}`); + const repoPath = await getRepoPathOrActiveOrPrompt( + uri, + editor, + `Show current branch history for which repository${GlyphChars.Ellipsis}` + ); if (!repoPath) return undefined; const branch = await Container.git.getBranch(repoPath); if (branch === undefined) return undefined; - return commands.executeCommand(Commands.ShowQuickBranchHistory, - uri, - { - branch: branch.name, - repoPath: repoPath, - goBackCommand: args.goBackCommand - } as ShowQuickBranchHistoryCommandArgs); + return commands.executeCommand(Commands.ShowQuickBranchHistory, uri, { + branch: branch.name, + repoPath: repoPath, + goBackCommand: args.goBackCommand + } as ShowQuickBranchHistoryCommandArgs); } catch (ex) { Logger.error(ex, 'ShowQuickCurrentBranchHistoryCommand'); return window.showErrorMessage(`Unable to show branch history. See output channel for more details`); } } -} \ No newline at end of file +} diff --git a/src/commands/showQuickFileHistory.ts b/src/commands/showQuickFileHistory.ts index 575d7ac..15a484c 100644 --- a/src/commands/showQuickFileHistory.ts +++ b/src/commands/showQuickFileHistory.ts @@ -6,7 +6,11 @@ import { GlyphChars } from '../constants'; import { Container } from '../container'; import { GitLog, GitUri } from '../gitService'; import { Logger } from '../logger'; -import { CommandQuickPickItem, FileHistoryQuickPick, ShowCommitsInResultsQuickPickItem } from '../quickPicks/quickPicks'; +import { + CommandQuickPickItem, + FileHistoryQuickPick, + ShowCommitsInResultsQuickPickItem +} from '../quickPicks/quickPicks'; import { ShowQuickCommitFileDetailsCommandArgs } from './showQuickCommitFileDetails'; import { Messages } from '../messages'; import * as path from 'path'; @@ -21,7 +25,6 @@ export interface ShowQuickFileHistoryCommandArgs { } export class ShowQuickFileHistoryCommand extends ActiveEditorCachedCommand { - constructor() { super(Commands.ShowQuickFileHistory); } @@ -34,13 +37,21 @@ export class ShowQuickFileHistoryCommand extends ActiveEditorCachedCommand { args = { ...args }; - const placeHolder = `${gitUri.getFormattedPath()}${gitUri.sha ? ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${gitUri.shortSha}` : ''}`; + const placeHolder = `${gitUri.getFormattedPath()}${ + gitUri.sha ? ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${gitUri.shortSha}` : '' + }`; const progressCancellation = FileHistoryQuickPick.showProgress(placeHolder); try { if (args.log === undefined) { - args.log = await Container.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { maxCount: args.maxCount, range: args.range, ref: gitUri.sha }); - if (args.log === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show file history'); + args.log = await Container.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { + maxCount: args.maxCount, + range: args.range, + ref: gitUri.sha + }); + if (args.log === undefined) { + return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show file history'); + } } if (progressCancellation.token.isCancellationRequested) return undefined; @@ -48,17 +59,30 @@ export class ShowQuickFileHistoryCommand extends ActiveEditorCachedCommand { let previousPageCommand: CommandQuickPickItem | undefined = undefined; if (args.log.truncated) { - const npc = new CommandQuickPickItem({ - label: `$(arrow-right) Show Next Commits`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${args.log.maxCount} newer commits` - }, Commands.ShowQuickFileHistory, [gitUri, { ...args, log: undefined } as ShowQuickFileHistoryCommandArgs]); + const npc = new CommandQuickPickItem( + { + label: `$(arrow-right) Show Next Commits`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${args.log.maxCount} newer commits` + }, + Commands.ShowQuickFileHistory, + [gitUri, { ...args, log: undefined } as ShowQuickFileHistoryCommandArgs] + ); const last = Iterables.last(args.log.commits.values()); if (last != null) { - previousPageCommand = new CommandQuickPickItem({ - label: `$(arrow-left) Show Previous Commits`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${args.log.maxCount} older commits` - }, Commands.ShowQuickFileHistory, [new GitUri(uri, last), { ...args, log: undefined, nextPageCommand: npc } as ShowQuickFileHistoryCommandArgs]); + previousPageCommand = new CommandQuickPickItem( + { + label: `$(arrow-left) Show Previous Commits`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${ + args.log.maxCount + } older commits` + }, + Commands.ShowQuickFileHistory, + [ + new GitUri(uri, last), + { ...args, log: undefined, nextPageCommand: npc } as ShowQuickFileHistoryCommandArgs + ] + ); } } @@ -67,40 +91,49 @@ export class ShowQuickFileHistoryCommand extends ActiveEditorCachedCommand { goBackCommand: args.goBackCommand, nextPageCommand: args.nextPageCommand, previousPageCommand: previousPageCommand, - showAllCommand: args.log !== undefined && args.log.truncated - ? new CommandQuickPickItem({ - label: `$(sync) Show All Commits`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} this may take a while` - }, Commands.ShowQuickFileHistory, [uri, { ...args, log: undefined, maxCount: 0 }]) - : undefined, - showInResultsExplorerCommand: args.log !== undefined - ? new ShowCommitsInResultsQuickPickItem(args.log, { - label: placeHolder, - resultsType: { singular: 'commit', plural: 'commits' } - }) - : undefined + showAllCommand: + args.log !== undefined && args.log.truncated + ? new CommandQuickPickItem( + { + label: `$(sync) Show All Commits`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} this may take a while` + }, + Commands.ShowQuickFileHistory, + [uri, { ...args, log: undefined, maxCount: 0 }] + ) + : undefined, + showInResultsExplorerCommand: + args.log !== undefined + ? new ShowCommitsInResultsQuickPickItem(args.log, { + label: placeHolder, + resultsType: { singular: 'commit', plural: 'commits' } + }) + : undefined }); if (pick === undefined) return undefined; if (pick instanceof CommandQuickPickItem) return pick.execute(); // Create a command to get back to where we are right now - const currentCommand = new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to history of ${GlyphChars.Space}$(file-text) ${path.basename(pick.commit.fileName)}${gitUri.sha ? ` from ${GlyphChars.Space}$(git-commit) ${gitUri.shortSha}` : ''}` - }, Commands.ShowQuickFileHistory, [ - uri, - args - ]); - - return commands.executeCommand(Commands.ShowQuickCommitFileDetails, - pick.commit.toGitUri(), + const currentCommand = new CommandQuickPickItem( { - commit: pick.commit, - fileLog: args.log, - sha: pick.commit.sha, - goBackCommand: currentCommand - } as ShowQuickCommitFileDetailsCommandArgs); + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to history of ${ + GlyphChars.Space + }$(file-text) ${path.basename(pick.commit.fileName)}${ + gitUri.sha ? ` from ${GlyphChars.Space}$(git-commit) ${gitUri.shortSha}` : '' + }` + }, + Commands.ShowQuickFileHistory, + [uri, args] + ); + + return commands.executeCommand(Commands.ShowQuickCommitFileDetails, pick.commit.toGitUri(), { + commit: pick.commit, + fileLog: args.log, + sha: pick.commit.sha, + goBackCommand: currentCommand + } as ShowQuickCommitFileDetailsCommandArgs); } catch (ex) { Logger.error(ex, 'ShowQuickFileHistoryCommand'); @@ -110,4 +143,4 @@ export class ShowQuickFileHistoryCommand extends ActiveEditorCachedCommand { progressCancellation.cancel(); } } -} \ No newline at end of file +} diff --git a/src/commands/showQuickRepoStatus.ts b/src/commands/showQuickRepoStatus.ts index 091c4cd..6fbdf01 100644 --- a/src/commands/showQuickRepoStatus.ts +++ b/src/commands/showQuickRepoStatus.ts @@ -11,7 +11,6 @@ export interface ShowQuickRepoStatusCommandArgs { } export class ShowQuickRepoStatusCommand extends ActiveEditorCachedCommand { - constructor() { super(Commands.ShowQuickRepoStatus); } @@ -20,7 +19,11 @@ export class ShowQuickRepoStatusCommand extends ActiveEditorCachedCommand { uri = getCommandUri(uri, editor); try { - const repoPath = await getRepoPathOrActiveOrPrompt(uri, editor, `Show status for which repository${GlyphChars.Ellipsis}`); + const repoPath = await getRepoPathOrActiveOrPrompt( + uri, + editor, + `Show status for which repository${GlyphChars.Ellipsis}` + ); if (!repoPath) return undefined; const status = await Container.git.getStatusForRepo(repoPath); @@ -38,4 +41,4 @@ export class ShowQuickRepoStatusCommand extends ActiveEditorCachedCommand { return window.showErrorMessage(`Unable to show repository status. See output channel for more details`); } } -} \ No newline at end of file +} diff --git a/src/commands/showQuickStashList.ts b/src/commands/showQuickStashList.ts index 243dabf..c31949c 100644 --- a/src/commands/showQuickStashList.ts +++ b/src/commands/showQuickStashList.ts @@ -13,7 +13,6 @@ export interface ShowQuickStashListCommandArgs { } export class ShowQuickStashListCommand extends ActiveEditorCachedCommand { - constructor() { super(Commands.ShowQuickStashList); } @@ -24,7 +23,11 @@ export class ShowQuickStashListCommand extends ActiveEditorCachedCommand { const progressCancellation = StashListQuickPick.showProgress('list'); try { - const repoPath = await getRepoPathOrActiveOrPrompt(uri, editor, `Show stashed changes for which repository${GlyphChars.Ellipsis}`); + const repoPath = await getRepoPathOrActiveOrPrompt( + uri, + editor, + `Show stashed changes for which repository${GlyphChars.Ellipsis}` + ); if (!repoPath) return undefined; const stash = await Container.git.getStashList(repoPath); @@ -33,28 +36,36 @@ export class ShowQuickStashListCommand extends ActiveEditorCachedCommand { if (progressCancellation.token.isCancellationRequested) return undefined; // Create a command to get back to here - const currentCommand = new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to stashed changes` - }, Commands.ShowQuickStashList, [ + const currentCommand = new CommandQuickPickItem( + { + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to stashed changes` + }, + Commands.ShowQuickStashList, + [ uri, { goBackCommand: args.goBackCommand } as ShowQuickStashListCommandArgs - ]); + ] + ); - const pick = await StashListQuickPick.show(stash, 'list', progressCancellation, args.goBackCommand, currentCommand); + const pick = await StashListQuickPick.show( + stash, + 'list', + progressCancellation, + args.goBackCommand, + currentCommand + ); if (pick === undefined) return undefined; if (pick instanceof CommandQuickPickItem) return pick.execute(); - return commands.executeCommand(Commands.ShowQuickCommitDetails, - pick.commit.toGitUri(), - { - commit: pick.commit, - sha: pick.commit.sha, - goBackCommand: currentCommand - } as ShowQuickCommitDetailsCommandArgs); + return commands.executeCommand(Commands.ShowQuickCommitDetails, pick.commit.toGitUri(), { + commit: pick.commit, + sha: pick.commit.sha, + goBackCommand: currentCommand + } as ShowQuickCommitDetailsCommandArgs); } catch (ex) { Logger.error(ex, 'ShowQuickStashListCommand'); @@ -64,4 +75,4 @@ export class ShowQuickStashListCommand extends ActiveEditorCachedCommand { progressCancellation.cancel(); } } -} \ No newline at end of file +} diff --git a/src/commands/showResultsExplorer.ts b/src/commands/showResultsExplorer.ts index 7794657..414ceee 100644 --- a/src/commands/showResultsExplorer.ts +++ b/src/commands/showResultsExplorer.ts @@ -3,7 +3,6 @@ import { Command, Commands } from './common'; import { Container } from '../container'; export class ShowResultsExplorerCommand extends Command { - constructor() { super(Commands.ShowResultsExplorer); } @@ -11,4 +10,4 @@ export class ShowResultsExplorerCommand extends Command { execute() { return Container.resultsExplorer.show(); } -} \ No newline at end of file +} diff --git a/src/commands/stashApply.ts b/src/commands/stashApply.ts index 8285259..a922d8e 100644 --- a/src/commands/stashApply.ts +++ b/src/commands/stashApply.ts @@ -11,18 +11,20 @@ import { CommandQuickPickItem, RepositoriesQuickPick, StashListQuickPick } from export interface StashApplyCommandArgs { confirm?: boolean; deleteAfter?: boolean; - stashItem?: { stashName: string, message: string, repoPath: string }; + stashItem?: { stashName: string; message: string; repoPath: string }; goBackCommand?: CommandQuickPickItem; } export class StashApplyCommand extends Command { - constructor() { super(Commands.StashApply); } - protected async preExecute(context: CommandContext, args: StashApplyCommandArgs = { confirm: true, deleteAfter: false }) { + protected async preExecute( + context: CommandContext, + args: StashApplyCommandArgs = { confirm: true, deleteAfter: false } + ) { if (isCommandViewContextWithCommit<GitStashCommit>(context)) { args = { ...args }; args.stashItem = context.node.commit; @@ -40,14 +42,23 @@ export class StashApplyCommand extends Command { let repoPath = await Container.git.getActiveRepoPath(); if (!repoPath) { - const pick = await RepositoriesQuickPick.show(`Apply stashed changes from which repository${GlyphChars.Ellipsis}`, args.goBackCommand); + const pick = await RepositoriesQuickPick.show( + `Apply stashed changes from which repository${GlyphChars.Ellipsis}`, + args.goBackCommand + ); if (pick instanceof CommandQuickPickItem) return pick.execute(); - if (pick === undefined) return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute(); - - goBackToRepositoriesCommand = new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to pick another repository` - }, Commands.StashApply, [args]); + if (pick === undefined) { + return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute(); + } + + goBackToRepositoriesCommand = new CommandQuickPickItem( + { + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to pick another repository` + }, + Commands.StashApply, + [args] + ); repoPath = pick.repoPath; } @@ -60,14 +71,26 @@ export class StashApplyCommand extends Command { if (progressCancellation.token.isCancellationRequested) return undefined; - const currentCommand = new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to apply stashed changes` - }, Commands.StashApply, [args]); - - const pick = await StashListQuickPick.show(stash, 'apply', progressCancellation, goBackToRepositoriesCommand || args.goBackCommand, currentCommand); + const currentCommand = new CommandQuickPickItem( + { + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to apply stashed changes` + }, + Commands.StashApply, + [args] + ); + + const pick = await StashListQuickPick.show( + stash, + 'apply', + progressCancellation, + goBackToRepositoriesCommand || args.goBackCommand, + currentCommand + ); if (pick instanceof CommandQuickPickItem) return pick.execute(); - if (pick === undefined) return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute(); + if (pick === undefined) { + return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute(); + } args.goBackCommand = currentCommand; args.stashItem = pick.commit as GitStashCommit; @@ -79,9 +102,19 @@ export class StashApplyCommand extends Command { try { if (args.confirm) { - const message = args.stashItem.message.length > 80 ? `${args.stashItem.message.substring(0, 80)}${GlyphChars.Ellipsis}` : args.stashItem.message; - const result = await window.showWarningMessage(`Apply stashed changes '${message}' to your working tree?`, { title: 'Yes, delete after applying' } as MessageItem, { title: 'Yes' } as MessageItem, { title: 'No', isCloseAffordance: true } as MessageItem); - if (result === undefined || result.title === 'No') return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute(); + const message = + args.stashItem.message.length > 80 + ? `${args.stashItem.message.substring(0, 80)}${GlyphChars.Ellipsis}` + : args.stashItem.message; + const result = await window.showWarningMessage( + `Apply stashed changes '${message}' to your working tree?`, + { title: 'Yes, delete after applying' } as MessageItem, + { title: 'Yes' } as MessageItem, + { title: 'No', isCloseAffordance: true } as MessageItem + ); + if (result === undefined || result.title === 'No') { + return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute(); + } args.deleteAfter = result.title !== 'Yes'; } @@ -91,7 +124,9 @@ export class StashApplyCommand extends Command { catch (ex) { Logger.error(ex, 'StashApplyCommand'); if (ex.message.includes('Your local changes to the following files would be overwritten by merge')) { - return window.showWarningMessage(`Unable to apply stash. Your working tree changes would be overwritten.`); + return window.showWarningMessage( + `Unable to apply stash. Your working tree changes would be overwritten.` + ); } else if (ex.message.includes('Auto-merging') && ex.message.includes('CONFLICT')) { return window.showInformationMessage(`Stash applied with conflicts`); @@ -101,4 +136,4 @@ export class StashApplyCommand extends Command { } } } -} \ No newline at end of file +} diff --git a/src/commands/stashDelete.ts b/src/commands/stashDelete.ts index 8a7492a..4953d1f 100644 --- a/src/commands/stashDelete.ts +++ b/src/commands/stashDelete.ts @@ -9,13 +9,12 @@ import { CommandQuickPickItem } from '../quickPicks/quickPicks'; export interface StashDeleteCommandArgs { confirm?: boolean; - stashItem?: { stashName: string, message: string, repoPath: string }; + stashItem?: { stashName: string; message: string; repoPath: string }; goBackCommand?: CommandQuickPickItem; } export class StashDeleteCommand extends Command { - constructor() { super(Commands.StashDelete); } @@ -32,7 +31,13 @@ export class StashDeleteCommand extends Command { async execute(args: StashDeleteCommandArgs = { confirm: true }) { args = { ...args }; - if (args.stashItem === undefined || args.stashItem.stashName === undefined || args.stashItem.repoPath === undefined) return undefined; + if ( + args.stashItem === undefined || + args.stashItem.stashName === undefined || + args.stashItem.repoPath === undefined + ) { + return undefined; + } if (args.confirm === undefined) { args.confirm = true; @@ -40,9 +45,18 @@ export class StashDeleteCommand extends Command { try { if (args.confirm) { - const message = args.stashItem.message.length > 80 ? `${args.stashItem.message.substring(0, 80)}${GlyphChars.Ellipsis}` : args.stashItem.message; - const result = await window.showWarningMessage(`Delete stashed changes '${message}'?`, { title: 'Yes' } as MessageItem, { title: 'No', isCloseAffordance: true } as MessageItem); - if (result === undefined || result.title !== 'Yes') return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute(); + const message = + args.stashItem.message.length > 80 + ? `${args.stashItem.message.substring(0, 80)}${GlyphChars.Ellipsis}` + : args.stashItem.message; + const result = await window.showWarningMessage( + `Delete stashed changes '${message}'?`, + { title: 'Yes' } as MessageItem, + { title: 'No', isCloseAffordance: true } as MessageItem + ); + if (result === undefined || result.title !== 'Yes') { + return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute(); + } } return await Container.git.stashDelete(args.stashItem.repoPath, args.stashItem.stashName); @@ -52,4 +66,4 @@ export class StashDeleteCommand extends Command { return window.showErrorMessage(`Unable to delete stash. See output channel for more details`); } } -} \ No newline at end of file +} diff --git a/src/commands/stashSave.ts b/src/commands/stashSave.ts index 62e83aa..5bb26b2 100644 --- a/src/commands/stashSave.ts +++ b/src/commands/stashSave.ts @@ -15,7 +15,6 @@ export interface StashSaveCommandArgs { } export class StashSaveCommand extends Command { - constructor() { super(Commands.StashSave); } @@ -29,7 +28,10 @@ export class StashSaveCommand extends Command { if (context.type === 'scm-groups') { args = { ...args }; - args.uris = context.scmResourceGroups.reduce<Uri[]>((a, b) => a.concat(b.resourceStates.map(s => s.resourceUri)), []); + args.uris = context.scmResourceGroups.reduce<Uri[]>( + (a, b) => a.concat(b.resourceStates.map(s => s.resourceUri)), + [] + ); return this.execute(args); } @@ -39,7 +41,10 @@ export class StashSaveCommand extends Command { async execute(args: StashSaveCommandArgs = {}) { let repoPath = await Container.git.getHighlanderRepoPath(); if (!repoPath) { - const pick = await RepositoriesQuickPick.show(`Stash changes for which repository${GlyphChars.Ellipsis}`, args.goBackCommand); + const pick = await RepositoriesQuickPick.show( + `Stash changes for which repository${GlyphChars.Ellipsis}`, + args.goBackCommand + ); if (pick instanceof CommandQuickPickItem) return pick.execute(); if (pick === undefined) return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute(); @@ -53,7 +58,9 @@ export class StashSaveCommand extends Command { prompt: `Please provide a stash message`, placeHolder: `Stash message` } as InputBoxOptions); - if (args.message === undefined) return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute(); + if (args.message === undefined) { + return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute(); + } } return await Container.git.stashSave(repoPath, args.message, args.uris); @@ -68,4 +75,4 @@ export class StashSaveCommand extends Command { return window.showErrorMessage(`Unable to save stash. See output channel for more details`); } } -} \ No newline at end of file +} diff --git a/src/commands/switchMode.ts b/src/commands/switchMode.ts index 81cc953..5aac20e 100644 --- a/src/commands/switchMode.ts +++ b/src/commands/switchMode.ts @@ -6,7 +6,6 @@ import { Container } from '../container'; import { ModesQuickPick } from '../quickPicks/quickPicks'; export class SwitchModeCommand extends Command { - constructor() { super(Commands.SwitchMode); } @@ -20,7 +19,6 @@ export class SwitchModeCommand extends Command { } export class ToggleReviewModeCommand extends Command { - constructor() { super(Commands.ToggleReviewMode); } @@ -34,7 +32,6 @@ export class ToggleReviewModeCommand extends Command { } export class ToggleZenModeCommand extends Command { - constructor() { super(Commands.ToggleZenMode); } diff --git a/src/commands/toggleCodeLens.ts b/src/commands/toggleCodeLens.ts index d1e8f0b..4ea916a 100644 --- a/src/commands/toggleCodeLens.ts +++ b/src/commands/toggleCodeLens.ts @@ -3,7 +3,6 @@ import { Command, Commands } from './common'; import { Container } from '../container'; export class ToggleCodeLensCommand extends Command { - constructor() { super(Commands.ToggleCodeLens); } diff --git a/src/commands/toggleFileBlame.ts b/src/commands/toggleFileBlame.ts index 2990658..60c9215 100644 --- a/src/commands/toggleFileBlame.ts +++ b/src/commands/toggleFileBlame.ts @@ -12,7 +12,6 @@ export interface ToggleFileBlameCommandArgs { } export class ToggleFileBlameCommand extends ActiveEditorCommand { - constructor() { super(Commands.ToggleFileBlame); } @@ -35,11 +34,17 @@ export class ToggleFileBlameCommand extends ActiveEditorCommand { args = { ...args, type: FileAnnotationType.Blame }; } - return Container.fileAnnotations.toggle(editor, args.type!, args.sha !== undefined ? args.sha : editor && editor.selection.active.line); + return Container.fileAnnotations.toggle( + editor, + args.type!, + args.sha !== undefined ? args.sha : editor && editor.selection.active.line + ); } catch (ex) { Logger.error(ex, 'ToggleFileBlameCommand'); - return window.showErrorMessage(`Unable to toggle file ${args.type} annotations. See output channel for more details`); + return window.showErrorMessage( + `Unable to toggle file ${args.type} annotations. See output channel for more details` + ); } } -} \ No newline at end of file +} diff --git a/src/commands/toggleFileHeatmap.ts b/src/commands/toggleFileHeatmap.ts index 6467889..5900ace 100644 --- a/src/commands/toggleFileHeatmap.ts +++ b/src/commands/toggleFileHeatmap.ts @@ -5,12 +5,13 @@ import { ActiveEditorCommand, Commands } from './common'; import { FileAnnotationType } from '../configuration'; export class ToggleFileHeatmapCommand extends ActiveEditorCommand { - constructor() { super(Commands.ToggleFileHeatmap); } async execute(editor: TextEditor, uri?: Uri): Promise<any> { - commands.executeCommand(Commands.ToggleFileBlame, uri, { type: FileAnnotationType.Heatmap } as ToggleFileBlameCommandArgs); + commands.executeCommand(Commands.ToggleFileBlame, uri, { + type: FileAnnotationType.Heatmap + } as ToggleFileBlameCommandArgs); } -} \ No newline at end of file +} diff --git a/src/commands/toggleFileRecentChanges.ts b/src/commands/toggleFileRecentChanges.ts index cc96f89..4d70df0 100644 --- a/src/commands/toggleFileRecentChanges.ts +++ b/src/commands/toggleFileRecentChanges.ts @@ -5,12 +5,13 @@ import { ActiveEditorCommand, Commands } from './common'; import { FileAnnotationType } from '../configuration'; export class ToggleFileRecentChangesCommand extends ActiveEditorCommand { - constructor() { super(Commands.ToggleFileRecentChanges); } async execute(editor: TextEditor, uri?: Uri): Promise<any> { - commands.executeCommand(Commands.ToggleFileBlame, uri, { type: FileAnnotationType.RecentChanges } as ToggleFileBlameCommandArgs); + commands.executeCommand(Commands.ToggleFileBlame, uri, { + type: FileAnnotationType.RecentChanges + } as ToggleFileBlameCommandArgs); } -} \ No newline at end of file +} diff --git a/src/commands/toggleLineBlame.ts b/src/commands/toggleLineBlame.ts index 3b826bc..d1cc49f 100644 --- a/src/commands/toggleLineBlame.ts +++ b/src/commands/toggleLineBlame.ts @@ -5,7 +5,6 @@ import { Container } from '../container'; import { Logger } from '../logger'; export class ToggleLineBlameCommand extends ActiveEditorCommand { - constructor() { super(Commands.ToggleLineBlame); } @@ -16,7 +15,9 @@ export class ToggleLineBlameCommand extends ActiveEditorCommand { } catch (ex) { Logger.error(ex, 'ToggleLineBlameCommand'); - return window.showErrorMessage(`Unable to toggle line blame annotations. See output channel for more details`); + return window.showErrorMessage( + `Unable to toggle line blame annotations. See output channel for more details` + ); } } -} \ No newline at end of file +} diff --git a/src/comparers.ts b/src/comparers.ts index 185345b..bd09f3d 100644 --- a/src/comparers.ts +++ b/src/comparers.ts @@ -6,7 +6,6 @@ abstract class Comparer<T> { } class UriComparer extends Comparer<Uri> { - equals(lhs: Uri | undefined, rhs: Uri | undefined) { if (lhs === rhs) return true; if (lhs === undefined || rhs === undefined) return false; @@ -16,7 +15,6 @@ class UriComparer extends Comparer<Uri> { } class TextDocumentComparer extends Comparer<TextDocument> { - equals(lhs: TextDocument | undefined, rhs: TextDocument | undefined) { return lhs === rhs; // if (lhs === rhs) return true; @@ -27,12 +25,15 @@ class TextDocumentComparer extends Comparer<TextDocument> { } class TextEditorComparer extends Comparer<TextEditor> { - - equals(lhs: TextEditor | undefined, rhs: TextEditor | undefined, options: { useId: boolean, usePosition: boolean } = { useId: false, usePosition: false }) { + equals( + lhs: TextEditor | undefined, + rhs: TextEditor | undefined, + options: { useId: boolean; usePosition: boolean } = { useId: false, usePosition: false } + ) { if (lhs === rhs) return true; if (lhs === undefined || rhs === undefined) return false; - if (options.usePosition && (lhs.viewColumn !== rhs.viewColumn)) return false; + if (options.usePosition && lhs.viewColumn !== rhs.viewColumn) return false; if (options.useId && (!lhs.document || !rhs.document)) { if ((lhs as any).id !== (rhs as any).id) return false; diff --git a/src/configuration.ts b/src/configuration.ts index 95208fa..0fddb81 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -2,7 +2,15 @@ export * from './ui/config'; import { Functions } from './system'; -import { ConfigurationChangeEvent, ConfigurationTarget, Event, EventEmitter, ExtensionContext, Uri, workspace } from 'vscode'; +import { + ConfigurationChangeEvent, + ConfigurationTarget, + Event, + EventEmitter, + ExtensionContext, + Uri, + workspace +} from 'vscode'; import { IConfig, KeyMap } from './ui/config'; import { CommandContext, extensionId, setCommandContext } from './constants'; import { Container } from './container'; @@ -15,9 +23,10 @@ const emptyConfig: any = new Proxy<any>({} as IConfig, { }); export class Configuration { - static configure(context: ExtensionContext) { - context.subscriptions.push(workspace.onDidChangeConfiguration(configuration.onConfigurationChanged, configuration)); + context.subscriptions.push( + workspace.onDidChangeConfiguration(configuration.onConfigurationChanged, configuration) + ); } private _onDidChange = new EventEmitter<ConfigurationChangeEvent>(); @@ -54,8 +63,10 @@ export class Configuration { setCommandContext(CommandContext.KeyMap, this.get<KeyMap>(section)); } - if (configuration.changed(e, configuration.name('mode').value) || - configuration.changed(e, configuration.name('modes').value)) { + if ( + configuration.changed(e, configuration.name('mode').value) || + configuration.changed(e, configuration.name('modes').value) + ) { const original = e.affectsConfiguration; e = { ...e, @@ -78,8 +89,12 @@ export class Configuration { get<T>(section?: string, resource?: Uri | null, defaultValue?: T) { return defaultValue === undefined - ? workspace.getConfiguration(section === undefined ? undefined : extensionId, resource!).get<T>(section === undefined ? extensionId : section)! - : workspace.getConfiguration(section === undefined ? undefined : extensionId, resource!).get<T>(section === undefined ? extensionId : section, defaultValue)!; + ? workspace + .getConfiguration(section === undefined ? undefined : extensionId, resource!) + .get<T>(section === undefined ? extensionId : section)! + : workspace + .getConfiguration(section === undefined ? undefined : extensionId, resource!) + .get<T>(section === undefined ? extensionId : section, defaultValue)!; } changed(e: ConfigurationChangeEvent, section: string, resource?: Uri | null) { @@ -91,16 +106,26 @@ export class Configuration { } inspect(section?: string, resource?: Uri | null) { - return workspace.getConfiguration(section === undefined ? undefined : extensionId, resource!).inspect(section === undefined ? extensionId : section); + return workspace + .getConfiguration(section === undefined ? undefined : extensionId, resource!) + .inspect(section === undefined ? extensionId : section); } - async migrate<TFrom, TTo>(from: string, to: string, options: { fallbackValue?: TTo, migrationFn?: (value: TFrom) => TTo } = {}): Promise<boolean> { + async migrate<TFrom, TTo>( + from: string, + to: string, + options: { fallbackValue?: TTo; migrationFn?(value: TFrom): TTo } = {} + ): Promise<boolean> { const inspection = configuration.inspect(from); if (inspection === undefined) return false; let migrated = false; if (inspection.globalValue !== undefined) { - await this.update(to, options.migrationFn ? options.migrationFn(inspection.globalValue as TFrom) : inspection.globalValue, ConfigurationTarget.Global); + await this.update( + to, + options.migrationFn ? options.migrationFn(inspection.globalValue as TFrom) : inspection.globalValue, + ConfigurationTarget.Global + ); migrated = true; // Can't delete the old setting currently because it errors with `Unable to write to User Settings because <setting name> is not a registered configuration` // if (from !== to) { @@ -112,7 +137,13 @@ export class Configuration { } if (inspection.workspaceValue !== undefined) { - await this.update(to, options.migrationFn ? options.migrationFn(inspection.workspaceValue as TFrom) : inspection.workspaceValue, ConfigurationTarget.Workspace); + await this.update( + to, + options.migrationFn + ? options.migrationFn(inspection.workspaceValue as TFrom) + : inspection.workspaceValue, + ConfigurationTarget.Workspace + ); migrated = true; // Can't delete the old setting currently because it errors with `Unable to write to User Settings because <setting name> is not a registered configuration` // if (from !== to) { @@ -124,7 +155,13 @@ export class Configuration { } if (inspection.workspaceFolderValue !== undefined) { - await this.update(to, options.migrationFn ? options.migrationFn(inspection.workspaceFolderValue as TFrom) : inspection.workspaceFolderValue, ConfigurationTarget.WorkspaceFolder); + await this.update( + to, + options.migrationFn + ? options.migrationFn(inspection.workspaceFolderValue as TFrom) + : inspection.workspaceFolderValue, + ConfigurationTarget.WorkspaceFolder + ); migrated = true; // Can't delete the old setting currently because it errors with `Unable to write to User Settings because <setting name> is not a registered configuration` // if (from !== to) { @@ -143,14 +180,20 @@ export class Configuration { return migrated; } - async migrateIfMissing<TFrom, TTo>(from: string, to: string, options: { migrationFn?: (value: TFrom) => TTo } = {}) { + async migrateIfMissing<TFrom, TTo>(from: string, to: string, options: { migrationFn?(value: TFrom): TTo } = {}) { const fromInspection = configuration.inspect(from); if (fromInspection === undefined) return; const toInspection = configuration.inspect(to); if (fromInspection.globalValue !== undefined) { if (toInspection === undefined || toInspection.globalValue === undefined) { - await this.update(to, options.migrationFn ? options.migrationFn(fromInspection.globalValue as TFrom) : fromInspection.globalValue, ConfigurationTarget.Global); + await this.update( + to, + options.migrationFn + ? options.migrationFn(fromInspection.globalValue as TFrom) + : fromInspection.globalValue, + ConfigurationTarget.Global + ); // Can't delete the old setting currently because it errors with `Unable to write to User Settings because <setting name> is not a registered configuration` // if (from !== to) { // try { @@ -163,7 +206,13 @@ export class Configuration { if (fromInspection.workspaceValue !== undefined) { if (toInspection === undefined || toInspection.workspaceValue === undefined) { - await this.update(to, options.migrationFn ? options.migrationFn(fromInspection.workspaceValue as TFrom) : fromInspection.workspaceValue, ConfigurationTarget.Workspace); + await this.update( + to, + options.migrationFn + ? options.migrationFn(fromInspection.workspaceValue as TFrom) + : fromInspection.workspaceValue, + ConfigurationTarget.Workspace + ); // Can't delete the old setting currently because it errors with `Unable to write to User Settings because <setting name> is not a registered configuration` // if (from !== to) { // try { @@ -176,7 +225,13 @@ export class Configuration { if (fromInspection.workspaceFolderValue !== undefined) { if (toInspection === undefined || toInspection.workspaceFolderValue === undefined) { - await this.update(to, options.migrationFn ? options.migrationFn(fromInspection.workspaceFolderValue as TFrom) : fromInspection.workspaceFolderValue, ConfigurationTarget.WorkspaceFolder); + await this.update( + to, + options.migrationFn + ? options.migrationFn(fromInspection.workspaceFolderValue as TFrom) + : fromInspection.workspaceFolderValue, + ConfigurationTarget.WorkspaceFolder + ); // Can't delete the old setting currently because it errors with `Unable to write to User Settings because <setting name> is not a registered configuration` // if (from !== to) { // try { @@ -209,7 +264,12 @@ export class Configuration { await configuration.update(section, value, ConfigurationTarget.Workspace); } else { - if (inspect.globalValue === value || (inspect.globalValue === undefined && inspect.defaultValue === value)) return; + if ( + inspect.globalValue === value || + (inspect.globalValue === undefined && inspect.defaultValue === value) + ) { + return; + } await configuration.update(section, value, ConfigurationTarget.Global); } } diff --git a/src/constants.ts b/src/constants.ts index 32d5574..055b5d5 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -57,7 +57,7 @@ export enum DocumentSchemes { export function getEditorIfActive(document: TextDocument): TextEditor | undefined { const editor = window.activeTextEditor; - return (editor != null && editor.document === document) ? editor : undefined; + return editor != null && editor.document === document ? editor : undefined; } export function isActiveDocument(document: TextDocument): boolean { @@ -112,16 +112,7 @@ export enum GlobalState { GitLensVersion = 'gitlensVersion' } -export const ImageExtensions = [ - '.png', - '.gif', - '.jpg', - '.jpeg', - '.webp', - '.tif', - '.tiff', - '.bmp' -]; +export const ImageExtensions = ['.png', '.gif', '.jpg', '.jpeg', '.webp', '.tif', '.tiff', '.bmp']; export enum WorkspaceState { GitExplorerAutoRefresh = 'gitlens:gitExplorer:autoRefresh', diff --git a/src/container.ts b/src/container.ts index c700b56..e4914a1 100644 --- a/src/container.ts +++ b/src/container.ts @@ -20,55 +20,58 @@ import { StatusBarController } from './statusBarController'; import { WelcomeEditor } from './webviews/welcomeEditor'; export class Container { - static initialize(context: ExtensionContext, config: IConfig) { this._context = context; this._config = Container.applyMode(config); - context.subscriptions.push(this._lineTracker = new GitLineTracker()); - context.subscriptions.push(this._tracker = new GitDocumentTracker()); - context.subscriptions.push(this._git = new GitService()); + context.subscriptions.push((this._lineTracker = new GitLineTracker())); + context.subscriptions.push((this._tracker = new GitDocumentTracker())); + context.subscriptions.push((this._git = new GitService())); // Since there is a bit of a chicken & egg problem with the DocumentTracker and the GitService, initialize the tracker once the GitService is loaded this._tracker.initialize(); - context.subscriptions.push(this._fileAnnotationController = new FileAnnotationController()); - context.subscriptions.push(this._lineAnnotationController = new LineAnnotationController()); - context.subscriptions.push(this._lineHoverController = new LineHoverController()); - context.subscriptions.push(this._statusBarController = new StatusBarController()); - context.subscriptions.push(this._codeLensController = new CodeLensController()); - context.subscriptions.push(this._keyboard = new Keyboard()); - context.subscriptions.push(this._settingsEditor = new SettingsEditor()); - context.subscriptions.push(this._welcomeEditor = new WelcomeEditor()); + context.subscriptions.push((this._fileAnnotationController = new FileAnnotationController())); + context.subscriptions.push((this._lineAnnotationController = new LineAnnotationController())); + context.subscriptions.push((this._lineHoverController = new LineHoverController())); + context.subscriptions.push((this._statusBarController = new StatusBarController())); + context.subscriptions.push((this._codeLensController = new CodeLensController())); + context.subscriptions.push((this._keyboard = new Keyboard())); + context.subscriptions.push((this._settingsEditor = new SettingsEditor())); + context.subscriptions.push((this._welcomeEditor = new WelcomeEditor())); if (config.gitExplorer.enabled) { - context.subscriptions.push(this._gitExplorer = new GitExplorer()); + context.subscriptions.push((this._gitExplorer = new GitExplorer())); } else { let disposable: Disposable; disposable = configuration.onDidChange(e => { if (configuration.changed(e, configuration.name('gitExplorer')('enabled').value)) { disposable.dispose(); - context.subscriptions.push(this._gitExplorer = new GitExplorer()); + context.subscriptions.push((this._gitExplorer = new GitExplorer())); } }); } if (config.historyExplorer.enabled) { - context.subscriptions.push(this._historyExplorer = new HistoryExplorer()); + context.subscriptions.push((this._historyExplorer = new HistoryExplorer())); } else { let disposable: Disposable; disposable = configuration.onDidChange(e => { if (configuration.changed(e, configuration.name('historyExplorer')('enabled').value)) { disposable.dispose(); - context.subscriptions.push(this._historyExplorer = new HistoryExplorer()); + context.subscriptions.push((this._historyExplorer = new HistoryExplorer())); } }); } - context.subscriptions.push(workspace.registerTextDocumentContentProvider(GitContentProvider.scheme, new GitContentProvider())); - context.subscriptions.push(languages.registerCodeLensProvider(GitRevisionCodeLensProvider.selector, new GitRevisionCodeLensProvider())); + context.subscriptions.push( + workspace.registerTextDocumentContentProvider(GitContentProvider.scheme, new GitContentProvider()) + ); + context.subscriptions.push( + languages.registerCodeLensProvider(GitRevisionCodeLensProvider.selector, new GitRevisionCodeLensProvider()) + ); } private static _codeLensController: CodeLensController; @@ -92,7 +95,7 @@ export class Container { private static _explorerCommands: ExplorerCommands | undefined; static get explorerCommands() { if (this._explorerCommands === undefined) { - this._context.subscriptions.push(this._explorerCommands = new ExplorerCommands()); + this._context.subscriptions.push((this._explorerCommands = new ExplorerCommands())); } return this._explorerCommands; } @@ -115,7 +118,7 @@ export class Container { private static _historyExplorer: HistoryExplorer | undefined; static get historyExplorer() { if (this._historyExplorer === undefined) { - this._context.subscriptions.push(this._historyExplorer = new HistoryExplorer()); + this._context.subscriptions.push((this._historyExplorer = new HistoryExplorer())); } return this._historyExplorer; @@ -144,7 +147,7 @@ export class Container { private static _resultsExplorer: ResultsExplorer | undefined; static get resultsExplorer() { if (this._resultsExplorer === undefined) { - this._context.subscriptions.push(this._resultsExplorer = new ResultsExplorer()); + this._context.subscriptions.push((this._resultsExplorer = new ResultsExplorer())); } return this._resultsExplorer; diff --git a/src/extension.ts b/src/extension.ts index 122367e..6cfa45c 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,7 +3,17 @@ import { Logger } from './logger'; import { Versions } from './system'; import { commands, ExtensionContext, extensions, window, workspace } from 'vscode'; -import { CodeLensLanguageScope, CodeLensScopes, configuration, Configuration, HighlightLocations, IConfig, IMenuConfig, KeyMap, OutputLevel } from './configuration'; +import { + CodeLensLanguageScope, + CodeLensScopes, + configuration, + Configuration, + HighlightLocations, + IConfig, + IMenuConfig, + KeyMap, + OutputLevel +} from './configuration'; import { CommandContext, extensionId, extensionQualifiedId, GlobalState, setCommandContext } from './constants'; import { Commands, configureCommands } from './commands'; import { Container } from './container'; @@ -50,7 +60,7 @@ export async function activate(context: ExtensionContext) { gitPath = await (gitExtension.exports as GitApi).getGitPath(); } } - catch { } + catch {} } await GitService.initialize(gitPath || workspace.getConfiguration('git').get<string>('path')); @@ -58,7 +68,11 @@ export async function activate(context: ExtensionContext) { catch (ex) { Logger.error(ex, `GitLens(v${gitlensVersion}).activate`); if (ex.message.includes('Unable to find git')) { - await window.showErrorMessage(`GitLens was unable to find Git. Please make sure Git is installed. Also ensure that Git is either in the PATH, or that '${extensionId}.${configuration.name('advanced')('git').value}' is pointed to its installed location.`); + await window.showErrorMessage( + `GitLens was unable to find Git. Please make sure Git is installed. Also ensure that Git is either in the PATH, or that '${extensionId}.${ + configuration.name('advanced')('git').value + }' is pointed to its installed location.` + ); } setCommandContext(CommandContext.Enabled, false); return; @@ -87,10 +101,10 @@ export async function activate(context: ExtensionContext) { // Telemetry.trackEvent('initialized', Objects.flatten(cfg, 'config', true)); const duration = process.hrtime(start); - Logger.log(`GitLens(v${gitlensVersion}) activated in ${(duration[0] * 1000) + Math.floor(duration[1] / 1000000)} ms`); + Logger.log(`GitLens(v${gitlensVersion}) activated in ${duration[0] * 1000 + Math.floor(duration[1] / 1000000)} ms`); } -export function deactivate() { } +export function deactivate() {} async function migrateSettings(context: ExtensionContext, previousVersion: string | undefined) { if (previousVersion === undefined) return; @@ -99,215 +113,384 @@ async function migrateSettings(context: ExtensionContext, previousVersion: strin try { if (Versions.compare(previous, Versions.from(7, 5, 10)) !== 1) { - await configuration.migrate('annotations.file.gutter.gravatars', configuration.name('blame')('avatars').value); - await configuration.migrate('annotations.file.gutter.compact', configuration.name('blame')('compact').value); - await configuration.migrate('annotations.file.gutter.dateFormat', configuration.name('blame')('dateFormat').value); + await configuration.migrate( + 'annotations.file.gutter.gravatars', + configuration.name('blame')('avatars').value + ); + await configuration.migrate( + 'annotations.file.gutter.compact', + configuration.name('blame')('compact').value + ); + await configuration.migrate( + 'annotations.file.gutter.dateFormat', + configuration.name('blame')('dateFormat').value + ); await configuration.migrate('annotations.file.gutter.format', configuration.name('blame')('format').value); - await configuration.migrate('annotations.file.gutter.heatmap.enabled', configuration.name('blame')('heatmap')('enabled').value); - await configuration.migrate('annotations.file.gutter.heatmap.location', configuration.name('blame')('heatmap')('location').value); - await configuration.migrate('annotations.file.gutter.lineHighlight.enabled', configuration.name('blame')('highlight')('enabled').value); - await configuration.migrate('annotations.file.gutter.lineHighlight.locations', configuration.name('blame')('highlight')('locations').value); - await configuration.migrate('annotations.file.gutter.separateLines', configuration.name('blame')('separateLines').value); + await configuration.migrate( + 'annotations.file.gutter.heatmap.enabled', + configuration.name('blame')('heatmap')('enabled').value + ); + await configuration.migrate( + 'annotations.file.gutter.heatmap.location', + configuration.name('blame')('heatmap')('location').value + ); + await configuration.migrate( + 'annotations.file.gutter.lineHighlight.enabled', + configuration.name('blame')('highlight')('enabled').value + ); + await configuration.migrate( + 'annotations.file.gutter.lineHighlight.locations', + configuration.name('blame')('highlight')('locations').value + ); + await configuration.migrate( + 'annotations.file.gutter.separateLines', + configuration.name('blame')('separateLines').value + ); await configuration.migrate('codeLens.locations', configuration.name('codeLens')('scopes').value); - await configuration.migrate<{ customSymbols?: string[], language: string | undefined, locations: CodeLensScopes[] }[], CodeLensLanguageScope[]>( - 'codeLens.perLanguageLocations', configuration.name('codeLens')('scopesByLanguage').value, { - migrationFn: v => { - const scopes = v.map(ls => { - return { - language: ls.language, - scopes: ls.locations, - symbolScopes: ls.customSymbols - }; - }); - return scopes; - } - }); - await configuration.migrate('codeLens.customLocationSymbols', configuration.name('codeLens')('symbolScopes').value); - - await configuration.migrate('annotations.line.trailing.dateFormat', configuration.name('currentLine')('dateFormat').value); + await configuration.migrate< + { customSymbols?: string[]; language: string | undefined; locations: CodeLensScopes[] }[], + CodeLensLanguageScope[] + >('codeLens.perLanguageLocations', configuration.name('codeLens')('scopesByLanguage').value, { + migrationFn: v => { + const scopes = v.map(ls => { + return { + language: ls.language, + scopes: ls.locations, + symbolScopes: ls.customSymbols + }; + }); + return scopes; + } + }); + await configuration.migrate( + 'codeLens.customLocationSymbols', + configuration.name('codeLens')('symbolScopes').value + ); + + await configuration.migrate( + 'annotations.line.trailing.dateFormat', + configuration.name('currentLine')('dateFormat').value + ); await configuration.migrate('blame.line.enabled', configuration.name('currentLine')('enabled').value); - await configuration.migrate('annotations.line.trailing.format', configuration.name('currentLine')('format').value); - - await configuration.migrate('annotations.file.gutter.hover.changes', configuration.name('hovers')('annotations')('changes').value); - await configuration.migrate('annotations.file.gutter.hover.details', configuration.name('hovers')('annotations')('details').value); - await configuration.migrate('annotations.file.gutter.hover.details', configuration.name('hovers')('annotations')('enabled').value); + await configuration.migrate( + 'annotations.line.trailing.format', + configuration.name('currentLine')('format').value + ); + + await configuration.migrate( + 'annotations.file.gutter.hover.changes', + configuration.name('hovers')('annotations')('changes').value + ); + await configuration.migrate( + 'annotations.file.gutter.hover.details', + configuration.name('hovers')('annotations')('details').value + ); + await configuration.migrate( + 'annotations.file.gutter.hover.details', + configuration.name('hovers')('annotations')('enabled').value + ); await configuration.migrate<boolean, 'line' | 'annotation'>( - 'annotations.file.gutter.hover.wholeLine', configuration.name('hovers')('annotations')('over').value, - { migrationFn: v => v ? 'line' : 'annotation' }); - - await configuration.migrate('annotations.line.trailing.hover.changes', configuration.name('hovers')('currentLine')('changes').value); - await configuration.migrate('annotations.line.trailing.hover.details', configuration.name('hovers')('currentLine')('details').value); - await configuration.migrate('blame.line.enabled', configuration.name('hovers')('currentLine')('enabled').value); + 'annotations.file.gutter.hover.wholeLine', + configuration.name('hovers')('annotations')('over').value, + { migrationFn: v => (v ? 'line' : 'annotation') } + ); + + await configuration.migrate( + 'annotations.line.trailing.hover.changes', + configuration.name('hovers')('currentLine')('changes').value + ); + await configuration.migrate( + 'annotations.line.trailing.hover.details', + configuration.name('hovers')('currentLine')('details').value + ); + await configuration.migrate( + 'blame.line.enabled', + configuration.name('hovers')('currentLine')('enabled').value + ); await configuration.migrate<boolean, 'line' | 'annotation'>( - 'annotations.line.trailing.hover.wholeLine', configuration.name('hovers')('currentLine')('over').value, - { migrationFn: v => v ? 'line' : 'annotation' }); + 'annotations.line.trailing.hover.wholeLine', + configuration.name('hovers')('currentLine')('over').value, + { migrationFn: v => (v ? 'line' : 'annotation') } + ); await configuration.migrate('gitExplorer.gravatars', configuration.name('explorers')('avatars').value); - await configuration.migrate('gitExplorer.commitFileFormat', configuration.name('explorers')('commitFileFormat').value); - await configuration.migrate('gitExplorer.commitFormat', configuration.name('explorers')('commitFormat').value); - await configuration.migrate('gitExplorer.stashFileFormat', configuration.name('explorers')('stashFileFormat').value); - await configuration.migrate('gitExplorer.stashFormat', configuration.name('explorers')('stashFormat').value); - await configuration.migrate('gitExplorer.statusFileFormat', configuration.name('explorers')('statusFileFormat').value); - - await configuration.migrate('recentChanges.file.lineHighlight.locations', configuration.name('recentChanges')('highlight')('locations').value); + await configuration.migrate( + 'gitExplorer.commitFileFormat', + configuration.name('explorers')('commitFileFormat').value + ); + await configuration.migrate( + 'gitExplorer.commitFormat', + configuration.name('explorers')('commitFormat').value + ); + await configuration.migrate( + 'gitExplorer.stashFileFormat', + configuration.name('explorers')('stashFileFormat').value + ); + await configuration.migrate( + 'gitExplorer.stashFormat', + configuration.name('explorers')('stashFormat').value + ); + await configuration.migrate( + 'gitExplorer.statusFileFormat', + configuration.name('explorers')('statusFileFormat').value + ); + + await configuration.migrate( + 'recentChanges.file.lineHighlight.locations', + configuration.name('recentChanges')('highlight')('locations').value + ); } if (Versions.compare(previous, Versions.from(8, 0, 0, 'beta2')) !== 1) { - await configuration.migrate<boolean, OutputLevel>( - 'debug', configuration.name('outputLevel').value, - { migrationFn: v => v ? OutputLevel.Debug : configuration.get<OutputLevel>(configuration.name('outputLevel').value) }); + await configuration.migrate<boolean, OutputLevel>('debug', configuration.name('outputLevel').value, { + migrationFn: v => + v ? OutputLevel.Debug : configuration.get<OutputLevel>(configuration.name('outputLevel').value) + }); await configuration.migrate('debug', configuration.name('debug').value, { migrationFn: v => undefined }); } if (Versions.compare(previous, Versions.from(8, 0, 0, 'rc')) !== 1) { let section = configuration.name('blame')('highlight')('locations').value; - await configuration.migrate<('gutter' | 'line' | 'overviewRuler')[], HighlightLocations[]>(section, section, { - migrationFn: v => { - const index = v.indexOf('overviewRuler'); - if (index !== -1) { - v.splice(index, 1, 'overview' as 'overviewRuler'); + await configuration.migrate<('gutter' | 'line' | 'overviewRuler')[], HighlightLocations[]>( + section, + section, + { + migrationFn: v => { + const index = v.indexOf('overviewRuler'); + if (index !== -1) { + v.splice(index, 1, 'overview' as 'overviewRuler'); + } + return v as HighlightLocations[]; } - return v as HighlightLocations[]; } - }); + ); section = configuration.name('recentChanges')('highlight')('locations').value; - await configuration.migrate<('gutter' | 'line' | 'overviewRuler')[], HighlightLocations[]>(section, section, { - migrationFn: v => { - const index = v.indexOf('overviewRuler'); - if (index !== -1) { - v.splice(index, 1, 'overview' as 'overviewRuler'); + await configuration.migrate<('gutter' | 'line' | 'overviewRuler')[], HighlightLocations[]>( + section, + section, + { + migrationFn: v => { + const index = v.indexOf('overviewRuler'); + if (index !== -1) { + v.splice(index, 1, 'overview' as 'overviewRuler'); + } + return v as HighlightLocations[]; } - return v as HighlightLocations[]; } - }); + ); } if (Versions.compare(previous, Versions.from(8, 0, 0)) !== 1) { - await configuration.migrateIfMissing('annotations.file.gutter.gravatars', configuration.name('blame')('avatars').value); - await configuration.migrateIfMissing('annotations.file.gutter.compact', configuration.name('blame')('compact').value); - await configuration.migrateIfMissing('annotations.file.gutter.dateFormat', configuration.name('blame')('dateFormat').value); - await configuration.migrateIfMissing('annotations.file.gutter.format', configuration.name('blame')('format').value); - await configuration.migrateIfMissing('annotations.file.gutter.heatmap.enabled', configuration.name('blame')('heatmap')('enabled').value); - await configuration.migrateIfMissing('annotations.file.gutter.heatmap.location', configuration.name('blame')('heatmap')('location').value); - await configuration.migrateIfMissing('annotations.file.gutter.lineHighlight.enabled', configuration.name('blame')('highlight')('enabled').value); - await configuration.migrateIfMissing('annotations.file.gutter.lineHighlight.locations', configuration.name('blame')('highlight')('locations').value); - await configuration.migrateIfMissing('annotations.file.gutter.separateLines', configuration.name('blame')('separateLines').value); + await configuration.migrateIfMissing( + 'annotations.file.gutter.gravatars', + configuration.name('blame')('avatars').value + ); + await configuration.migrateIfMissing( + 'annotations.file.gutter.compact', + configuration.name('blame')('compact').value + ); + await configuration.migrateIfMissing( + 'annotations.file.gutter.dateFormat', + configuration.name('blame')('dateFormat').value + ); + await configuration.migrateIfMissing( + 'annotations.file.gutter.format', + configuration.name('blame')('format').value + ); + await configuration.migrateIfMissing( + 'annotations.file.gutter.heatmap.enabled', + configuration.name('blame')('heatmap')('enabled').value + ); + await configuration.migrateIfMissing( + 'annotations.file.gutter.heatmap.location', + configuration.name('blame')('heatmap')('location').value + ); + await configuration.migrateIfMissing( + 'annotations.file.gutter.lineHighlight.enabled', + configuration.name('blame')('highlight')('enabled').value + ); + await configuration.migrateIfMissing( + 'annotations.file.gutter.lineHighlight.locations', + configuration.name('blame')('highlight')('locations').value + ); + await configuration.migrateIfMissing( + 'annotations.file.gutter.separateLines', + configuration.name('blame')('separateLines').value + ); await configuration.migrateIfMissing('codeLens.locations', configuration.name('codeLens')('scopes').value); - await configuration.migrateIfMissing<{ customSymbols?: string[], language: string | undefined, locations: CodeLensScopes[] }[], CodeLensLanguageScope[]>( - 'codeLens.perLanguageLocations', configuration.name('codeLens')('scopesByLanguage').value, { - migrationFn: v => { - const scopes = v.map(ls => { - return { - language: ls.language, - scopes: ls.locations, - symbolScopes: ls.customSymbols - }; - }); - return scopes; - } - }); - await configuration.migrateIfMissing('codeLens.customLocationSymbols', configuration.name('codeLens')('symbolScopes').value); - - await configuration.migrateIfMissing('annotations.line.trailing.dateFormat', configuration.name('currentLine')('dateFormat').value); - await configuration.migrateIfMissing('blame.line.enabled', configuration.name('currentLine')('enabled').value); - await configuration.migrateIfMissing('annotations.line.trailing.format', configuration.name('currentLine')('format').value); - - await configuration.migrateIfMissing('annotations.file.gutter.hover.changes', configuration.name('hovers')('annotations')('changes').value); - await configuration.migrateIfMissing('annotations.file.gutter.hover.details', configuration.name('hovers')('annotations')('details').value); - await configuration.migrateIfMissing('annotations.file.gutter.hover.details', configuration.name('hovers')('annotations')('enabled').value); + await configuration.migrateIfMissing< + { customSymbols?: string[]; language: string | undefined; locations: CodeLensScopes[] }[], + CodeLensLanguageScope[] + >('codeLens.perLanguageLocations', configuration.name('codeLens')('scopesByLanguage').value, { + migrationFn: v => { + const scopes = v.map(ls => { + return { + language: ls.language, + scopes: ls.locations, + symbolScopes: ls.customSymbols + }; + }); + return scopes; + } + }); + await configuration.migrateIfMissing( + 'codeLens.customLocationSymbols', + configuration.name('codeLens')('symbolScopes').value + ); + + await configuration.migrateIfMissing( + 'annotations.line.trailing.dateFormat', + configuration.name('currentLine')('dateFormat').value + ); + await configuration.migrateIfMissing( + 'blame.line.enabled', + configuration.name('currentLine')('enabled').value + ); + await configuration.migrateIfMissing( + 'annotations.line.trailing.format', + configuration.name('currentLine')('format').value + ); + + await configuration.migrateIfMissing( + 'annotations.file.gutter.hover.changes', + configuration.name('hovers')('annotations')('changes').value + ); + await configuration.migrateIfMissing( + 'annotations.file.gutter.hover.details', + configuration.name('hovers')('annotations')('details').value + ); + await configuration.migrateIfMissing( + 'annotations.file.gutter.hover.details', + configuration.name('hovers')('annotations')('enabled').value + ); await configuration.migrateIfMissing<boolean, 'line' | 'annotation'>( - 'annotations.file.gutter.hover.wholeLine', configuration.name('hovers')('annotations')('over').value, - { migrationFn: v => v ? 'line' : 'annotation' }); - - await configuration.migrateIfMissing('annotations.line.trailing.hover.changes', configuration.name('hovers')('currentLine')('changes').value); - await configuration.migrateIfMissing('annotations.line.trailing.hover.details', configuration.name('hovers')('currentLine')('details').value); - await configuration.migrateIfMissing('blame.line.enabled', configuration.name('hovers')('currentLine')('enabled').value); + 'annotations.file.gutter.hover.wholeLine', + configuration.name('hovers')('annotations')('over').value, + { migrationFn: v => (v ? 'line' : 'annotation') } + ); + + await configuration.migrateIfMissing( + 'annotations.line.trailing.hover.changes', + configuration.name('hovers')('currentLine')('changes').value + ); + await configuration.migrateIfMissing( + 'annotations.line.trailing.hover.details', + configuration.name('hovers')('currentLine')('details').value + ); + await configuration.migrateIfMissing( + 'blame.line.enabled', + configuration.name('hovers')('currentLine')('enabled').value + ); await configuration.migrateIfMissing<boolean, 'line' | 'annotation'>( - 'annotations.line.trailing.hover.wholeLine', configuration.name('hovers')('currentLine')('over').value, - { migrationFn: v => v ? 'line' : 'annotation' }); - - await configuration.migrateIfMissing('gitExplorer.gravatars', configuration.name('explorers')('avatars').value); - await configuration.migrateIfMissing('gitExplorer.commitFileFormat', configuration.name('explorers')('commitFileFormat').value); - await configuration.migrateIfMissing('gitExplorer.commitFormat', configuration.name('explorers')('commitFormat').value); - await configuration.migrateIfMissing('gitExplorer.stashFileFormat', configuration.name('explorers')('stashFileFormat').value); - await configuration.migrateIfMissing('gitExplorer.stashFormat', configuration.name('explorers')('stashFormat').value); - await configuration.migrateIfMissing('gitExplorer.statusFileFormat', configuration.name('explorers')('statusFileFormat').value); - - await configuration.migrateIfMissing('recentChanges.file.lineHighlight.locations', configuration.name('recentChanges')('highlight')('locations').value); + 'annotations.line.trailing.hover.wholeLine', + configuration.name('hovers')('currentLine')('over').value, + { migrationFn: v => (v ? 'line' : 'annotation') } + ); + + await configuration.migrateIfMissing( + 'gitExplorer.gravatars', + configuration.name('explorers')('avatars').value + ); + await configuration.migrateIfMissing( + 'gitExplorer.commitFileFormat', + configuration.name('explorers')('commitFileFormat').value + ); + await configuration.migrateIfMissing( + 'gitExplorer.commitFormat', + configuration.name('explorers')('commitFormat').value + ); + await configuration.migrateIfMissing( + 'gitExplorer.stashFileFormat', + configuration.name('explorers')('stashFileFormat').value + ); + await configuration.migrateIfMissing( + 'gitExplorer.stashFormat', + configuration.name('explorers')('stashFormat').value + ); + await configuration.migrateIfMissing( + 'gitExplorer.statusFileFormat', + configuration.name('explorers')('statusFileFormat').value + ); + + await configuration.migrateIfMissing( + 'recentChanges.file.lineHighlight.locations', + configuration.name('recentChanges')('highlight')('locations').value + ); } if (Versions.compare(previous, Versions.from(8, 0, 2)) !== 1) { const section = configuration.name('keymap').value; await configuration.migrate<'standard' | 'chorded' | 'none', KeyMap>(section, section, { fallbackValue: KeyMap.Alternate, - migrationFn: v => v === 'standard' ? KeyMap.Alternate : v as KeyMap + migrationFn: v => (v === 'standard' ? KeyMap.Alternate : (v as KeyMap)) }); } if (Versions.compare(previous, Versions.from(8, 2, 4)) !== 1) { - await configuration.migrate<{ - explorerContext: { - fileDiff: boolean, - history: boolean, - remote: boolean - }, - editorContext: { - blame: boolean, - copy: boolean, - details: boolean, - fileDiff: boolean, - history: boolean, - lineDiff: boolean, - remote: boolean + await configuration.migrate< + { + explorerContext: { + fileDiff: boolean; + history: boolean; + remote: boolean; + }; + editorContext: { + blame: boolean; + copy: boolean; + details: boolean; + fileDiff: boolean; + history: boolean; + lineDiff: boolean; + remote: boolean; + }; + editorTitle: { + blame: boolean; + fileDiff: boolean; + history: boolean; + remote: boolean; + status: boolean; + }; + editorTitleContext: { + blame: boolean; + fileDiff: boolean; + history: boolean; + remote: boolean; + }; }, - editorTitle: { - blame: boolean, - fileDiff: boolean, - history: boolean, - remote: boolean, - status: boolean - }, - editorTitleContext: { - blame: boolean, - fileDiff: boolean, - history: boolean, - remote: boolean + IMenuConfig + >('advanced.menus', configuration.name('menus').value, { + migrationFn: m => { + return { + editor: { + blame: !!m.editorContext.blame, + clipboard: !!m.editorContext.copy, + compare: !!m.editorContext.lineDiff, + details: !!m.editorContext.details, + history: !!m.editorContext.history, + remote: !!m.editorContext.remote + }, + editorGroup: { + blame: !!m.editorTitle.blame, + compare: !!m.editorTitle.fileDiff, + history: !!m.editorTitle.history, + remote: !!m.editorTitle.remote + }, + editorTab: { + compare: !!m.editorTitleContext.fileDiff, + history: !!m.editorTitleContext.history, + remote: !!m.editorTitleContext.remote + }, + explorer: { + compare: !!m.explorerContext.fileDiff, + history: !!m.explorerContext.history, + remote: !!m.explorerContext.remote + } + } as IMenuConfig; } - }, - IMenuConfig>( - 'advanced.menus', configuration.name('menus').value, { - migrationFn: m => { - return { - editor: { - blame: !!m.editorContext.blame, - clipboard: !!m.editorContext.copy, - compare: !!m.editorContext.lineDiff, - details: !!m.editorContext.details, - history: !!m.editorContext.history, - remote: !!m.editorContext.remote - }, - editorGroup: { - blame: !!m.editorTitle.blame, - compare: !!m.editorTitle.fileDiff, - history: !!m.editorTitle.history, - remote: !!m.editorTitle.remote - }, - editorTab: { - compare: !!m.editorTitleContext.fileDiff, - history: !!m.editorTitleContext.history, - remote: !!m.editorTitleContext.remote - }, - explorer: { - compare: !!m.explorerContext.fileDiff, - history: !!m.explorerContext.history, - remote: !!m.explorerContext.remote - } - } as IMenuConfig; - } - }); + }); } } catch (ex) { diff --git a/src/git/formatters/commitFormatter.ts b/src/git/formatters/commitFormatter.ts index d922974..f7bec9d 100644 --- a/src/git/formatters/commitFormatter.ts +++ b/src/git/formatters/commitFormatter.ts @@ -21,7 +21,6 @@ export interface ICommitFormatOptions extends IFormatOptions { } export class CommitFormatter extends Formatter<GitCommit, ICommitFormatOptions> { - private get _ago() { return this._item.fromNow(); } @@ -31,7 +30,8 @@ export class CommitFormatter extends Formatter<GitCommit, ICommitFormatOptions> } private get _agoOrDate() { - const dateStyle = this._options.dateStyle !== undefined ? this._options.dateStyle : Container.config.defaultDateStyle; + const dateStyle = + this._options.dateStyle !== undefined ? this._options.dateStyle : Container.config.defaultDateStyle; return dateStyle === DateStyle.Absolute ? this._date : this._ago; } @@ -92,8 +92,16 @@ export class CommitFormatter extends Formatter<GitCommit, ICommitFormatOptions> static fromTemplate(template: string, commit: GitCommit, dateFormat: string | null): string; static fromTemplate(template: string, commit: GitCommit, options?: ICommitFormatOptions): string; - static fromTemplate(template: string, commit: GitCommit, dateFormatOrOptions?: string | null | ICommitFormatOptions): string; - static fromTemplate(template: string, commit: GitCommit, dateFormatOrOptions?: string | null | ICommitFormatOptions): string { + static fromTemplate( + template: string, + commit: GitCommit, + dateFormatOrOptions?: string | null | ICommitFormatOptions + ): string; + static fromTemplate( + template: string, + commit: GitCommit, + dateFormatOrOptions?: string | null | ICommitFormatOptions + ): string { return super.fromTemplateCore(this, template, commit, dateFormatOrOptions); } -} \ No newline at end of file +} diff --git a/src/git/formatters/formatter.ts b/src/git/formatters/formatter.ts index bb3de2a..701ed79 100644 --- a/src/git/formatters/formatter.ts +++ b/src/git/formatters/formatter.ts @@ -9,7 +9,6 @@ export interface IFormatOptions { type Constructor<T = {}> = new (...args: any[]) => T; export abstract class Formatter<TItem = any, TOptions extends IFormatOptions = IFormatOptions> { - protected _item!: TItem; protected _options!: TOptions; @@ -88,16 +87,27 @@ export abstract class Formatter<TItem = any, TOptions extends IFormatOptions = I private static _formatter: Formatter | undefined = undefined; - protected static fromTemplateCore<TFormatter extends Formatter<TItem, TOptions>, TItem, TOptions extends IFormatOptions>(formatter: TFormatter | Constructor<TFormatter>, template: string, item: TItem, dateFormatOrOptions?: string | null | TOptions): string { + protected static fromTemplateCore< + TFormatter extends Formatter<TItem, TOptions>, + TItem, + TOptions extends IFormatOptions + >( + formatter: TFormatter | Constructor<TFormatter>, + template: string, + item: TItem, + dateFormatOrOptions?: string | null | TOptions + ): string { if (formatter instanceof Formatter) return Strings.interpolate(template, formatter); let options: TOptions | undefined = undefined; if (dateFormatOrOptions == null || typeof dateFormatOrOptions === 'string') { - const tokenOptions = Strings.getTokensFromTemplate(template) - .reduce((map, token) => { + const tokenOptions = Strings.getTokensFromTemplate(template).reduce( + (map, token) => { map[token.key] = token.options; return map; - }, {} as { [token: string]: Strings.ITokenOptions | undefined }); + }, + {} as { [token: string]: Strings.ITokenOptions | undefined } + ); options = { dateFormat: dateFormatOrOptions, @@ -117,4 +127,4 @@ export abstract class Formatter<TItem = any, TOptions extends IFormatOptions = I return Strings.interpolate(template, this._formatter); } -} \ No newline at end of file +} diff --git a/src/git/formatters/statusFormatter.ts b/src/git/formatters/statusFormatter.ts index 3871a14..c78be82 100644 --- a/src/git/formatters/statusFormatter.ts +++ b/src/git/formatters/statusFormatter.ts @@ -18,7 +18,6 @@ export interface IStatusFormatOptions extends IFormatOptions { } export class StatusFileFormatter extends Formatter<IGitStatusFile, IStatusFormatOptions> { - get directory() { const directory = GitStatusFile.getFormattedDirectory(this._item, false, this._options.relativePath); return this._padOrTruncate(directory, this._options.tokenOptions!.file); @@ -46,13 +45,21 @@ export class StatusFileFormatter extends Formatter<IGitStatusFile, IStatusFormat get working() { const commit = (this._item as IGitStatusFileWithCommit).commit; - return (commit !== undefined && commit.isUncommitted) ? `${GlyphChars.Pencil} ${GlyphChars.Space}` : ''; + return commit !== undefined && commit.isUncommitted ? `${GlyphChars.Pencil} ${GlyphChars.Space}` : ''; } static fromTemplate(template: string, status: IGitStatusFile, dateFormat: string | null): string; static fromTemplate(template: string, status: IGitStatusFile, options?: IStatusFormatOptions): string; - static fromTemplate(template: string, status: IGitStatusFile, dateFormatOrOptions?: string | null | IStatusFormatOptions): string; - static fromTemplate(template: string, status: IGitStatusFile, dateFormatOrOptions?: string | null | IStatusFormatOptions): string { + static fromTemplate( + template: string, + status: IGitStatusFile, + dateFormatOrOptions?: string | null | IStatusFormatOptions + ): string; + static fromTemplate( + template: string, + status: IGitStatusFile, + dateFormatOrOptions?: string | null | IStatusFormatOptions + ): string { return super.fromTemplateCore(this, template, status, dateFormatOrOptions); } -} \ No newline at end of file +} diff --git a/src/git/git.ts b/src/git/git.ts index 246a3f5..4a86a40 100644 --- a/src/git/git.ts +++ b/src/git/git.ts @@ -23,13 +23,13 @@ const sl = '%x2f'; // `%x${'/'.charCodeAt(0).toString(16)}`; const logFormat = [ `${lb}${sl}f${rb}`, - `${lb}r${rb} %H`, // ref - `${lb}a${rb} %an`, // author - `${lb}e${rb} %ae`, // email - `${lb}d${rb} %at`, // date - `${lb}p${rb} %P`, // parents + `${lb}r${rb} %H`, // ref + `${lb}a${rb} %an`, // author + `${lb}e${rb} %ae`, // email + `${lb}d${rb} %at`, // date + `${lb}p${rb} %P`, // parents `${lb}s${rb}`, - `%B`, // summary + `%B`, // summary `${lb}${sl}s${rb}`, `${lb}f${rb}` ].join('%n'); @@ -38,11 +38,11 @@ const defaultLogParams = ['log', '--name-status', '-M', `--format=${logFormat}`] const stashFormat = [ `${lb}${sl}f${rb}`, - `${lb}r${rb} %H`, // ref - `${lb}d${rb} %at`, // date - `${lb}l${rb} %gd`, // reflog-selector + `${lb}r${rb} %H`, // ref + `${lb}d${rb} %at`, // date + `${lb}l${rb} %gd`, // reflog-selector `${lb}s${rb}`, - `%B`, // summary + `%B`, // summary `${lb}${sl}s${rb}`, `${lb}f${rb}` ].join('%n'); @@ -62,10 +62,14 @@ const GitWarnings = { foundButNotInRevision: /Path \'.*?\' exists on disk, but not in/i, headNotABranch: /HEAD does not point to a branch/i, noUpstream: /no upstream configured for branch \'(.*?)\'/i, + // tslint:disable-next-line:max-line-length unknownRevision: /ambiguous argument \'.*?\': unknown revision or path not in the working tree|not stored as a remote-tracking branch/i }; -async function gitCommand(options: CommandOptions & { readonly correlationKey?: string }, ...args: any[]): Promise<string> { +async function gitCommand( + options: CommandOptions & { readonly correlationKey?: string }, + ...args: any[] +): Promise<string> { try { return await gitCommandCore(options, ...args); } @@ -77,7 +81,10 @@ async function gitCommand(options: CommandOptions & { readonly correlationKey?: // A map of running git commands -- avoids running duplicate overlaping commands const pendingCommands: Map<string, Promise<string>> = new Map(); -async function gitCommandCore(options: CommandOptions & { readonly correlationKey?: string }, ...args: any[]): Promise<string> { +async function gitCommandCore( + options: CommandOptions & { readonly correlationKey?: string }, + ...args: any[] +): Promise<string> { const start = process.hrtime(); const { correlationKey, ...opts } = options; @@ -122,7 +129,8 @@ async function gitCommandCore(options: CommandOptions & { readonly correlationKe pendingCommands.delete(command); const duration = process.hrtime(start); - const completedIn = `${exception === undefined ? 'Completed' : 'FAILED'} in ${(duration[0] * 1000) + Math.floor(duration[1] / 1000000)} ms`; + const completedIn = `${exception === undefined ? 'Completed' : 'FAILED'} in ${duration[0] * 1000 + + Math.floor(duration[1] / 1000000)} ms`; Logger.log(`${exception === undefined ? 'Completed' : 'FAILED'}${command} ${completedIn}`); Logger.logGitCommand(`${gitCommand} ${completedIn}`, runOpts.cwd!, exception); @@ -149,7 +157,6 @@ function gitCommandDefaultErrorHandler(ex: Error, options: CommandOptions, ...ar } export class Git { - static shaRegex = /^[0-9a-f]{40}(\^[0-9]*?)??( -)?$/; static shaStrictRegex = /^[0-9a-f]{40}$/; static stagedUncommittedRegex = /^[0]{40}(\^[0-9]*?)??:$/; @@ -162,9 +169,7 @@ export class Git { } static getEncoding(encoding: string | undefined) { - return (encoding !== undefined && iconv.encodingExists(encoding)) - ? encoding - : 'utf8'; + return encoding !== undefined && iconv.encodingExists(encoding) ? encoding : 'utf8'; } static async getGitInfo(gitPath?: string): Promise<IGit> { @@ -173,7 +178,10 @@ export class Git { git = await findGitPath(gitPath); const duration = process.hrtime(start); - Logger.log(`Git found: ${git.version} @ ${git.path === 'git' ? 'PATH' : git.path} in ${(duration[0] * 1000) + Math.floor(duration[1] / 1000000)} ms`); + Logger.log( + `Git found: ${git.version} @ ${git.path === 'git' ? 'PATH' : git.path} in ${duration[0] * 1000 + + Math.floor(duration[1] / 1000000)} ms` + ); return git; } @@ -186,12 +194,17 @@ export class Git { ref = ''; } - const suffix = Strings.truncate(Strings.sanitizeForFileSystem(Git.isSha(ref) ? Git.shortenSha(ref)! : ref), 50, ''); + const suffix = Strings.truncate( + Strings.sanitizeForFileSystem(Git.isSha(ref) ? Git.shortenSha(ref)! : ref), + 50, + '' + ); const ext = path.extname(fileName); const tmp = await import('tmp'); return new Promise<string>((resolve, reject) => { - tmp.file({ prefix: `${path.basename(fileName, ext)}-${suffix}__`, postfix: ext }, + tmp.file( + { prefix: `${path.basename(fileName, ext)}-${suffix}__`, postfix: ext }, (err, destination, fd, cleanupCallback) => { if (err) { reject(err); @@ -210,7 +223,8 @@ export class Git { resolve(destination); }); }); - }); + } + ); }); } @@ -230,7 +244,10 @@ export class Git { return sha === undefined ? false : Git.uncommittedRegex.test(sha); } - static shortenSha(sha: string, strings: { stagedUncommitted?: string, uncommitted?: string, working?: string } = {}) { + static shortenSha( + sha: string, + strings: { stagedUncommitted?: string; uncommitted?: string; working?: string } = {} + ) { strings = { stagedUncommitted: 'index', uncommitted: 'working', working: '', ...strings }; if (sha === '') return strings.working; @@ -261,17 +278,22 @@ export class Git { fileName = Strings.normalizePath(extract ? path.basename(fileName) : fileName); } - return [ fileName, repoPath ]; + return [fileName, repoPath]; } static validateVersion(major: number, minor: number): boolean { const [gitMajor, gitMinor] = git.version.split('.'); - return (parseInt(gitMajor, 10) >= major && parseInt(gitMinor, 10) >= minor); + return parseInt(gitMajor, 10) >= major && parseInt(gitMinor, 10) >= minor; } // Git commands - static async blame(repoPath: string | undefined, fileName: string, sha?: string, options: { args?: string[] | null, ignoreWhitespace?: boolean, startLine?: number, endLine?: number } = {}) { + static async blame( + repoPath: string | undefined, + fileName: string, + sha?: string, + options: { args?: string[] | null; ignoreWhitespace?: boolean; startLine?: number; endLine?: number } = {} + ) { const [file, root] = Git.splitPath(fileName, repoPath); const params = [...defaultBlameParams]; @@ -303,7 +325,18 @@ export class Git { return gitCommand({ cwd: root, stdin: stdin }, ...params, '--', file); } - static async blame_contents(repoPath: string | undefined, fileName: string, contents: string, options: { args?: string[] | null, correlationKey?: string, ignoreWhitespace?: boolean, startLine?: number, endLine?: number } = {}) { + static async blame_contents( + repoPath: string | undefined, + fileName: string, + contents: string, + options: { + args?: string[] | null; + correlationKey?: string; + ignoreWhitespace?: boolean; + startLine?: number; + endLine?: number; + } = {} + ) { const [file, root] = Git.splitPath(fileName, repoPath); const params = [...defaultBlameParams]; @@ -321,7 +354,12 @@ export class Git { // Pipe the blame contents to stdin params.push('--contents', '-'); - return gitCommand({ cwd: root, stdin: contents, correlationKey: options.correlationKey }, ...params, '--', file); + return gitCommand( + { cwd: root, stdin: contents, correlationKey: options.correlationKey }, + ...params, + '--', + file + ); } static branch(repoPath: string, options: { all: boolean } = { all: false }) { @@ -413,7 +451,7 @@ export class Git { return gitCommand({ cwd: repoPath }, ...params); } - static log(repoPath: string, options: { maxCount?: number, ref?: string, reverse?: boolean }) { + static log(repoPath: string, options: { maxCount?: number; ref?: string; reverse?: boolean }) { const params = [...defaultLogParams, '--full-history', '-m']; if (options.maxCount && !options.reverse) { params.push(`-n${options.maxCount}`); @@ -429,7 +467,18 @@ export class Git { return gitCommand({ cwd: repoPath }, ...params, '--'); } - static log_file(repoPath: string, fileName: string, options: { maxCount?: number, ref?: string, renames?: boolean, reverse?: boolean, startLine?: number, endLine?: number } = { renames: true, reverse: false }) { + static log_file( + repoPath: string, + fileName: string, + options: { + maxCount?: number; + ref?: string; + renames?: boolean; + reverse?: boolean; + startLine?: number; + endLine?: number; + } = { renames: true, reverse: false } + ) { const [file, root] = Git.splitPath(fileName, repoPath); const params = [...defaultLogParams]; @@ -469,7 +518,16 @@ export class Git { static async log_resolve(repoPath: string, fileName: string, ref: string) { try { - const data = await gitCommandCore({ cwd: repoPath }, 'log', '-M', '-n1', '--format=%H', ref, '--', fileName); + const data = await gitCommandCore( + { cwd: repoPath }, + 'log', + '-M', + '-n1', + '--format=%H', + ref, + '--', + fileName + ); return data.trim(); } catch { @@ -576,7 +634,12 @@ export class Git { } } - static async show(repoPath: string | undefined, fileName: string, ref: string, options: { encoding?: string } = {}): Promise<string | undefined> { + static async show( + repoPath: string | undefined, + fileName: string, + ref: string, + options: { encoding?: string } = {} + ): Promise<string | undefined> { const [file, root] = Git.splitPath(fileName, repoPath); if (Git.isStagedUncommitted(ref)) { @@ -585,9 +648,7 @@ export class Git { if (Git.isUncommitted(ref)) throw new Error(`sha=${ref} is uncommitted`); const opts = { cwd: root, encoding: options.encoding || 'utf8' } as CommandOptions; - const args = ref.endsWith(':') - ? `${ref}./${file}` - : `${ref}:./${file}`; + const args = ref.endsWith(':') ? `${ref}./${file}` : `${ref}:./${file}`; try { const data = await gitCommandCore(opts, 'show', args, '--'); @@ -599,9 +660,13 @@ export class Git { return Git.show(repoPath, fileName, 'HEAD:', options); } - if (GitErrors.badRevision.test(msg) || + if ( + GitErrors.badRevision.test(msg) || GitWarnings.notFound.test(msg) || - GitWarnings.foundButNotInRevision.test(msg)) return undefined; + GitWarnings.foundButNotInRevision.test(msg) + ) { + return undefined; + } return gitCommandDefaultErrorHandler(ex, opts, args); } @@ -640,14 +705,29 @@ export class Git { static status(repoPath: string, porcelainVersion: number = 1): Promise<string> { const porcelain = porcelainVersion >= 2 ? `--porcelain=v${porcelainVersion}` : '--porcelain'; - return gitCommand({ cwd: repoPath, env: { ...process.env, GIT_OPTIONAL_LOCKS: '0' } }, '-c', 'color.status=false', 'status', porcelain, '--branch', '-u'); + return gitCommand( + { cwd: repoPath, env: { ...process.env, GIT_OPTIONAL_LOCKS: '0' } }, + '-c', + 'color.status=false', + 'status', + porcelain, + '--branch', + '-u' + ); } static status_file(repoPath: string, fileName: string, porcelainVersion: number = 1): Promise<string> { const [file, root] = Git.splitPath(fileName, repoPath); const porcelain = porcelainVersion >= 2 ? `--porcelain=v${porcelainVersion}` : '--porcelain'; - return gitCommand({ cwd: root, env: { ...process.env, GIT_OPTIONAL_LOCKS: '0' } }, '-c', 'color.status=false', 'status', porcelain, file); + return gitCommand( + { cwd: root, env: { ...process.env, GIT_OPTIONAL_LOCKS: '0' } }, + '-c', + 'color.status=false', + 'status', + porcelain, + file + ); } static tag(repoPath: string) { diff --git a/src/git/gitLocator.ts b/src/git/gitLocator.ts index 0d1b4c7..d2ec88e 100644 --- a/src/git/gitLocator.ts +++ b/src/git/gitLocator.ts @@ -69,13 +69,16 @@ export async function findGitPath(path?: string): Promise<IGit> { catch (ex) { try { switch (process.platform) { - case 'darwin': return await findGitDarwin(); - case 'win32': return await findGitWin32(); - default: return Promise.reject('Unable to find git'); + case 'darwin': + return await findGitDarwin(); + case 'win32': + return await findGitWin32(); + default: + return Promise.reject('Unable to find git'); } } catch (ex) { return Promise.reject(new Error('Unable to find git')); } } -} \ No newline at end of file +} diff --git a/src/git/gitUri.ts b/src/git/gitUri.ts index dbc57fd..42dad57 100644 --- a/src/git/gitUri.ts +++ b/src/git/gitUri.ts @@ -23,20 +23,19 @@ interface UriComponents { } interface UriEx { - new(): Uri; - new(scheme: string, authority: string, path: string, query: string, fragment: string): Uri; + new (): Uri; + new (scheme: string, authority: string, path: string, query: string, fragment: string): Uri; // Use this ctor, because vscode doesn't validate it - new(components: UriComponents): Uri; + new (components: UriComponents): Uri; } export class GitUri extends ((Uri as any) as UriEx) { - repoPath?: string; sha?: string; versionedPath?: string; - constructor(uri?: Uri) + constructor(uri?: Uri); constructor(uri: Uri, commit: IGitCommitInfo); constructor(uri: Uri, repoPath: string | undefined); constructor(uri?: Uri, commitOrRepoPath?: IGitCommitInfo | string) { @@ -49,7 +48,10 @@ export class GitUri extends ((Uri as any) as UriEx) { if (uri.scheme === DocumentSchemes.GitLensGit) { const data: IUriRevisionData = JSON.parse(uri.query); - const [authority, fsPath] = GitUri.ensureValidUNCPath(uri.authority, path.resolve(data.repoPath, data.fileName)); + const [authority, fsPath] = GitUri.ensureValidUNCPath( + uri.authority, + path.resolve(data.repoPath, data.fileName) + ); super({ scheme: uri.scheme, authority: authority, path: fsPath, query: uri.query, fragment: uri.fragment }); this.repoPath = data.repoPath; @@ -74,7 +76,10 @@ export class GitUri extends ((Uri as any) as UriEx) { return; } - const [authority, fsPath] = GitUri.ensureValidUNCPath(uri.authority, path.resolve(commitOrRepoPath.repoPath, commitOrRepoPath.fileName || uri.fsPath)); + const [authority, fsPath] = GitUri.ensureValidUNCPath( + uri.authority, + path.resolve(commitOrRepoPath.repoPath, commitOrRepoPath.fileName || uri.fsPath) + ); super({ scheme: uri.scheme, authority: authority, path: fsPath, query: uri.query, fragment: uri.fragment }); this.repoPath = commitOrRepoPath.repoPath; @@ -88,7 +93,7 @@ export class GitUri extends ((Uri as any) as UriEx) { return this.sha && GitService.shortenSha(this.sha); } - fileUri(options: { noSha?: boolean, useVersionedPath?: boolean } = {}) { + fileUri(options: { noSha?: boolean; useVersionedPath?: boolean } = {}) { if (options.useVersionedPath && this.versionedPath !== undefined) return Uri.file(this.versionedPath); return Uri.file(!options.noSha && this.sha ? this.path : this.fsPath); @@ -112,7 +117,7 @@ export class GitUri extends ((Uri as any) as UriEx) { } directory = Strings.normalizePath(directory); - return (!directory || directory === '.') + return !directory || directory === '.' ? path.basename(this.fsPath) : `${path.basename(this.fsPath)}${separator}${directory}`; } @@ -133,7 +138,8 @@ export class GitUri extends ((Uri as any) as UriEx) { if (index === -1) { authority = fsPath.substring(2); fsPath = '\\'; - } else { + } + else { authority = fsPath.substring(2, index); fsPath = fsPath.substring(index) || '\\'; } @@ -153,9 +159,7 @@ export class GitUri extends ((Uri as any) as UriEx) { static fromFileStatus(status: IGitStatusFile, repoPath: string, sha?: string, original: boolean = false): GitUri { const uri = Uri.file(path.resolve(repoPath, (original && status.originalFileName) || status.fileName)); - return sha === undefined - ? new GitUri(uri, repoPath) - : new GitUri(uri, { repoPath: repoPath, sha: sha }); + return sha === undefined ? new GitUri(uri, repoPath) : new GitUri(uri, { repoPath: repoPath, sha: sha }); } static fromRepoPath(repoPath: string, ref?: string) { @@ -177,7 +181,7 @@ export class GitUri extends ((Uri as any) as UriEx) { // If this is a git uri, find its repoPath if (uri.scheme === DocumentSchemes.Git) { - const data: { path: string, ref: string } = JSON.parse(uri.query); + const data: { path: string; ref: string } = JSON.parse(uri.query); const repoPath = await Container.git.getRepoPath(data.path); @@ -216,10 +220,14 @@ export class GitUri extends ((Uri as any) as UriEx) { directory = path.relative(relativeTo, directory); } directory = Strings.normalizePath(directory); - return (!directory || directory === '.') ? '' : directory; + return !directory || directory === '.' ? '' : directory; } - static getFormattedPath(fileNameOrUri: string | Uri, separator: string = Strings.pad(GlyphChars.Dot, 2, 2), relativeTo?: string): string { + static getFormattedPath( + fileNameOrUri: string | Uri, + separator: string = Strings.pad(GlyphChars.Dot, 2, 2), + relativeTo?: string + ): string { let fileName: string; if (fileNameOrUri instanceof Uri) { if (fileNameOrUri instanceof GitUri) return fileNameOrUri.getFormattedPath(separator, relativeTo); @@ -231,9 +239,7 @@ export class GitUri extends ((Uri as any) as UriEx) { } const directory = GitUri.getDirectory(fileName, relativeTo); - return !directory - ? path.basename(fileName) - : `${path.basename(fileName)}${separator}${directory}`; + return !directory ? path.basename(fileName) : `${path.basename(fileName)}${separator}${directory}`; } static getRelativePath(fileNameOrUri: string | Uri, relativeTo?: string, repoPath?: string): string { @@ -258,13 +264,19 @@ export class GitUri extends ((Uri as any) as UriEx) { static toKey(uri: Uri): string; static toKey(fileNameOrUri: string | Uri): string; static toKey(fileNameOrUri: string | Uri): string { - return Strings.normalizePath(typeof fileNameOrUri === 'string' ? fileNameOrUri : fileNameOrUri.fsPath).toLowerCase(); + return Strings.normalizePath( + typeof fileNameOrUri === 'string' ? fileNameOrUri : fileNameOrUri.fsPath + ).toLowerCase(); } static toRevisionUri(uri: GitUri): Uri; static toRevisionUri(sha: string, fileName: string, repoPath: string): Uri; static toRevisionUri(sha: string, status: IGitStatusFile, repoPath: string): Uri; - static toRevisionUri(uriOrSha: string | GitUri, fileNameOrStatus?: string | IGitStatusFile, repoPath?: string): Uri { + static toRevisionUri( + uriOrSha: string | GitUri, + fileNameOrStatus?: string | IGitStatusFile, + repoPath?: string + ): Uri { let fileName: string; let sha: string | undefined; let shortSha: string | undefined; @@ -294,9 +306,12 @@ export class GitUri extends ((Uri as any) as UriEx) { }; const parsed = path.parse(fileName); - return Uri.parse(`${DocumentSchemes.GitLensGit}:${path.join(parsed.dir, parsed.name)}:${shortSha}${parsed.ext}?${JSON.stringify(data)}`); + return Uri.parse( + `${DocumentSchemes.GitLensGit}:${path.join(parsed.dir, parsed.name)}:${shortSha}${ + parsed.ext + }?${JSON.stringify(data)}` + ); } - } interface IUriRevisionData { diff --git a/src/git/models/blame.ts b/src/git/models/blame.ts index c92a958..7a5820b 100644 --- a/src/git/models/blame.ts +++ b/src/git/models/blame.ts @@ -23,4 +23,4 @@ export interface GitBlameCommitLines { readonly author: GitAuthor; readonly commit: GitBlameCommit; readonly lines: GitCommitLine[]; -} \ No newline at end of file +} diff --git a/src/git/models/blameCommit.ts b/src/git/models/blameCommit.ts index 2b84f50..d333e72 100644 --- a/src/git/models/blameCommit.ts +++ b/src/git/models/blameCommit.ts @@ -2,7 +2,6 @@ import { GitCommit, GitCommitLine, GitCommitType } from './commit'; export class GitBlameCommit extends GitCommit { - constructor( repoPath: string, sha: string, @@ -37,7 +36,14 @@ export class GitBlameCommit extends GitCommit { return `${this.sha}^`; } - with(changes: { sha?: string, fileName?: string, originalFileName?: string | null, previousFileName?: string | null, previousSha?: string | null, lines?: GitCommitLine[] | null }): GitBlameCommit { + with(changes: { + sha?: string; + fileName?: string; + originalFileName?: string | null; + previousFileName?: string | null; + previousSha?: string | null; + lines?: GitCommitLine[] | null; + }): GitBlameCommit { return new GitBlameCommit( this.repoPath, changes.sha || this.sha, @@ -49,7 +55,7 @@ export class GitBlameCommit extends GitCommit { this.getChangedValue(changes.originalFileName, this.originalFileName), this.getChangedValue(changes.previousSha, this.previousSha), this.getChangedValue(changes.previousFileName, this.previousFileName), - this.getChangedValue(changes.lines, (changes.sha || changes.fileName) ? [] : this.lines) || [] + this.getChangedValue(changes.lines, changes.sha || changes.fileName ? [] : this.lines) || [] ); } -} \ No newline at end of file +} diff --git a/src/git/models/branch.ts b/src/git/models/branch.ts index 6d6c194..50974b8 100644 --- a/src/git/models/branch.ts +++ b/src/git/models/branch.ts @@ -3,7 +3,6 @@ import { GlyphChars } from '../../constants'; 'use strict'; export class GitBranch { - readonly name: string; readonly remote: boolean; readonly tracking?: string; @@ -30,7 +29,7 @@ export class GitBranch { } this.name = branch; - this.tracking = (tracking === '' || tracking == null) ? undefined : tracking; + this.tracking = tracking === '' || tracking == null ? undefined : tracking; this.state = { ahead: ahead, behind: behind @@ -42,9 +41,7 @@ export class GitBranch { if (this._basename === undefined) { const name = this.getName(); const index = name.lastIndexOf('/'); - this._basename = index !== -1 - ? name.substring(index + 1) - : name; + this._basename = index !== -1 ? name.substring(index + 1) : name; } return this._basename; @@ -53,9 +50,7 @@ export class GitBranch { private _name: string | undefined; getName(): string { if (this._name === undefined) { - this._name = this.remote - ? this.name.substring(this.name.indexOf('/') + 1) - : this.name; + this._name = this.remote ? this.name.substring(this.name.indexOf('/') + 1) : this.name; } return this._name; @@ -68,7 +63,7 @@ export class GitBranch { return undefined; } - getTrackingStatus(options: { empty?: string, expand?: boolean, prefix?: string, separator?: string } = {}): string { + getTrackingStatus(options: { empty?: string; expand?: boolean; prefix?: string; separator?: string } = {}): string { options = { empty: '', prefix: '', separator: ' ', ...options }; if (this.tracking === undefined || (this.state.behind === 0 && this.state.ahead === 0)) return options.empty!; @@ -78,12 +73,16 @@ export class GitBranch { status += `${this.state.behind} ${this.state.behind === 1 ? 'commit' : 'commits'} behind`; } if (this.state.ahead) { - status += `${status === '' ? '' : options.separator}${this.state.ahead} ${this.state.ahead === 1 ? 'commit' : 'commits'} ahead`; + status += `${status === '' ? '' : options.separator}${this.state.ahead} ${ + this.state.ahead === 1 ? 'commit' : 'commits' + } ahead`; } return `${options.prefix}${status}`; } - return `${options.prefix}${this.state.behind}${GlyphChars.ArrowDown}${options.separator}${this.state.ahead}${GlyphChars.ArrowUp}`; + return `${options.prefix}${this.state.behind}${GlyphChars.ArrowDown}${options.separator}${this.state.ahead}${ + GlyphChars.ArrowUp + }`; } isValid(): boolean { @@ -99,4 +98,4 @@ export class GitBranch { // Deals with detached HEAD states return name.match(/\s/) === null; } -} \ No newline at end of file +} diff --git a/src/git/models/commit.ts b/src/git/models/commit.ts index 7a9bc70..aef7ba6 100644 --- a/src/git/models/commit.ts +++ b/src/git/models/commit.ts @@ -45,7 +45,6 @@ export const CommitFormatting = { }; export abstract class GitCommit { - readonly type: GitCommitType; readonly originalFileName: string | undefined; previousFileName: string | undefined; @@ -97,7 +96,11 @@ export abstract class GitCommit { } get isFile() { - return this.type === GitCommitType.Blame || this.type === GitCommitType.File || this.type === GitCommitType.StashFile; + return ( + this.type === GitCommitType.Blame || + this.type === GitCommitType.File || + this.type === GitCommitType.StashFile + ); } get isStash() { @@ -140,7 +143,9 @@ export abstract class GitCommit { } get previousUri(): Uri { - return this.previousFileName ? Uri.file(path.resolve(this.repoPath, (this.previousFileName || this.originalFileName)!)) : this.uri; + return this.previousFileName + ? Uri.file(path.resolve(this.repoPath, (this.previousFileName || this.originalFileName)!)) + : this.uri; } get uri(): Uri { @@ -172,14 +177,16 @@ export abstract class GitCommit { } getGravatarUri(fallback: GravatarDefaultStyle, size: number = 16): Uri { - const key = this.email - ? `${this.email.trim().toLowerCase()}:${size}` - : ''; + const key = this.email ? `${this.email.trim().toLowerCase()}:${size}` : ''; let gravatar = gravatarCache.get(key); if (gravatar !== undefined) return gravatar; - gravatar = Uri.parse(`https://www.gravatar.com/avatar/${this.email ? Strings.md5(this.email, 'hex') : '00000000000000000000000000000000'}.jpg?s=${size}&d=${fallback}`); + gravatar = Uri.parse( + `https://www.gravatar.com/avatar/${ + this.email ? Strings.md5(this.email, 'hex') : '00000000000000000000000000000000' + }.jpg?s=${size}&d=${fallback}` + ); // HACK: Monkey patch Uri.toString to avoid the unwanted query string encoding const originalToStringFn = gravatar.toString; @@ -202,17 +209,28 @@ export abstract class GitCommit { async resolvePreviousFileSha(): Promise<void> { if (this._resolvedPreviousFileSha !== undefined) return; - this._resolvedPreviousFileSha = await Container.git.resolveReference(this.repoPath, this.previousFileSha, this.fileName ? this.previousUri : undefined); + this._resolvedPreviousFileSha = await Container.git.resolveReference( + this.repoPath, + this.previousFileSha, + this.fileName ? this.previousUri : undefined + ); } toGitUri(previous: boolean = false): GitUri { return GitUri.fromCommit(this, previous); } - abstract with(changes: { type?: GitCommitType, sha?: string, fileName?: string, originalFileName?: string | null, previousFileName?: string | null, previousSha?: string | null }): GitCommit; + abstract with(changes: { + type?: GitCommitType; + sha?: string; + fileName?: string; + originalFileName?: string | null; + previousFileName?: string | null; + previousSha?: string | null; + }): GitCommit; protected getChangedValue<T>(change: T | null | undefined, original: T | undefined): T | undefined { if (change === undefined) return original; return change !== null ? change : undefined; } -} \ No newline at end of file +} diff --git a/src/git/models/diff.ts b/src/git/models/diff.ts index 31ec7b6..fa9ea0d 100644 --- a/src/git/models/diff.ts +++ b/src/git/models/diff.ts @@ -11,17 +11,16 @@ export interface GitDiffChunkLine extends GitDiffLine { } export class GitDiffChunk { - private _chunk: string | undefined; private _lines: GitDiffChunkLine[] | undefined; constructor( chunk: string, - public currentPosition: { start: number, end: number }, - public previousPosition: { start: number, end: number } + public currentPosition: { start: number; end: number }, + public previousPosition: { start: number; end: number } ) { this._chunk = chunk; - } + } get lines(): GitDiffChunkLine[] { if (this._lines === undefined) { @@ -43,4 +42,4 @@ export interface GitDiffShortStat { readonly files: number; readonly insertions: number; readonly deletions: number; -} \ No newline at end of file +} diff --git a/src/git/models/log.ts b/src/git/models/log.ts index c4dfe91..0b57650 100644 --- a/src/git/models/log.ts +++ b/src/git/models/log.ts @@ -14,5 +14,5 @@ export interface GitLog { readonly range: Range; readonly truncated: boolean; - query: (maxCount: number | undefined) => Promise<GitLog | undefined>; -} \ No newline at end of file + query(maxCount: number | undefined): Promise<GitLog | undefined>; +} diff --git a/src/git/models/logCommit.ts b/src/git/models/logCommit.ts index e308186..132adf9 100644 --- a/src/git/models/logCommit.ts +++ b/src/git/models/logCommit.ts @@ -7,7 +7,6 @@ import { GitStatusFileStatus, IGitStatusFile } from './status'; import * as path from 'path'; export class GitLogCommit extends GitCommit { - nextSha?: string; nextFileName?: string; @@ -57,9 +56,7 @@ export class GitLogCommit extends GitCommit { get previousFileSha(): string { if (this._resolvedPreviousFileSha !== undefined) return this._resolvedPreviousFileSha; - return (this.isFile && this.previousSha) - ? this.previousSha - : `${this.sha}^`; + return this.isFile && this.previousSha ? this.previousSha : `${this.sha}^`; } getDiffStatus(): string { @@ -99,9 +96,7 @@ export class GitLogCommit extends GitCommit { } // If this isn't a single-file commit, we can't trust the previousSha - const previousSha = this.isFile - ? this.previousSha - : `${this.sha}^`; + const previousSha = this.isFile ? this.previousSha : `${this.sha}^`; return this.with({ type: this.isStash ? GitCommitType.StashFile : GitCommitType.File, @@ -114,7 +109,20 @@ export class GitLogCommit extends GitCommit { }); } - with(changes: { type?: GitCommitType, sha?: string | null, fileName?: string, author?: string, email?: string, date?: Date, message?: string, originalFileName?: string | null, previousFileName?: string | null, previousSha?: string | null, status?: GitStatusFileStatus, fileStatuses?: IGitStatusFile[] | null }): GitLogCommit { + with(changes: { + type?: GitCommitType; + sha?: string | null; + fileName?: string; + author?: string; + email?: string; + date?: Date; + message?: string; + originalFileName?: string | null; + previousFileName?: string | null; + previousSha?: string | null; + status?: GitStatusFileStatus; + fileStatuses?: IGitStatusFile[] | null; + }): GitLogCommit { return new GitLogCommit( changes.type || this.type, this.repoPath, @@ -132,4 +140,4 @@ export class GitLogCommit extends GitCommit { undefined ); } -} \ No newline at end of file +} diff --git a/src/git/models/remote.ts b/src/git/models/remote.ts index 4eaef7d..92363c5 100644 --- a/src/git/models/remote.ts +++ b/src/git/models/remote.ts @@ -7,7 +7,6 @@ export enum GitRemoteType { } export class GitRemote { - constructor( public readonly repoPath: string, public readonly name: string, @@ -15,6 +14,6 @@ export class GitRemote { public readonly domain: string, public readonly path: string, public readonly provider: RemoteProvider | undefined, - public readonly types: { type: GitRemoteType, url: string }[] - ) { } -} \ No newline at end of file + public readonly types: { type: GitRemoteType; url: string }[] + ) {} +} diff --git a/src/git/models/repository.ts b/src/git/models/repository.ts index ace9007..3e36a62 100644 --- a/src/git/models/repository.ts +++ b/src/git/models/repository.ts @@ -1,6 +1,15 @@ 'use strict'; import { Functions } from '../../system'; -import { ConfigurationChangeEvent, Disposable, Event, EventEmitter, RelativePattern, Uri, workspace, WorkspaceFolder } from 'vscode'; +import { + ConfigurationChangeEvent, + Disposable, + Event, + EventEmitter, + RelativePattern, + Uri, + workspace, + WorkspaceFolder +} from 'vscode'; import { configuration, IRemotesConfig } from '../../configuration'; import { Container } from '../../container'; import { GitBranch, GitDiffShortStat, GitRemote, GitStash, GitStatus, GitTag } from '../git'; @@ -19,12 +28,11 @@ export enum RepositoryChange { } export class RepositoryChangeEvent { - readonly changes: RepositoryChange[] = []; constructor( public readonly repository?: Repository - ) { } + ) {} changed(change: RepositoryChange, solely: boolean = false) { if (solely) return this.changes.length === 1 && this.changes[0] === change; @@ -52,7 +60,6 @@ export enum RepositoryStorage { } export class Repository extends Disposable { - private _onDidChange = new EventEmitter<RepositoryChangeEvent>(); get onDidChange(): Event<RepositoryChangeEvent> { return this._onDidChange.event; @@ -75,7 +82,7 @@ export class Repository extends Disposable { private _fireFileSystemChangeDebounced: ((e: RepositoryFileSystemChangeEvent) => void) | undefined = undefined; private _fsWatchCounter = 0; private _fsWatcherDisposable: Disposable | undefined; - private _pendingChanges: { repo?: RepositoryChangeEvent, fs?: RepositoryFileSystemChangeEvent } = { }; + private _pendingChanges: { repo?: RepositoryChangeEvent; fs?: RepositoryFileSystemChangeEvent } = {}; private _providerMap: RemoteProviderMap | undefined; private _remotes: Promise<GitRemote[]> | undefined; private _suspended: boolean; @@ -95,9 +102,7 @@ export class Repository extends Disposable { } else { const relativePath = _path.relative(folder.uri.fsPath, path); - this.formattedName = relativePath - ? `${folder.name} (${relativePath})` - : folder.name; + this.formattedName = relativePath ? `${folder.name} (${relativePath})` : folder.name; } this.index = folder.index; this.name = folder.name; @@ -108,7 +113,21 @@ export class Repository extends Disposable { this._closed = closed; // TODO: createFileSystemWatcher doesn't work unless the folder is part of the workspaceFolders - const watcher = workspace.createFileSystemWatcher(new RelativePattern(folder, '{**/.git/config,**/.git/index,**/.git/HEAD,**/.git/refs/stash,**/.git/refs/heads/**,**/.git/refs/remotes/**,**/.git/refs/tags/**,**/.gitignore}')); + const watcher = workspace.createFileSystemWatcher( + new RelativePattern( + folder, + '{\ +**/.git/config,\ +**/.git/index,\ +**/.git/HEAD,\ +**/.git/refs/stash,\ +**/.git/refs/heads/**,\ +**/.git/refs/remotes/**,\ +**/.git/refs/tags/**,\ +**/.gitignore\ +}' + ) + ); this._disposable = Disposable.from( watcher, watcher.onDidChange(this.onRepositoryChanged, this), @@ -137,7 +156,9 @@ export class Repository extends Disposable { const section = configuration.name('remotes').value; if (initializing || configuration.changed(e, section, this.folder.uri)) { - this._providerMap = RemoteProviderFactory.createMap(configuration.get<IRemotesConfig[] | null | undefined>(section, this.folder.uri)); + this._providerMap = RemoteProviderFactory.createMap( + configuration.get<IRemotesConfig[] | null | undefined>(section, this.folder.uri) + ); if (!initializing) { this._remotes = undefined; @@ -201,9 +222,7 @@ export class Repository extends Disposable { containsUri(uri: Uri) { if (uri instanceof GitUri) { - uri = uri.repoPath !== undefined - ? Uri.file(uri.repoPath) - : uri.fileUri(); + uri = uri.repoPath !== undefined ? Uri.file(uri.repoPath) : uri.fileUri(); } return this.folder === workspace.getWorkspaceFolder(uri); @@ -227,7 +246,10 @@ export class Repository extends Disposable { getRemotes(): Promise<GitRemote[]> { if (this._remotes === undefined) { if (this._providerMap === undefined) { - const remotesCfg = configuration.get<IRemotesConfig[] | null | undefined>(configuration.name('remotes').value, this.folder.uri); + const remotesCfg = configuration.get<IRemotesConfig[] | null | undefined>( + configuration.name('remotes').value, + this.folder.uri + ); this._providerMap = RemoteProviderFactory.createMap(remotesCfg); } @@ -351,5 +373,4 @@ export class Repository extends Disposable { this._onDidChangeFileSystem.fire(e); } - } diff --git a/src/git/models/stash.ts b/src/git/models/stash.ts index 2648f99..de3dfd5 100644 --- a/src/git/models/stash.ts +++ b/src/git/models/stash.ts @@ -4,4 +4,4 @@ import { GitStashCommit } from './stashCommit'; export interface GitStash { readonly repoPath: string; readonly commits: Map<string, GitStashCommit>; -} \ No newline at end of file +} diff --git a/src/git/models/stashCommit.ts b/src/git/models/stashCommit.ts index 1f623d1..907cd6a 100644 --- a/src/git/models/stashCommit.ts +++ b/src/git/models/stashCommit.ts @@ -4,7 +4,6 @@ import { GitLogCommit } from './logCommit'; import { GitStatusFileStatus, IGitStatusFile } from './status'; export class GitStashCommit extends GitLogCommit { - constructor( type: GitCommitType, public readonly stashName: string, @@ -40,7 +39,18 @@ export class GitStashCommit extends GitLogCommit { return this.stashName; } - with(changes: { type?: GitCommitType, sha?: string | null, fileName?: string, date?: Date, message?: string, originalFileName?: string | null, previousFileName?: string | null, previousSha?: string | null, status?: GitStatusFileStatus, fileStatuses?: IGitStatusFile[] | null }): GitLogCommit { + with(changes: { + type?: GitCommitType; + sha?: string | null; + fileName?: string; + date?: Date; + message?: string; + originalFileName?: string | null; + previousFileName?: string | null; + previousSha?: string | null; + status?: GitStatusFileStatus; + fileStatuses?: IGitStatusFile[] | null; + }): GitLogCommit { return new GitStashCommit( changes.type || this.type, this.stashName, @@ -56,4 +66,4 @@ export class GitStashCommit extends GitLogCommit { this.getChangedValue(changes.previousFileName, this.previousFileName) ); } -} \ No newline at end of file +} diff --git a/src/git/models/status.ts b/src/git/models/status.ts index 5d0c71e..c79042f 100644 --- a/src/git/models/status.ts +++ b/src/git/models/status.ts @@ -12,7 +12,6 @@ export interface GitStatusUpstreamState { } export class GitStatus { - constructor( public readonly repoPath: string, public readonly branch: string, @@ -20,15 +19,15 @@ export class GitStatus { public readonly files: GitStatusFile[], public readonly state: GitStatusUpstreamState, public readonly upstream?: string - ) { } + ) {} private _diff?: { - added: number, - deleted: number, - changed: number + added: number; + deleted: number; + changed: number; }; - getDiffStatus(options: { empty?: string, expand?: boolean, prefix?: string, separator?: string } = {}): string { + getDiffStatus(options: { empty?: string; expand?: boolean; prefix?: string; separator?: string } = {}): string { options = { empty: '', prefix: '', separator: ' ', ...options }; if (this.files.length === 0) return options.empty!; @@ -53,7 +52,6 @@ export class GitStatus { break; } } - } if (options.expand) { @@ -62,18 +60,24 @@ export class GitStatus { status += `${this._diff.added} ${this._diff.added === 1 ? 'file' : 'files'} added`; } if (this._diff.changed) { - status += `${status === '' ? '' : options.separator}${this._diff.changed} ${this._diff.changed === 1 ? 'file' : 'files'} changed`; + status += `${status === '' ? '' : options.separator}${this._diff.changed} ${ + this._diff.changed === 1 ? 'file' : 'files' + } changed`; } if (this._diff.deleted) { - status += `${status === '' ? '' : options.separator}${this._diff.deleted} ${this._diff.deleted === 1 ? 'file' : 'files'} deleted`; + status += `${status === '' ? '' : options.separator}${this._diff.deleted} ${ + this._diff.deleted === 1 ? 'file' : 'files' + } deleted`; } return `${options.prefix}${status}`; } - return `${options.prefix}+${this._diff.added}${options.separator}~${this._diff.changed}${options.separator}-${this._diff.deleted}`; + return `${options.prefix}+${this._diff.added}${options.separator}~${this._diff.changed}${options.separator}-${ + this._diff.deleted + }`; } - getUpstreamStatus(options: { empty?: string, expand?: boolean, prefix?: string, separator?: string } = {}): string { + getUpstreamStatus(options: { empty?: string; expand?: boolean; prefix?: string; separator?: string } = {}): string { options = { empty: '', prefix: '', separator: ' ', ...options }; if (this.upstream === undefined || (this.state.behind === 0 && this.state.ahead === 0)) return options.empty!; @@ -83,12 +87,16 @@ export class GitStatus { status += `${this.state.behind} ${this.state.behind === 1 ? 'commit' : 'commits'} behind`; } if (this.state.ahead) { - status += `${status === '' ? '' : options.separator}${this.state.ahead} ${this.state.ahead === 1 ? 'commit' : 'commits'} ahead`; + status += `${status === '' ? '' : options.separator}${this.state.ahead} ${ + this.state.ahead === 1 ? 'commit' : 'commits' + } ahead`; } return `${options.prefix}${status}`; } - return `${options.prefix}${this.state.behind}${GlyphChars.ArrowDown}${options.separator}${this.state.ahead}${GlyphChars.ArrowUp}`; + return `${options.prefix}${this.state.behind}${GlyphChars.ArrowDown}${options.separator}${this.state.ahead}${ + GlyphChars.ArrowUp + }`; } } @@ -107,14 +115,13 @@ export interface IGitStatusFileWithCommit extends IGitStatusFile { } export class GitStatusFile implements IGitStatusFile { - constructor( public readonly repoPath: string, public readonly indexStatus: GitStatusFileStatus, public readonly workTreeStatus: GitStatusFileStatus, public readonly fileName: string, public readonly originalFileName?: string - ) { } + ) {} get status(): GitStatusFileStatus { return (this.indexStatus || this.workTreeStatus || '?') as GitStatusFileStatus; @@ -144,7 +151,12 @@ export class GitStatusFile implements IGitStatusFile { return GitStatusFile.getStatusText(this.status); } - with(changes: { indexStatus?: GitStatusFileStatus | null, workTreeStatus?: GitStatusFileStatus | null, fileName?: string, originalFileName?: string | null }): GitStatusFile { + with(changes: { + indexStatus?: GitStatusFileStatus | null; + workTreeStatus?: GitStatusFileStatus | null; + fileName?: string; + originalFileName?: string | null; + }): GitStatusFile { return new GitStatusFile( this.repoPath, this.getChangedValue(changes.indexStatus, this.indexStatus) as GitStatusFileStatus, @@ -159,14 +171,22 @@ export class GitStatusFile implements IGitStatusFile { return change !== null ? change : undefined; } - static getFormattedDirectory(status: IGitStatusFile, includeOriginal: boolean = false, relativeTo?: string): string { + static getFormattedDirectory( + status: IGitStatusFile, + includeOriginal: boolean = false, + relativeTo?: string + ): string { const directory = GitUri.getDirectory(status.fileName, relativeTo); - return (includeOriginal && status.status === 'R' && status.originalFileName) + return includeOriginal && status.status === 'R' && status.originalFileName ? `${directory} ${Strings.pad(GlyphChars.ArrowLeft, 1, 1)} ${status.originalFileName}` : directory; } - static getFormattedPath(status: IGitStatusFile, separator: string = Strings.pad(GlyphChars.Dot, 2, 2), relativeTo?: string): string { + static getFormattedPath( + status: IGitStatusFile, + separator: string = Strings.pad(GlyphChars.Dot, 2, 2), + relativeTo?: string + ): string { return GitUri.getFormattedPath(status.fileName, separator, relativeTo); } @@ -231,4 +251,4 @@ const statusTextMap = { export function getGitStatusText(status: GitStatusFileStatus): string { return statusTextMap[status] || statusTextMap['X']; -} \ No newline at end of file +} diff --git a/src/git/models/tag.ts b/src/git/models/tag.ts index adb86d7..063b172 100644 --- a/src/git/models/tag.ts +++ b/src/git/models/tag.ts @@ -1,21 +1,18 @@ 'use strict'; export class GitTag { - constructor( public readonly repoPath: string, public readonly name: string - ) { } + ) {} private _basename: string | undefined; getBasename(): string { if (this._basename === undefined) { const index = this.name.lastIndexOf('/'); - this._basename = index !== -1 - ? this.name.substring(index + 1) - : this.name; + this._basename = index !== -1 ? this.name.substring(index + 1) : this.name; } return this._basename; } -} \ No newline at end of file +} diff --git a/src/git/parsers/blameParser.ts b/src/git/parsers/blameParser.ts index 3b2532d..be82760 100644 --- a/src/git/parsers/blameParser.ts +++ b/src/git/parsers/blameParser.ts @@ -24,8 +24,12 @@ interface BlameEntry { } export class GitBlameParser { - - static parse(data: string, repoPath: string | undefined, fileName: string, currentUser: string | undefined): GitBlame | undefined { + static parse( + data: string, + repoPath: string | undefined, + fileName: string, + currentUser: string | undefined + ): GitBlame | undefined { if (!data) return undefined; const authors: Map<string, GitAuthor> = new Map(); @@ -61,7 +65,10 @@ export class GitBlameParser { entry.author = 'You'; } else { - entry.author = lineParts.slice(1).join(' ').trim(); + entry.author = lineParts + .slice(1) + .join(' ') + .trim(); if (currentUser !== undefined && currentUser === entry.author) { entry.author = 'You'; } @@ -69,7 +76,10 @@ export class GitBlameParser { break; case 'author-mail': - entry.authorEmail = lineParts.slice(1).join(' ').trim(); + entry.authorEmail = lineParts + .slice(1) + .join(' ') + .trim(); const start = entry.authorEmail.indexOf('<'); if (start >= 0) { const end = entry.authorEmail.indexOf('>', start); @@ -92,7 +102,10 @@ export class GitBlameParser { break; case 'summary': - entry.summary = lineParts.slice(1).join(' ').trim(); + entry.summary = lineParts + .slice(1) + .join(' ') + .trim(); break; case 'previous': @@ -105,7 +118,9 @@ export class GitBlameParser { if (first && repoPath === undefined) { // Try to get the repoPath from the most recent commit - repoPath = Strings.normalizePath(fileName.replace(fileName.startsWith('/') ? `/${entry.fileName}` : entry.fileName!, '')); + repoPath = Strings.normalizePath( + fileName.replace(fileName.startsWith('/') ? `/${entry.fileName}` : entry.fileName!, '') + ); relativeFileName = Strings.normalizePath(path.relative(repoPath, fileName)); } first = false; @@ -139,7 +154,14 @@ export class GitBlameParser { } as GitBlame; } - private static parseEntry(entry: BlameEntry, repoPath: string | undefined, fileName: string | undefined, commits: Map<string, GitBlameCommit>, authors: Map<string, GitAuthor>, lines: GitCommitLine[]) { + private static parseEntry( + entry: BlameEntry, + repoPath: string | undefined, + fileName: string | undefined, + commits: Map<string, GitBlameCommit>, + authors: Map<string, GitAuthor>, + lines: GitCommitLine[] + ) { let commit = commits.get(entry.sha); if (commit === undefined) { if (entry.author !== undefined) { @@ -158,7 +180,7 @@ export class GitBlameParser { entry.sha, entry.author, entry.authorEmail, - new Date(entry.authorDate as any * 1000), + new Date((entry.authorDate as any) * 1000), entry.summary!, fileName!, fileName !== entry.fileName ? entry.fileName : undefined, @@ -185,4 +207,4 @@ export class GitBlameParser { lines[line.line] = line; } } -} \ No newline at end of file +} diff --git a/src/git/parsers/branchParser.ts b/src/git/parsers/branchParser.ts index 92f08d0..87ead28 100644 --- a/src/git/parsers/branchParser.ts +++ b/src/git/parsers/branchParser.ts @@ -5,7 +5,6 @@ const branchWithTrackingRegex = /^(\*?)\s+(.+?)\s+([0-9,a-f]+)\s+(?:\[(.*?\/.*?) const branchWithTrackingStateRegex = /^(?:ahead\s([0-9]+))?[,\s]*(?:behind\s([0-9]+))?/; export class GitBranchParser { - static parse(data: string, repoPath: string): GitBranch[] | undefined { if (!data) return undefined; @@ -33,9 +32,6 @@ export class GitBranchParser { const ahead = parseInt(match[1], 10); const behind = parseInt(match[2], 10); - return [ - isNaN(ahead) ? 0 : ahead, - isNaN(behind) ? 0 : behind - ]; + return [isNaN(ahead) ? 0 : ahead, isNaN(behind) ? 0 : behind]; } -} \ No newline at end of file +} diff --git a/src/git/parsers/diffParser.ts b/src/git/parsers/diffParser.ts index 17e1df8..f08e1f5 100644 --- a/src/git/parsers/diffParser.ts +++ b/src/git/parsers/diffParser.ts @@ -1,13 +1,21 @@ 'use strict'; import { Iterables, Strings } from '../../system'; -import { GitDiff, GitDiffChunk, GitDiffChunkLine, GitDiffLine, GitDiffShortStat, GitStatusFile, GitStatusParser } from './../git'; +import { + GitDiff, + GitDiffChunk, + GitDiffChunkLine, + GitDiffLine, + GitDiffShortStat, + GitStatusFile, + GitStatusParser +} from './../git'; const nameStatusDiffRegex = /^(.*?)\t(.*?)(?:\t(.*?))?$/gm; +// tslint:disable-next-line:max-line-length const shortStatDiffRegex = /^\s*(\d+)\sfiles? changed(?:,\s+(\d+)\s+insertions?\(\+\))?(?:,\s+(\d+)\s+deletions?\(-\))?/; const unifiedDiffRegex = /^@@ -([\d]+),([\d]+) [+]([\d]+),([\d]+) @@([\s\S]*?)(?=^@@)/gm; export class GitDiffParser { - static parse(data: string, debug: boolean = false): GitDiff | undefined { if (!data) return undefined; @@ -29,7 +37,19 @@ export class GitDiffParser { currentStart = parseInt(match[3], 10); previousStart = parseInt(match[1], 10); - chunks.push(new GitDiffChunk(chunk, { start: currentStart, end: currentStart + parseInt(match[4], 10) }, { start: previousStart, end: previousStart + parseInt(match[2], 10) })); + chunks.push( + new GitDiffChunk( + chunk, + { + start: currentStart, + end: currentStart + parseInt(match[4], 10) + }, + { + start: previousStart, + end: previousStart + parseInt(match[2], 10) + } + ) + ); } while (match != null); if (!chunks.length) return undefined; @@ -152,4 +172,4 @@ export class GitDiffParser { deletions: deletions == null ? 0 : parseInt(deletions, 10) } as GitDiffShortStat; } -} \ No newline at end of file +} diff --git a/src/git/parsers/logParser.ts b/src/git/parsers/logParser.ts index debea43..b26867c 100644 --- a/src/git/parsers/logParser.ts +++ b/src/git/parsers/logParser.ts @@ -27,8 +27,17 @@ const diffRegex = /diff --git a\/(.*) b\/(.*)/; const emptyEntry: LogEntry = {}; export class GitLogParser { - - static parse(data: string, type: GitCommitType, repoPath: string | undefined, fileName: string | undefined, sha: string | undefined, currentUser: string | undefined, maxCount: number | undefined, reverse: boolean, range: Range | undefined): GitLog | undefined { + static parse( + data: string, + type: GitCommitType, + repoPath: string | undefined, + fileName: string | undefined, + sha: string | undefined, + currentUser: string | undefined, + maxCount: number | undefined, + reverse: boolean, + range: Range | undefined + ): GitLog | undefined { if (!data) return undefined; let relativeFileName: string; @@ -60,7 +69,7 @@ export class GitLogParser { line = next.value; // Since log --reverse doesn't properly honor a max count -- enforce it here - if (reverse && maxCount && (i >= maxCount)) break; + if (reverse && maxCount && i >= maxCount) break; // <<1-char token>> <data> // e.g. <r> bd1452a2dc @@ -173,13 +182,17 @@ export class GitLogParser { } if (entry.fileStatuses !== undefined) { - entry.fileName = Arrays.filterMap(entry.fileStatuses, - f => !!f.fileName ? f.fileName : undefined).join(', '); + entry.fileName = Arrays.filterMap( + entry.fileStatuses, + f => (!!f.fileName ? f.fileName : undefined) + ).join(', '); } if (first && repoPath === undefined && type === GitCommitType.File && fileName !== undefined) { // Try to get the repoPath from the most recent commit - repoPath = Strings.normalizePath(fileName.replace(fileName.startsWith('/') ? `/${entry.fileName}` : entry.fileName!, '')); + repoPath = Strings.normalizePath( + fileName.replace(fileName.startsWith('/') ? `/${entry.fileName}` : entry.fileName!, '') + ); relativeFileName = Strings.normalizePath(path.relative(repoPath, fileName)); } else { @@ -191,7 +204,16 @@ export class GitLogParser { if (commit === undefined) { i++; } - recentCommit = GitLogParser.parseEntry(entry, commit, type, repoPath, relativeFileName, commits, authors, recentCommit); + recentCommit = GitLogParser.parseEntry( + entry, + commit, + type, + repoPath, + relativeFileName, + commits, + authors, + recentCommit + ); break; } @@ -209,7 +231,16 @@ export class GitLogParser { } as GitLog; } - private static parseEntry(entry: LogEntry, commit: GitLogCommit | undefined, type: GitCommitType, repoPath: string | undefined, relativeFileName: string, commits: Map<string, GitLogCommit>, authors: Map<string, GitAuthor>, recentCommit: GitLogCommit | undefined): GitLogCommit | undefined { + private static parseEntry( + entry: LogEntry, + commit: GitLogCommit | undefined, + type: GitCommitType, + repoPath: string | undefined, + relativeFileName: string, + commits: Map<string, GitLogCommit>, + authors: Map<string, GitAuthor>, + recentCommit: GitLogCommit | undefined + ): GitLogCommit | undefined { if (commit === undefined) { if (entry.author !== undefined) { let author = authors.get(entry.author); @@ -224,7 +255,13 @@ export class GitLogParser { const originalFileName = relativeFileName !== entry.fileName ? entry.fileName : undefined; if (type === GitCommitType.File) { - entry.fileStatuses = [{ status: entry.status, fileName: relativeFileName, originalFileName: originalFileName } as IGitStatusFile]; + entry.fileStatuses = [ + { + status: entry.status, + fileName: relativeFileName, + originalFileName: originalFileName + } as IGitStatusFile + ]; } commit = new GitLogCommit( @@ -233,7 +270,7 @@ export class GitLogParser { entry.ref!, entry.author!, entry.email, - new Date(entry.date! as any * 1000), + new Date((entry.date! as any) * 1000), entry.summary === undefined ? '' : entry.summary, relativeFileName, entry.fileStatuses || [], @@ -265,7 +302,7 @@ export class GitLogParser { return commit; } - static parseFileName(entry: { fileName?: string, originalFileName?: string }) { + static parseFileName(entry: { fileName?: string; originalFileName?: string }) { if (entry.fileName === undefined) return; const index = entry.fileName.indexOf('\t') + 1; @@ -280,4 +317,4 @@ export class GitLogParser { } } } -} \ No newline at end of file +} diff --git a/src/git/parsers/remoteParser.ts b/src/git/parsers/remoteParser.ts index 988202d..43bbb5a 100644 --- a/src/git/parsers/remoteParser.ts +++ b/src/git/parsers/remoteParser.ts @@ -4,6 +4,7 @@ import { GitRemoteType } from '../models/remote'; import { RemoteProvider } from '../remotes/factory'; const remoteRegex = /^(.*)\t(.*)\s\((.*)\)$/gm; +// tslint:disable-next-line:max-line-length const urlRegex = /^(?:(git:\/\/)(.*?)\/|(https?:\/\/)(?:.*?@)?(.*?)\/|git@(.*):|(ssh:\/\/)(?:.*@)?(.*?)(?::.*?)?\/|(?:.*?@)(.*?):)(.*)$/; // Test git urls @@ -44,8 +45,11 @@ user:password@host.xz:/path/to/repo.git/ */ export class GitRemoteParser { - - static parse(data: string, repoPath: string, providerFactory: (domain: string, path: string) => RemoteProvider | undefined): GitRemote[] { + static parse( + data: string, + repoPath: string, + providerFactory: (domain: string, path: string) => RemoteProvider | undefined + ): GitRemote[] { if (!data) return []; const remotes: GitRemote[] = []; @@ -63,7 +67,9 @@ export class GitRemoteParser { const uniqueness = `${domain}/${path}`; let remote: GitRemote | undefined = groups[uniqueness]; if (remote === undefined) { - remote = new GitRemote(repoPath, match[1], scheme, domain, path, providerFactory(domain, path), [{ url: url, type: match[3] as GitRemoteType }]); + remote = new GitRemote(repoPath, match[1], scheme, domain, path, providerFactory(domain, path), [ + { url: url, type: match[3] as GitRemoteType } + ]); remotes.push(remote); groups[uniqueness] = remote; } @@ -87,4 +93,4 @@ export class GitRemoteParser { match[9].replace(/\.git\/?$/, '') ]; } -} \ No newline at end of file +} diff --git a/src/git/parsers/stashParser.ts b/src/git/parsers/stashParser.ts index 82a9bc1..92be0f3 100644 --- a/src/git/parsers/stashParser.ts +++ b/src/git/parsers/stashParser.ts @@ -15,7 +15,6 @@ interface StashEntry { const emptyEntry: StashEntry = {}; export class GitStashParser { - static parse(data: string, repoPath: string): GitStash | undefined { if (!data) return undefined; @@ -110,8 +109,10 @@ export class GitStashParser { } if (entry.fileStatuses !== undefined) { - entry.fileNames = Arrays.filterMap(entry.fileStatuses, - f => !!f.fileName ? f.fileName : undefined).join(', '); + entry.fileNames = Arrays.filterMap( + entry.fileStatuses, + f => (!!f.fileName ? f.fileName : undefined) + ).join(', '); } } @@ -126,14 +127,19 @@ export class GitStashParser { } as GitStash; } - private static parseEntry(entry: StashEntry, commit: GitStashCommit | undefined, repoPath: string, commits: Map<string, GitStashCommit>): GitStashCommit | undefined { + private static parseEntry( + entry: StashEntry, + commit: GitStashCommit | undefined, + repoPath: string, + commits: Map<string, GitStashCommit> + ): GitStashCommit | undefined { if (commit === undefined) { commit = new GitStashCommit( GitCommitType.Stash, entry.stashName!, repoPath, entry.ref!, - new Date(entry.date! as any * 1000), + new Date((entry.date! as any) * 1000), entry.summary === undefined ? '' : entry.summary, entry.fileNames!, entry.fileStatuses || [] @@ -143,4 +149,4 @@ export class GitStashParser { commits.set(entry.ref!, commit); return commit; } -} \ No newline at end of file +} diff --git a/src/git/parsers/statusParser.ts b/src/git/parsers/statusParser.ts index 2008677..c96c74e 100644 --- a/src/git/parsers/statusParser.ts +++ b/src/git/parsers/statusParser.ts @@ -6,7 +6,6 @@ const aheadStatusV1Regex = /(?:ahead ([0-9]+))/; const behindStatusV1Regex = /(?:behind ([0-9]+))/; export class GitStatusParser { - static parse(data: string, repoPath: string, porcelainVersion: number): GitStatus | undefined { if (!data) return undefined; @@ -57,13 +56,7 @@ export class GitStatusParser { } } - return new GitStatus( - Strings.normalizePath(repoPath), - branch || '', - '', - files, - state, - upstream); + return new GitStatus(Strings.normalizePath(repoPath), branch || '', '', files, state, upstream); } private static parseV2(lines: string[], repoPath: string): GitStatus { @@ -105,7 +98,10 @@ export class GitStatusParser { files.push(this.parseStatusFile(repoPath, lineParts[1], lineParts.slice(8).join(' '))); break; case '2': // rename - const file = lineParts.slice(9).join(' ').split('\t'); + const file = lineParts + .slice(9) + .join(' ') + .split('\t'); files.push(this.parseStatusFile(repoPath, lineParts[1], file[0], file[1])); break; case 'u': // unmerged @@ -118,17 +114,15 @@ export class GitStatusParser { } } - return new GitStatus( - Strings.normalizePath(repoPath), - branch || '', - sha || '', - files, - state, - upstream - ); + return new GitStatus(Strings.normalizePath(repoPath), branch || '', sha || '', files, state, upstream); } - static parseStatusFile(repoPath: string, rawStatus: string, fileName: string, originalFileName?: string): GitStatusFile { + static parseStatusFile( + repoPath: string, + rawStatus: string, + fileName: string, + originalFileName?: string + ): GitStatusFile { let indexStatus = rawStatus[0] !== '.' ? rawStatus[0].trim() : undefined; if (indexStatus === '' || indexStatus === null) { indexStatus = undefined; @@ -150,4 +144,4 @@ export class GitStatusParser { originalFileName ); } -} \ No newline at end of file +} diff --git a/src/git/parsers/tagParser.ts b/src/git/parsers/tagParser.ts index c39e6c9..9d3f66a 100644 --- a/src/git/parsers/tagParser.ts +++ b/src/git/parsers/tagParser.ts @@ -3,13 +3,12 @@ import { Arrays } from '../../system'; import { GitTag } from './../git'; export class GitTagParser { - static parse(data: string, repoPath: string): GitTag[] | undefined { if (!data) return undefined; - const tags = Arrays.filterMap(data.split('\n'), t => !!t ? new GitTag(repoPath, t) : undefined); + const tags = Arrays.filterMap(data.split('\n'), t => (!!t ? new GitTag(repoPath, t) : undefined)); if (!tags.length) return undefined; return tags; } -} \ No newline at end of file +} diff --git a/src/git/remotes/bitbucket-server.ts b/src/git/remotes/bitbucket-server.ts index b05031a..7e159e1 100644 --- a/src/git/remotes/bitbucket-server.ts +++ b/src/git/remotes/bitbucket-server.ts @@ -6,14 +6,7 @@ const issueEnricherRegEx = /(^|\s)(issue #([0-9]+))\b/gi; const prEnricherRegEx = /(^|\s)(pull request #([0-9]+))\b/gi; export class BitbucketServerService extends RemoteProvider { - - constructor( - domain: string, - path: string, - protocol?: string, - name?: string, - custom: boolean = false - ) { + constructor(domain: string, path: string, protocol?: string, name?: string, custom: boolean = false) { super(domain, path, protocol, name, custom); } @@ -31,11 +24,13 @@ export class BitbucketServerService extends RemoteProvider { } enrichMessage(message: string): string { - return message - // Matches issue #123 - .replace(issueEnricherRegEx, `$1[$2](${this.baseUrl}/issues/$3 "Open Issue $2")`) - // Matches pull request #123 - .replace(prEnricherRegEx, `$1[$2](${this.baseUrl}/pull-requests/$3 "Open PR $2")`); + return ( + message + // Matches issue #123 + .replace(issueEnricherRegEx, `$1[$2](${this.baseUrl}/issues/$3 "Open Issue $2")`) + // Matches pull request #123 + .replace(prEnricherRegEx, `$1[$2](${this.baseUrl}/pull-requests/$3 "Open PR $2")`) + ); } protected getUrlForBranches(): string { @@ -65,4 +60,4 @@ export class BitbucketServerService extends RemoteProvider { if (branch) return `${this.baseUrl}/browse/${fileName}?at=${branch}${line}`; return `${this.baseUrl}/browse/${fileName}${line}`; } -} \ No newline at end of file +} diff --git a/src/git/remotes/bitbucket.ts b/src/git/remotes/bitbucket.ts index c998524..5fef642 100644 --- a/src/git/remotes/bitbucket.ts +++ b/src/git/remotes/bitbucket.ts @@ -6,14 +6,7 @@ const issueEnricherRegEx = /(^|\s)(issue #([0-9]+))\b/gi; const prEnricherRegEx = /(^|\s)(pull request #([0-9]+))\b/gi; export class BitbucketService extends RemoteProvider { - - constructor( - domain: string, - path: string, - protocol?: string, - name?: string, - custom: boolean = false - ) { + constructor(domain: string, path: string, protocol?: string, name?: string, custom: boolean = false) { super(domain, path, protocol, name, custom); } @@ -26,11 +19,13 @@ export class BitbucketService extends RemoteProvider { } enrichMessage(message: string): string { - return message - // Matches issue #123 - .replace(issueEnricherRegEx, `$1[$2](${this.baseUrl}/issues/$3 "Open Issue $2")`) - // Matches pull request #123 - .replace(prEnricherRegEx, `$1[$2](${this.baseUrl}/pull-requests/$3 "Open PR $2")`); + return ( + message + // Matches issue #123 + .replace(issueEnricherRegEx, `$1[$2](${this.baseUrl}/issues/$3 "Open Issue $2")`) + // Matches pull request #123 + .replace(prEnricherRegEx, `$1[$2](${this.baseUrl}/pull-requests/$3 "Open PR $2")`) + ); } protected getUrlForBranches(): string { @@ -60,4 +55,4 @@ export class BitbucketService extends RemoteProvider { if (branch) return `${this.baseUrl}/src/${branch}/${fileName}${line}`; return `${this.baseUrl}?path=${fileName}${line}`; } -} \ No newline at end of file +} diff --git a/src/git/remotes/custom.ts b/src/git/remotes/custom.ts index a680e1a..1051b8a 100644 --- a/src/git/remotes/custom.ts +++ b/src/git/remotes/custom.ts @@ -5,16 +5,9 @@ import { IRemotesUrlsConfig } from '../../configuration'; import { RemoteProvider } from './provider'; export class CustomService extends RemoteProvider { - private readonly urls: IRemotesUrlsConfig; - constructor( - domain: string, - path: string, - urls: IRemotesUrlsConfig, - protocol?: string, - name?: string - ) { + constructor(domain: string, path: string, urls: IRemotesUrlsConfig, protocol?: string, name?: string) { super(domain, path, protocol, name, true); this.urls = urls; } @@ -50,8 +43,18 @@ export class CustomService extends RemoteProvider { } } - if (sha) return Strings.interpolate(this.urls.fileInCommit, this.getContext({ id: sha, file: fileName, line: line })); - if (branch) return Strings.interpolate(this.urls.fileInBranch, this.getContext({ branch: branch, file: fileName, line: line })); + if (sha) { + return Strings.interpolate( + this.urls.fileInCommit, + this.getContext({ id: sha, file: fileName, line: line }) + ); + } + if (branch) { + return Strings.interpolate( + this.urls.fileInBranch, + this.getContext({ branch: branch, file: fileName, line: line }) + ); + } return Strings.interpolate(this.urls.file, this.getContext({ file: fileName, line: line })); } @@ -64,4 +67,4 @@ export class CustomService extends RemoteProvider { ...(context || {}) }; } -} \ No newline at end of file +} diff --git a/src/git/remotes/factory.ts b/src/git/remotes/factory.ts index 58e13a0..4127017 100644 --- a/src/git/remotes/factory.ts +++ b/src/git/remotes/factory.ts @@ -21,7 +21,6 @@ const defaultProviderMap = new Map<string, (domain: string, path: string) => Rem export type RemoteProviderMap = Map<string, (domain: string, path: string) => RemoteProvider>; export class RemoteProviderFactory { - static factory(providerMap: RemoteProviderMap): (domain: string, path: string) => RemoteProvider | undefined { return (domain: string, path: string) => this.create(providerMap, domain, path); } @@ -59,12 +58,20 @@ export class RemoteProviderFactory { private static getCustomProvider(cfg: IRemotesConfig) { switch (cfg.type) { - case CustomRemoteType.Bitbucket: return (domain: string, path: string) => new BitbucketService(domain, path, cfg.protocol, cfg.name, true); - case CustomRemoteType.BitbucketServer: return (domain: string, path: string) => new BitbucketServerService(domain, path, cfg.protocol, cfg.name, true); - case CustomRemoteType.Custom: return (domain: string, path: string) => new CustomService(domain, path, cfg.urls!, cfg.protocol, cfg.name); - case CustomRemoteType.GitHub: return (domain: string, path: string) => new GitHubService(domain, path, cfg.protocol, cfg.name, true); - case CustomRemoteType.GitLab: return (domain: string, path: string) => new GitLabService(domain, path, cfg.protocol, cfg.name, true); + case CustomRemoteType.Bitbucket: + return (domain: string, path: string) => + new BitbucketService(domain, path, cfg.protocol, cfg.name, true); + case CustomRemoteType.BitbucketServer: + return (domain: string, path: string) => + new BitbucketServerService(domain, path, cfg.protocol, cfg.name, true); + case CustomRemoteType.Custom: + return (domain: string, path: string) => + new CustomService(domain, path, cfg.urls!, cfg.protocol, cfg.name); + case CustomRemoteType.GitHub: + return (domain: string, path: string) => new GitHubService(domain, path, cfg.protocol, cfg.name, true); + case CustomRemoteType.GitLab: + return (domain: string, path: string) => new GitLabService(domain, path, cfg.protocol, cfg.name, true); } return undefined; } -} \ No newline at end of file +} diff --git a/src/git/remotes/github.ts b/src/git/remotes/github.ts index 24038e8..4bf00fd 100644 --- a/src/git/remotes/github.ts +++ b/src/git/remotes/github.ts @@ -6,14 +6,7 @@ const issueEnricherRegEx = /(^|\s)((?:#|gh-)([0-9]+))\b/gi; const issueEnricher3rdParyRegEx = /\b((\w+-?\w+(?!-)\/\w+-?\w+(?!-))#([0-9]+))\b/g; export class GitHubService extends RemoteProvider { - - constructor( - domain: string, - path: string, - protocol?: string, - name?: string, - custom: boolean = false - ) { + constructor(domain: string, path: string, protocol?: string, name?: string, custom: boolean = false) { super(domain, path, protocol, name, custom); } @@ -26,11 +19,16 @@ export class GitHubService extends RemoteProvider { } enrichMessage(message: string): string { - return message - // Matches #123 or gh-123 or GH-123 - .replace(issueEnricherRegEx, `$1[$2](${this.baseUrl}/issues/$3 "Open Issue $2")`) - // Matches eamodio/vscode-gitlens#123 - .replace(issueEnricher3rdParyRegEx, `[$1](${this.protocol}://${this.domain}/$2/issues/$3 "Open Issue #$3 from $2")`); + return ( + message + // Matches #123 or gh-123 or GH-123 + .replace(issueEnricherRegEx, `$1[$2](${this.baseUrl}/issues/$3 "Open Issue $2")`) + // Matches eamodio/vscode-gitlens#123 + .replace( + issueEnricher3rdParyRegEx, + `[$1](${this.protocol}://${this.domain}/$2/issues/$3 "Open Issue #$3 from $2")` + ) + ); } protected getUrlForBranches(): string { @@ -60,4 +58,4 @@ export class GitHubService extends RemoteProvider { if (branch) return `${this.baseUrl}/blob/${branch}/${fileName}${line}`; return `${this.baseUrl}?path=${fileName}${line}`; } -} \ No newline at end of file +} diff --git a/src/git/remotes/gitlab.ts b/src/git/remotes/gitlab.ts index 64e3596..dc6658e 100644 --- a/src/git/remotes/gitlab.ts +++ b/src/git/remotes/gitlab.ts @@ -5,14 +5,7 @@ import { RemoteProvider } from './provider'; const issueEnricherRegEx = /(^|\s)(#([0-9]+))\b/gi; export class GitLabService extends RemoteProvider { - - constructor( - domain: string, - path: string, - protocol?: string, - name?: string, - custom: boolean = false - ) { + constructor(domain: string, path: string, protocol?: string, name?: string, custom: boolean = false) { super(domain, path, protocol, name, custom); } @@ -56,4 +49,4 @@ export class GitLabService extends RemoteProvider { if (branch) return `${this.baseUrl}/blob/${branch}/${fileName}${line}`; return `${this.baseUrl}?path=${fileName}${line}`; } -} \ No newline at end of file +} diff --git a/src/git/remotes/provider.ts b/src/git/remotes/provider.ts index e90cc78..d3817b4 100644 --- a/src/git/remotes/provider.ts +++ b/src/git/remotes/provider.ts @@ -13,27 +13,55 @@ export enum RemoteResourceType { } export type RemoteResource = - { type: RemoteResourceType.Branch, branch: string } | - { type: RemoteResourceType.Branches } | - { type: RemoteResourceType.Commit, sha: string } | - { type: RemoteResourceType.File, branch?: string, fileName: string, range?: Range } | - { type: RemoteResourceType.Repo } | - { type: RemoteResourceType.Revision, branch?: string, commit?: GitLogCommit, fileName: string, range?: Range, sha?: string }; + | { + type: RemoteResourceType.Branch; + branch: string; + } + | { + type: RemoteResourceType.Branches; + } + | { + type: RemoteResourceType.Commit; + sha: string; + } + | { + type: RemoteResourceType.File; + branch?: string; + fileName: string; + range?: Range; + } + | { + type: RemoteResourceType.Repo; + } + | { + type: RemoteResourceType.Revision; + branch?: string; + commit?: GitLogCommit; + fileName: string; + range?: Range; + sha?: string; + }; export function getNameFromRemoteResource(resource: RemoteResource) { switch (resource.type) { - case RemoteResourceType.Branch: return 'Branch'; - case RemoteResourceType.Branches: return 'Branches'; - case RemoteResourceType.Commit: return 'Commit'; - case RemoteResourceType.File: return 'File'; - case RemoteResourceType.Repo: return 'Repository'; - case RemoteResourceType.Revision: return 'Revision'; - default: return ''; + case RemoteResourceType.Branch: + return 'Branch'; + case RemoteResourceType.Branches: + return 'Branches'; + case RemoteResourceType.Commit: + return 'Commit'; + case RemoteResourceType.File: + return 'File'; + case RemoteResourceType.Repo: + return 'Repository'; + case RemoteResourceType.Revision: + return 'Revision'; + default: + return ''; } } export abstract class RemoteProvider { - private _name: string | undefined; constructor( @@ -67,7 +95,7 @@ export abstract class RemoteProvider { protected splitPath(): [string, string] { const index = this.path.indexOf('/'); - return [ this.path.substring(0, index), this.path.substring(index + 1) ]; + return [this.path.substring(0, index), this.path.substring(index + 1)]; } protected getUrlForRepository(): string { @@ -86,12 +114,18 @@ export abstract class RemoteProvider { open(resource: RemoteResource): Promise<{} | undefined> { switch (resource.type) { - case RemoteResourceType.Branch: return this.openBranch(resource.branch); - case RemoteResourceType.Branches: return this.openBranches(); - case RemoteResourceType.Commit: return this.openCommit(resource.sha); - case RemoteResourceType.File: return this.openFile(resource.fileName, resource.branch, undefined, resource.range); - case RemoteResourceType.Repo: return this.openRepo(); - case RemoteResourceType.Revision: return this.openFile(resource.fileName, resource.branch, resource.sha, resource.range); + case RemoteResourceType.Branch: + return this.openBranch(resource.branch); + case RemoteResourceType.Branches: + return this.openBranches(); + case RemoteResourceType.Commit: + return this.openCommit(resource.sha); + case RemoteResourceType.File: + return this.openFile(resource.fileName, resource.branch, undefined, resource.range); + case RemoteResourceType.Repo: + return this.openRepo(); + case RemoteResourceType.Revision: + return this.openFile(resource.fileName, resource.branch, resource.sha, resource.range); } } diff --git a/src/git/remotes/visualStudio.ts b/src/git/remotes/visualStudio.ts index 5bb8016..60fe7b6 100644 --- a/src/git/remotes/visualStudio.ts +++ b/src/git/remotes/visualStudio.ts @@ -6,13 +6,7 @@ const issueEnricherRegEx = /(^|\s)(#([0-9]+))\b/gi; const stripGitRegex = /\/_git\/?/i; export class VisualStudioService extends RemoteProvider { - - constructor( - domain: string, - path: string, - protocol?: string, - name?: string - ) { + constructor(domain: string, path: string, protocol?: string, name?: string) { super(domain, path, protocol, name); } @@ -58,4 +52,4 @@ export class VisualStudioService extends RemoteProvider { if (branch) return `${this.baseUrl}/?path=%2F${fileName}&version=GB${branch}&_a=contents${line}`; return `${this.baseUrl}?path=%2F${fileName}${line}`; } -} \ No newline at end of file +} diff --git a/src/git/shell.ts b/src/git/shell.ts index bba0e09..6bd0b75 100644 --- a/src/git/shell.ts +++ b/src/git/shell.ts @@ -24,9 +24,9 @@ function runDownPath(exe: string): string { const target = path.join('.', exe); try { - if (fs.statSync(target) ) return target; + if (fs.statSync(target)) return target; } - catch { } + catch {} const haystack = process.env.PATH!.split(isWindows ? ';' : ':'); for (const p of haystack) { @@ -34,7 +34,7 @@ function runDownPath(exe: string): string { try { if (fs.statSync(needle)) return needle; } - catch { } + catch {} } return exe; @@ -118,28 +118,29 @@ export function runCommand(command: string, args: any[], options: CommandOptions const { stdin, stdinEncoding, ...opts } = { maxBuffer: 10 * 1024 * 1024, ...options } as CommandOptions; return new Promise<string>((resolve, reject) => { - const proc = execFile( - command, - args, - opts, - (err: Error & { code?: string | number } | null, stdout, stderr) => { - if (!err) { - if (stderr) { - Logger.warn(`Warning(${command} ${args.join(' ')}): ${stderr}`); - } - resolve(stdout); - - return; + const proc = execFile(command, args, opts, (err: Error & { code?: string | number } | null, stdout, stderr) => { + if (!err) { + if (stderr) { + Logger.warn(`Warning(${command} ${args.join(' ')}): ${stderr}`); } + resolve(stdout); - if (err.message === 'stdout maxBuffer exceeded') { - reject(new Error(`Command output exceeded the allocated stdout buffer. Set 'options.maxBuffer' to a larger value than ${opts.maxBuffer} bytes`)); - } + return; + } - // Logger.warn(`Error(${opts.cwd}): ${command} ${args.join(' ')})\n (${err.code}) ${err.message}\n${stderr}`); - reject(err); + if (err.message === 'stdout maxBuffer exceeded') { + reject( + new Error( + `Command output exceeded the allocated stdout buffer. Set 'options.maxBuffer' to a larger value than ${ + opts.maxBuffer + } bytes` + ) + ); } - ); + + // Logger.warn(`Error(${opts.cwd}): ${command} ${args.join(' ')})\n (${err.code}) ${err.message}\n${stderr}`); + reject(err); + }); if (stdin) { proc.stdin.end(stdin, stdinEncoding || 'utf8'); diff --git a/src/gitCodeLensProvider.ts b/src/gitCodeLensProvider.ts index b78c7de..8419159 100644 --- a/src/gitCodeLensProvider.ts +++ b/src/gitCodeLensProvider.ts @@ -1,8 +1,37 @@ 'use strict'; import { Functions, Iterables } from './system'; -import { CancellationToken, CodeLens, CodeLensProvider, Command, commands, DocumentSelector, Event, EventEmitter, ExtensionContext, Location, Position, Range, SymbolInformation, SymbolKind, TextDocument, Uri } from 'vscode'; -import { Commands, DiffWithPreviousCommandArgs, ShowQuickCommitDetailsCommandArgs, ShowQuickCommitFileDetailsCommandArgs, ShowQuickFileHistoryCommandArgs } from './commands'; -import { CodeLensCommand, CodeLensLanguageScope, CodeLensScopes, configuration, ICodeLensConfig } from './configuration'; +import { + CancellationToken, + CodeLens, + CodeLensProvider, + Command, + commands, + DocumentSelector, + Event, + EventEmitter, + ExtensionContext, + Location, + Position, + Range, + SymbolInformation, + SymbolKind, + TextDocument, + Uri +} from 'vscode'; +import { + Commands, + DiffWithPreviousCommandArgs, + ShowQuickCommitDetailsCommandArgs, + ShowQuickCommitFileDetailsCommandArgs, + ShowQuickFileHistoryCommandArgs +} from './commands'; +import { + CodeLensCommand, + CodeLensLanguageScope, + CodeLensScopes, + configuration, + ICodeLensConfig +} from './configuration'; import { BuiltInCommands, DocumentSchemes } from './constants'; import { Container } from './container'; import { DocumentTracker, GitDocumentState } from './trackers/gitDocumentTracker'; @@ -10,7 +39,6 @@ import { GitBlame, GitBlameCommit, GitBlameLines, GitService, GitUri } from './g import { Logger } from './logger'; export class GitRecentChangeCodeLens extends CodeLens { - constructor( public readonly languageId: string, public readonly symbol: SymbolInformation, @@ -31,7 +59,6 @@ export class GitRecentChangeCodeLens extends CodeLens { } export class GitAuthorsCodeLens extends CodeLens { - constructor( public readonly languageId: string, public readonly symbol: SymbolInformation, @@ -51,19 +78,22 @@ export class GitAuthorsCodeLens extends CodeLens { } export class GitCodeLensProvider implements CodeLensProvider { - private _onDidChangeCodeLenses = new EventEmitter<void>(); public get onDidChangeCodeLenses(): Event<void> { return this._onDidChangeCodeLenses.event; } - static selector: DocumentSelector = [{ scheme: DocumentSchemes.File }, { scheme: DocumentSchemes.Git }, { scheme: DocumentSchemes.GitLensGit }]; + static selector: DocumentSelector = [ + { scheme: DocumentSchemes.File }, + { scheme: DocumentSchemes.Git }, + { scheme: DocumentSchemes.GitLensGit } + ]; constructor( context: ExtensionContext, private readonly _git: GitService, private readonly _tracker: DocumentTracker<GitDocumentState> - ) { } + ) {} reset(reason?: 'idle' | 'saved') { this._onDidChangeCodeLenses.fire(); @@ -89,7 +119,11 @@ export class GitCodeLensProvider implements CodeLensProvider { const cfg = configuration.get<ICodeLensConfig>(configuration.name('codeLens').value, document.uri); - let languageScope = cfg.scopesByLanguage && cfg.scopesByLanguage.find(ll => ll.language !== undefined && ll.language.toLowerCase() === document.languageId); + let languageScope = + cfg.scopesByLanguage && + cfg.scopesByLanguage.find( + ll => ll.language !== undefined && ll.language.toLowerCase() === document.languageId + ); if (languageScope == null) { languageScope = { language: undefined @@ -102,9 +136,10 @@ export class GitCodeLensProvider implements CodeLensProvider { languageScope.symbolScopes = cfg.symbolScopes; } - languageScope.symbolScopes = languageScope.symbolScopes != null - ? languageScope.symbolScopes = languageScope.symbolScopes.map(s => s.toLowerCase()) - : []; + languageScope.symbolScopes = + languageScope.symbolScopes != null + ? (languageScope.symbolScopes = languageScope.symbolScopes.map(s => s.toLowerCase())) + : []; const lenses: CodeLens[] = []; @@ -125,7 +160,9 @@ export class GitCodeLensProvider implements CodeLensProvider { document.isDirty ? this._git.getBlameForFileContents(gitUri, document.getText()) : this._git.getBlameForFile(gitUri), - commands.executeCommand(BuiltInCommands.ExecuteDocumentSymbolProvider, document.uri) as Promise<SymbolInformation[]> + commands.executeCommand(BuiltInCommands.ExecuteDocumentSymbolProvider, document.uri) as Promise< + SymbolInformation[] + > ]); } @@ -133,7 +170,10 @@ export class GitCodeLensProvider implements CodeLensProvider { } else { if (languageScope.scopes.length !== 1 || !languageScope.scopes.includes(CodeLensScopes.Document)) { - symbols = await commands.executeCommand(BuiltInCommands.ExecuteDocumentSymbolProvider, document.uri) as SymbolInformation[]; + symbols = (await commands.executeCommand( + BuiltInCommands.ExecuteDocumentSymbolProvider, + document.uri + )) as SymbolInformation[]; } } @@ -142,14 +182,30 @@ export class GitCodeLensProvider implements CodeLensProvider { const documentRangeFn = Functions.once(() => document.validateRange(new Range(0, 1000000, 1000000, 1000000))); // Since blame information isn't valid when there are unsaved changes -- update the lenses appropriately - const dirtyCommand = dirty ? { title: this.getDirtyTitle(cfg) } as Command : undefined; + const dirtyCommand = dirty ? ({ title: this.getDirtyTitle(cfg) } as Command) : undefined; if (symbols !== undefined) { Logger.log('GitCodeLensProvider.provideCodeLenses:', `${symbols.length} symbol(s) found`); - symbols.forEach(sym => this.provideCodeLens(lenses, document, sym, languageScope as Required<CodeLensLanguageScope>, documentRangeFn, blame, gitUri, cfg, dirty, dirtyCommand)); + symbols.forEach(sym => + this.provideCodeLens( + lenses, + document, + sym, + languageScope as Required<CodeLensLanguageScope>, + documentRangeFn, + blame, + gitUri, + cfg, + dirty, + dirtyCommand + ) + ); } - if ((languageScope.scopes.includes(CodeLensScopes.Document) || languageScope.symbolScopes.includes('file')) && !languageScope.symbolScopes.includes('!file')) { + if ( + (languageScope.scopes.includes(CodeLensScopes.Document) || languageScope.symbolScopes.includes('file')) && + !languageScope.symbolScopes.includes('!file') + ) { // Check if we have a lens for the whole document -- if not add one if (!lenses.find(l => l.range.start.line === 0 && l.range.end.line === 0)) { const blameRange = documentRangeFn(); @@ -157,38 +213,56 @@ export class GitCodeLensProvider implements CodeLensProvider { let blameForRangeFn: (() => GitBlameLines | undefined) | undefined = undefined; if (dirty || cfg.recentChange.enabled) { if (!dirty) { - blameForRangeFn = Functions.once(() => this._git.getBlameForRangeSync(blame!, gitUri!, blameRange)); + blameForRangeFn = Functions.once(() => + this._git.getBlameForRangeSync(blame!, gitUri!, blameRange) + ); } - const fileSymbol = new SymbolInformation(gitUri.getFilename(), SymbolKind.File, '', new Location(gitUri.fileUri(), new Range(0, 0, 0, blameRange.start.character))); - lenses.push(new GitRecentChangeCodeLens( - document.languageId, - fileSymbol, - gitUri, - blameForRangeFn, - blameRange, - true, - getRangeFromSymbol(fileSymbol), - cfg.recentChange.command, - dirtyCommand - )); + const fileSymbol = new SymbolInformation( + gitUri.getFilename(), + SymbolKind.File, + '', + new Location(gitUri.fileUri(), new Range(0, 0, 0, blameRange.start.character)) + ); + lenses.push( + new GitRecentChangeCodeLens( + document.languageId, + fileSymbol, + gitUri, + blameForRangeFn, + blameRange, + true, + getRangeFromSymbol(fileSymbol), + cfg.recentChange.command, + dirtyCommand + ) + ); } if (!dirty && cfg.authors.enabled) { if (blameForRangeFn === undefined) { - blameForRangeFn = Functions.once(() => this._git.getBlameForRangeSync(blame!, gitUri!, blameRange)); + blameForRangeFn = Functions.once(() => + this._git.getBlameForRangeSync(blame!, gitUri!, blameRange) + ); } - const fileSymbol = new SymbolInformation(gitUri.getFilename(), SymbolKind.File, '', new Location(gitUri.fileUri(), new Range(0, 1, 0, blameRange.start.character))); - lenses.push(new GitAuthorsCodeLens( - document.languageId, - fileSymbol, - gitUri, - blameForRangeFn, - blameRange, - true, - getRangeFromSymbol(fileSymbol), - cfg.authors.command - )); + const fileSymbol = new SymbolInformation( + gitUri.getFilename(), + SymbolKind.File, + '', + new Location(gitUri.fileUri(), new Range(0, 1, 0, blameRange.start.character)) + ); + lenses.push( + new GitAuthorsCodeLens( + document.languageId, + fileSymbol, + gitUri, + blameForRangeFn, + blameRange, + true, + getRangeFromSymbol(fileSymbol), + cfg.authors.command + ) + ); } } } @@ -196,14 +270,21 @@ export class GitCodeLensProvider implements CodeLensProvider { return lenses; } - private validateSymbolAndGetBlameRange(symbol: SymbolInformation, languageScope: Required<CodeLensLanguageScope>, documentRangeFn: () => Range): Range | undefined { + private validateSymbolAndGetBlameRange( + symbol: SymbolInformation, + languageScope: Required<CodeLensLanguageScope>, + documentRangeFn: () => Range + ): Range | undefined { let valid = false; let range: Range | undefined; const symbolName = SymbolKind[symbol.kind].toLowerCase(); switch (symbol.kind) { case SymbolKind.File: - if (languageScope.scopes.includes(CodeLensScopes.Containers) || languageScope.symbolScopes!.includes(symbolName)) { + if ( + languageScope.scopes.includes(CodeLensScopes.Containers) || + languageScope.symbolScopes!.includes(symbolName) + ) { valid = !languageScope.symbolScopes!.includes(`!${symbolName}`); } @@ -214,7 +295,10 @@ export class GitCodeLensProvider implements CodeLensProvider { break; case SymbolKind.Package: - if (languageScope.scopes.includes(CodeLensScopes.Containers) || languageScope.symbolScopes!.includes(symbolName)) { + if ( + languageScope.scopes.includes(CodeLensScopes.Containers) || + languageScope.symbolScopes!.includes(symbolName) + ) { valid = !languageScope.symbolScopes!.includes(`!${symbolName}`); } @@ -231,7 +315,10 @@ export class GitCodeLensProvider implements CodeLensProvider { case SymbolKind.Module: case SymbolKind.Namespace: case SymbolKind.Struct: - if (languageScope.scopes.includes(CodeLensScopes.Containers) || languageScope.symbolScopes!.includes(symbolName)) { + if ( + languageScope.scopes.includes(CodeLensScopes.Containers) || + languageScope.symbolScopes!.includes(symbolName) + ) { valid = !languageScope.symbolScopes!.includes(`!${symbolName}`); } break; @@ -240,7 +327,10 @@ export class GitCodeLensProvider implements CodeLensProvider { case SymbolKind.Enum: case SymbolKind.Function: case SymbolKind.Method: - if (languageScope.scopes.includes(CodeLensScopes.Blocks) || languageScope.symbolScopes!.includes(symbolName)) { + if ( + languageScope.scopes.includes(CodeLensScopes.Blocks) || + languageScope.symbolScopes!.includes(symbolName) + ) { valid = !languageScope.symbolScopes!.includes(`!${symbolName}`); } break; @@ -255,7 +345,18 @@ export class GitCodeLensProvider implements CodeLensProvider { return valid ? range || getRangeFromSymbol(symbol) : undefined; } - private provideCodeLens(lenses: CodeLens[], document: TextDocument, symbol: SymbolInformation, languageScope: Required<CodeLensLanguageScope>, documentRangeFn: () => Range, blame: GitBlame | undefined, gitUri: GitUri | undefined, cfg: ICodeLensConfig, dirty: boolean, dirtyCommand: Command | undefined): void { + private provideCodeLens( + lenses: CodeLens[], + document: TextDocument, + symbol: SymbolInformation, + languageScope: Required<CodeLensLanguageScope>, + documentRangeFn: () => Range, + blame: GitBlame | undefined, + gitUri: GitUri | undefined, + cfg: ICodeLensConfig, + dirty: boolean, + dirtyCommand: Command | undefined + ): void { const blameRange = this.validateSymbolAndGetBlameRange(symbol, languageScope, documentRangeFn); if (blameRange === undefined) return; @@ -271,7 +372,19 @@ export class GitCodeLensProvider implements CodeLensProvider { if (!dirty) { blameForRangeFn = Functions.once(() => this._git.getBlameForRangeSync(blame!, gitUri!, blameRange)); } - lenses.push(new GitRecentChangeCodeLens(document.languageId, symbol, gitUri, blameForRangeFn, blameRange, false, line.range.with(new Position(line.range.start.line, startChar)), cfg.recentChange.command, dirtyCommand)); + lenses.push( + new GitRecentChangeCodeLens( + document.languageId, + symbol, + gitUri, + blameForRangeFn, + blameRange, + false, + line.range.with(new Position(line.range.start.line, startChar)), + cfg.recentChange.command, + dirtyCommand + ) + ); startChar++; } @@ -300,7 +413,18 @@ export class GitCodeLensProvider implements CodeLensProvider { if (blameForRangeFn === undefined) { blameForRangeFn = Functions.once(() => this._git.getBlameForRangeSync(blame!, gitUri!, blameRange)); } - lenses.push(new GitAuthorsCodeLens(document.languageId, symbol, gitUri, blameForRangeFn, blameRange, false, line.range.with(new Position(line.range.start.line, startChar)), cfg.authors.command)); + lenses.push( + new GitAuthorsCodeLens( + document.languageId, + symbol, + gitUri, + blameForRangeFn, + blameRange, + false, + line.range.with(new Position(line.range.start.line, startChar)), + cfg.authors.command + ) + ); } } } @@ -318,17 +442,42 @@ export class GitCodeLensProvider implements CodeLensProvider { const recentCommit = Iterables.first(blame.commits.values()); let title = `${recentCommit.author}, ${recentCommit.formattedDate}`; if (Container.config.debug) { - title += ` [${lens.languageId}: ${SymbolKind[lens.symbol.kind]}(${lens.range.start.character}-${lens.range.end.character}${lens.symbol.containerName ? `|${lens.symbol.containerName}` : ''}), Lines (${lens.blameRange.start.line + 1}-${lens.blameRange.end.line + 1}), Commit (${recentCommit.shortSha})]`; + title += ` [${lens.languageId}: ${SymbolKind[lens.symbol.kind]}(${lens.range.start.character}-${ + lens.range.end.character + }${lens.symbol.containerName ? `|${lens.symbol.containerName}` : ''}), Lines (${lens.blameRange.start.line + + 1}-${lens.blameRange.end.line + 1}), Commit (${recentCommit.shortSha})]`; } switch (lens.desiredCommand) { - case CodeLensCommand.DiffWithPrevious: return this.applyDiffWithPreviousCommand<GitRecentChangeCodeLens>(title, lens, blame, recentCommit); - case CodeLensCommand.ShowQuickCommitDetails: return this.applyShowQuickCommitDetailsCommand<GitRecentChangeCodeLens>(title, lens, blame, recentCommit); - case CodeLensCommand.ShowQuickCommitFileDetails: return this.applyShowQuickCommitFileDetailsCommand<GitRecentChangeCodeLens>(title, lens, blame, recentCommit); - case CodeLensCommand.ShowQuickCurrentBranchHistory: return this.applyShowQuickCurrentBranchHistoryCommand<GitRecentChangeCodeLens>(title, lens, blame, recentCommit); - case CodeLensCommand.ShowQuickFileHistory: return this.applyShowQuickFileHistoryCommand<GitRecentChangeCodeLens>(title, lens, blame, recentCommit); - case CodeLensCommand.ToggleFileBlame: return this.applyToggleFileBlameCommand<GitRecentChangeCodeLens>(title, lens, blame); - default: return lens; + case CodeLensCommand.DiffWithPrevious: + return this.applyDiffWithPreviousCommand<GitRecentChangeCodeLens>(title, lens, blame, recentCommit); + case CodeLensCommand.ShowQuickCommitDetails: + return this.applyShowQuickCommitDetailsCommand<GitRecentChangeCodeLens>( + title, + lens, + blame, + recentCommit + ); + case CodeLensCommand.ShowQuickCommitFileDetails: + return this.applyShowQuickCommitFileDetailsCommand<GitRecentChangeCodeLens>( + title, + lens, + blame, + recentCommit + ); + case CodeLensCommand.ShowQuickCurrentBranchHistory: + return this.applyShowQuickCurrentBranchHistoryCommand<GitRecentChangeCodeLens>( + title, + lens, + blame, + recentCommit + ); + case CodeLensCommand.ShowQuickFileHistory: + return this.applyShowQuickFileHistoryCommand<GitRecentChangeCodeLens>(title, lens, blame, recentCommit); + case CodeLensCommand.ToggleFileBlame: + return this.applyToggleFileBlameCommand<GitRecentChangeCodeLens>(title, lens, blame); + default: + return lens; } } @@ -337,23 +486,43 @@ export class GitCodeLensProvider implements CodeLensProvider { if (blame === undefined) return lens; const count = blame.authors.size; - let title = `${count} ${count > 1 ? 'authors' : 'author'} (${Iterables.first(blame.authors.values()).name}${count > 1 ? ' and others' : ''})`; + let title = `${count} ${count > 1 ? 'authors' : 'author'} (${Iterables.first(blame.authors.values()).name}${ + count > 1 ? ' and others' : '' + })`; if (Container.config.debug) { - title += ` [${lens.languageId}: ${SymbolKind[lens.symbol.kind]}(${lens.range.start.character}-${lens.range.end.character}${lens.symbol.containerName ? `|${lens.symbol.containerName}` : ''}), Lines (${lens.blameRange.start.line + 1}-${lens.blameRange.end.line + 1}), Authors (${Iterables.join(Iterables.map(blame.authors.values(), a => a.name), ', ')})]`; + title += ` [${lens.languageId}: ${SymbolKind[lens.symbol.kind]}(${lens.range.start.character}-${ + lens.range.end.character + }${lens.symbol.containerName ? `|${lens.symbol.containerName}` : ''}), Lines (${lens.blameRange.start.line + + 1}-${lens.blameRange.end.line + 1}), Authors (${Iterables.join( + Iterables.map(blame.authors.values(), a => a.name), + ', ' + )})]`; } switch (lens.desiredCommand) { - case CodeLensCommand.DiffWithPrevious: return this.applyDiffWithPreviousCommand<GitAuthorsCodeLens>(title, lens, blame); - case CodeLensCommand.ShowQuickCommitDetails: return this.applyShowQuickCommitDetailsCommand<GitAuthorsCodeLens>(title, lens, blame); - case CodeLensCommand.ShowQuickCommitFileDetails: return this.applyShowQuickCommitFileDetailsCommand<GitAuthorsCodeLens>(title, lens, blame); - case CodeLensCommand.ShowQuickCurrentBranchHistory: return this.applyShowQuickCurrentBranchHistoryCommand<GitAuthorsCodeLens>(title, lens, blame); - case CodeLensCommand.ShowQuickFileHistory: return this.applyShowQuickFileHistoryCommand<GitAuthorsCodeLens>(title, lens, blame); - case CodeLensCommand.ToggleFileBlame: return this.applyToggleFileBlameCommand<GitAuthorsCodeLens>(title, lens, blame); - default: return lens; + case CodeLensCommand.DiffWithPrevious: + return this.applyDiffWithPreviousCommand<GitAuthorsCodeLens>(title, lens, blame); + case CodeLensCommand.ShowQuickCommitDetails: + return this.applyShowQuickCommitDetailsCommand<GitAuthorsCodeLens>(title, lens, blame); + case CodeLensCommand.ShowQuickCommitFileDetails: + return this.applyShowQuickCommitFileDetailsCommand<GitAuthorsCodeLens>(title, lens, blame); + case CodeLensCommand.ShowQuickCurrentBranchHistory: + return this.applyShowQuickCurrentBranchHistoryCommand<GitAuthorsCodeLens>(title, lens, blame); + case CodeLensCommand.ShowQuickFileHistory: + return this.applyShowQuickFileHistoryCommand<GitAuthorsCodeLens>(title, lens, blame); + case CodeLensCommand.ToggleFileBlame: + return this.applyToggleFileBlameCommand<GitAuthorsCodeLens>(title, lens, blame); + default: + return lens; } } - private applyDiffWithPreviousCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>(title: string, lens: T, blame: GitBlameLines, commit?: GitBlameCommit): T { + private applyDiffWithPreviousCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>( + title: string, + lens: T, + blame: GitBlameLines, + commit?: GitBlameCommit + ): T { if (commit === undefined) { const blameLine = blame.allLines[lens.range.start.line]; commit = blame.commits.get(blameLine.sha); @@ -372,7 +541,12 @@ export class GitCodeLensProvider implements CodeLensProvider { return lens; } - private applyShowQuickCommitDetailsCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>(title: string, lens: T, blame: GitBlameLines, commit?: GitBlameCommit): T { + private applyShowQuickCommitDetailsCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>( + title: string, + lens: T, + blame: GitBlameLines, + commit?: GitBlameCommit + ): T { lens.command = { title: title, command: commit !== undefined && commit.isUncommitted ? '' : CodeLensCommand.ShowQuickCommitDetails, @@ -381,12 +555,18 @@ export class GitCodeLensProvider implements CodeLensProvider { { commit, sha: commit === undefined ? undefined : commit.sha - } as ShowQuickCommitDetailsCommandArgs] + } as ShowQuickCommitDetailsCommandArgs + ] }; return lens; } - private applyShowQuickCommitFileDetailsCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>(title: string, lens: T, blame: GitBlameLines, commit?: GitBlameCommit): T { + private applyShowQuickCommitFileDetailsCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>( + title: string, + lens: T, + blame: GitBlameLines, + commit?: GitBlameCommit + ): T { lens.command = { title: title, command: commit !== undefined && commit.isUncommitted ? '' : CodeLensCommand.ShowQuickCommitFileDetails, @@ -395,12 +575,18 @@ export class GitCodeLensProvider implements CodeLensProvider { { commit, sha: commit === undefined ? undefined : commit.sha - } as ShowQuickCommitFileDetailsCommandArgs] + } as ShowQuickCommitFileDetailsCommandArgs + ] }; return lens; } - private applyShowQuickCurrentBranchHistoryCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>(title: string, lens: T, blame: GitBlameLines, commit?: GitBlameCommit): T { + private applyShowQuickCurrentBranchHistoryCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>( + title: string, + lens: T, + blame: GitBlameLines, + commit?: GitBlameCommit + ): T { lens.command = { title: title, command: CodeLensCommand.ShowQuickCurrentBranchHistory, @@ -409,7 +595,12 @@ export class GitCodeLensProvider implements CodeLensProvider { return lens; } - private applyShowQuickFileHistoryCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>(title: string, lens: T, blame: GitBlameLines, commit?: GitBlameCommit): T { + private applyShowQuickFileHistoryCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>( + title: string, + lens: T, + blame: GitBlameLines, + commit?: GitBlameCommit + ): T { lens.command = { title: title, command: CodeLensCommand.ShowQuickFileHistory, @@ -423,7 +614,11 @@ export class GitCodeLensProvider implements CodeLensProvider { return lens; } - private applyToggleFileBlameCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>(title: string, lens: T, blame: GitBlameLines): T { + private applyToggleFileBlameCommand<T extends GitRecentChangeCodeLens | GitAuthorsCodeLens>( + title: string, + lens: T, + blame: GitBlameLines + ): T { lens.command = { title: title, command: Commands.ToggleFileBlame, @@ -433,7 +628,9 @@ export class GitCodeLensProvider implements CodeLensProvider { } private getDirtyTitle(cfg: ICodeLensConfig) { - if (cfg.recentChange.enabled && cfg.authors.enabled) return Container.config.strings.codeLens.unsavedChanges.recentChangeAndAuthors; + if (cfg.recentChange.enabled && cfg.authors.enabled) { + return Container.config.strings.codeLens.unsavedChanges.recentChangeAndAuthors; + } if (cfg.recentChange.enabled) return Container.config.strings.codeLens.unsavedChanges.recentChangeOnly; return Container.config.strings.codeLens.unsavedChanges.authorsOnly; } @@ -442,4 +639,4 @@ export class GitCodeLensProvider implements CodeLensProvider { function getRangeFromSymbol(symbol: SymbolInformation) { // Normalize the range to deal with the new api return (symbol.location && symbol.location.range) || (symbol as any).range; -} \ No newline at end of file +} diff --git a/src/gitContentProvider.ts b/src/gitContentProvider.ts index 9cda3ca..f8568d6 100644 --- a/src/gitContentProvider.ts +++ b/src/gitContentProvider.ts @@ -7,7 +7,6 @@ import { Logger } from './logger'; import * as path from 'path'; export class GitContentProvider implements TextDocumentContentProvider { - static scheme = DocumentSchemes.GitLensGit; async provideTextDocumentContent(uri: Uri, token: CancellationToken): Promise<string | undefined> { @@ -19,8 +18,13 @@ export class GitContentProvider implements TextDocumentContentProvider { } catch (ex) { Logger.error(ex, 'GitContentProvider', 'getVersionedFileText'); - window.showErrorMessage(`Unable to show Git revision ${GitService.shortenSha(gitUri.sha)} of '${path.relative(gitUri.repoPath, gitUri.fsPath)}'`); + window.showErrorMessage( + `Unable to show Git revision ${GitService.shortenSha(gitUri.sha)} of '${path.relative( + gitUri.repoPath, + gitUri.fsPath + )}'` + ); return undefined; } } -} \ No newline at end of file +} diff --git a/src/gitRevisionCodeLensProvider.ts b/src/gitRevisionCodeLensProvider.ts index 96b451e..7368158 100644 --- a/src/gitRevisionCodeLensProvider.ts +++ b/src/gitRevisionCodeLensProvider.ts @@ -6,7 +6,6 @@ import { Container } from './container'; import { GitCommit, GitUri } from './gitService'; export class GitDiffWithWorkingCodeLens extends CodeLens { - constructor( public readonly fileName: string, public readonly commit: GitCommit, @@ -17,7 +16,6 @@ export class GitDiffWithWorkingCodeLens extends CodeLens { } export class GitDiffWithPreviousCodeLens extends CodeLens { - constructor( public readonly fileName: string, public readonly commit: GitCommit, @@ -28,7 +26,6 @@ export class GitDiffWithPreviousCodeLens extends CodeLens { } export class GitRevisionCodeLensProvider implements CodeLensProvider { - static selector: DocumentSelector = { scheme: DocumentSchemes.GitLensGit }; async provideCodeLenses(document: TextDocument, token: CancellationToken): Promise<CodeLens[]> { @@ -36,7 +33,10 @@ export class GitRevisionCodeLensProvider implements CodeLensProvider { const lenses: CodeLens[] = []; - const commit = await Container.git.getLogCommitForFile(gitUri.repoPath, gitUri.fsPath, { ref: gitUri.sha, firstIfNotFound: true }); + const commit = await Container.git.getLogCommitForFile(gitUri.repoPath, gitUri.fsPath, { + ref: gitUri.sha, + firstIfNotFound: true + }); if (commit === undefined) return lenses; if (commit.previousSha) { @@ -53,7 +53,10 @@ export class GitRevisionCodeLensProvider implements CodeLensProvider { return Promise.reject<CodeLens>(undefined); } - _resolveDiffWithWorkingTreeCodeLens(lens: GitDiffWithWorkingCodeLens, token: CancellationToken): Thenable<CodeLens> { + _resolveDiffWithWorkingTreeCodeLens( + lens: GitDiffWithWorkingCodeLens, + token: CancellationToken + ): Thenable<CodeLens> { lens.command = { title: `Compare Revision (${lens.commit.shortSha}) with Working`, command: Commands.DiffWithWorking, @@ -68,7 +71,10 @@ export class GitRevisionCodeLensProvider implements CodeLensProvider { return Promise.resolve(lens); } - _resolveGitDiffWithPreviousCodeLens(lens: GitDiffWithPreviousCodeLens, token: CancellationToken): Thenable<CodeLens> { + _resolveGitDiffWithPreviousCodeLens( + lens: GitDiffWithPreviousCodeLens, + token: CancellationToken + ): Thenable<CodeLens> { lens.command = { title: `Compare Revision (${lens.commit.shortSha}) with Previous (${lens.commit.previousShortSha})`, command: Commands.DiffWithPrevious, diff --git a/src/gitService.ts b/src/gitService.ts index fbf9fc0..277cfa0 100644 --- a/src/gitService.ts +++ b/src/gitService.ts @@ -1,11 +1,56 @@ 'use strict'; import { Iterables, Objects, Strings, TernarySearchTree, Versions } from './system'; -import { ConfigurationChangeEvent, Disposable, Event, EventEmitter, Range, TextEditor, Uri, window, WindowState, workspace, WorkspaceFolder, WorkspaceFoldersChangeEvent } from 'vscode'; +import { + ConfigurationChangeEvent, + Disposable, + Event, + EventEmitter, + Range, + TextEditor, + Uri, + window, + WindowState, + workspace, + WorkspaceFolder, + WorkspaceFoldersChangeEvent +} from 'vscode'; import { configuration, IRemotesConfig } from './configuration'; import { CommandContext, DocumentSchemes, setCommandContext } from './constants'; import { Container } from './container'; import { RemoteProviderFactory, RemoteProviderMap } from './git/remotes/factory'; -import { CommitFormatting, Git, GitAuthor, GitBlame, GitBlameCommit, GitBlameLine, GitBlameLines, GitBlameParser, GitBranch, GitBranchParser, GitCommit, GitCommitType, GitDiff, GitDiffChunkLine, GitDiffParser, GitDiffShortStat, GitLog, GitLogCommit, GitLogParser, GitRemote, GitRemoteParser, GitStash, GitStashParser, GitStatus, GitStatusFile, GitStatusParser, GitTag, GitTagParser, IGit, Repository, RepositoryChange } from './git/git'; +import { + CommitFormatting, + Git, + GitAuthor, + GitBlame, + GitBlameCommit, + GitBlameLine, + GitBlameLines, + GitBlameParser, + GitBranch, + GitBranchParser, + GitCommit, + GitCommitType, + GitDiff, + GitDiffChunkLine, + GitDiffParser, + GitDiffShortStat, + GitLog, + GitLogCommit, + GitLogParser, + GitRemote, + GitRemoteParser, + GitStash, + GitStashParser, + GitStatus, + GitStatusFile, + GitStatusParser, + GitTag, + GitTagParser, + IGit, + Repository, + RepositoryChange +} from './git/git'; import { CachedBlame, CachedDiff, CachedLog, GitDocumentState, TrackedDocument } from './trackers/gitDocumentTracker'; import { GitUri, IGitCommitInfo } from './git/gitUri'; import { Logger } from './logger'; @@ -32,7 +77,6 @@ export enum GitRepoSearchBy { } export class GitService extends Disposable { - static emptyPromise: Promise<GitBlame | GitDiff | GitLog | undefined> = Promise.resolve(undefined); static deletedSha = 'ffffffffffffffffffffffffffffffffffffffff'; static stagedUncommittedSha = Git.stagedUncommittedSha; @@ -95,9 +139,11 @@ export class GitService extends Disposable { private onConfigurationChanged(e: ConfigurationChangeEvent) { const initializing = configuration.initializing(e); - if (initializing || + if ( + initializing || configuration.changed(e, configuration.name('defaultDateStyle').value) || - configuration.changed(e, configuration.name('defaultDateFormat').value)) { + configuration.changed(e, configuration.name('defaultDateFormat').value) + ) { CommitFormatting.reset(); } } @@ -140,10 +186,16 @@ export class GitService extends Disposable { const fsPath = f.uri.fsPath; const filteredTree = this._repositoryTree.findSuperstr(fsPath); - const reposToDelete = filteredTree !== undefined - // Since the filtered tree will have keys that are relative to the fsPath, normalize to the full path - ? [...Iterables.map<[Repository, string], [Repository, string]>(filteredTree.entries(), ([r, k]) => [r, path.join(fsPath, k)])] - : []; + const reposToDelete = + filteredTree !== undefined + ? // Since the filtered tree will have keys that are relative to the fsPath, normalize to the full path + [ + ...Iterables.map<[Repository, string], [Repository, string]>( + filteredTree.entries(), + ([r, k]) => [r, path.join(fsPath, k)] + ) + ] + : []; const repo = this._repositoryTree.get(fsPath); if (repo !== undefined) { @@ -167,7 +219,10 @@ export class GitService extends Disposable { private async repositorySearch(folder: WorkspaceFolder): Promise<Repository[]> { const folderUri = folder.uri; - const depth = configuration.get<number>(configuration.name('advanced')('repositorySearchDepth').value, folderUri); + const depth = configuration.get<number>( + configuration.name('advanced')('repositorySearchDepth').value, + folderUri + ); Logger.log(`Searching for repositories (depth=${depth}) in '${folderUri.fsPath}' ...`); @@ -184,7 +239,10 @@ export class GitService extends Disposable { if (depth <= 0) { const duration = process.hrtime(start); - Logger.log(`Searching for repositories (depth=${depth}) in '${folderUri.fsPath}' took ${(duration[0] * 1000) + Math.floor(duration[1] / 1000000)} ms`); + Logger.log( + `Searching for repositories (depth=${depth}) in '${folderUri.fsPath}' took ${duration[0] * 1000 + + Math.floor(duration[1] / 1000000)} ms` + ); return repositories; } @@ -195,16 +253,21 @@ export class GitService extends Disposable { ...workspace.getConfiguration('search', folderUri).get<{ [key: string]: boolean }>('exclude', {}) }; - const excludedPaths = [...Iterables.filterMap(Objects.entries(excludes), ([key, value]) => { - if (!value) return undefined; - if (key.startsWith('**/')) return key.substring(3); - return key; - })]; - - excludes = excludedPaths.reduce((accumulator, current) => { - accumulator[current] = true; - return accumulator; - }, Object.create(null) as any); + const excludedPaths = [ + ...Iterables.filterMap(Objects.entries(excludes), ([key, value]) => { + if (!value) return undefined; + if (key.startsWith('**/')) return key.substring(3); + return key; + }) + ]; + + excludes = excludedPaths.reduce( + (accumulator, current) => { + accumulator[current] = true; + return accumulator; + }, + Object.create(null) as any + ); let paths; try { @@ -212,7 +275,11 @@ export class GitService extends Disposable { } catch (ex) { if (RepoSearchWarnings.doesNotExist.test(ex.message || '')) { - Logger.log(`Searching for repositories (depth=${depth}) in '${folderUri.fsPath}' FAILED${ex.message ? ` (${ex.message})` : ''}`); + Logger.log( + `Searching for repositories (depth=${depth}) in '${folderUri.fsPath}' FAILED${ + ex.message ? ` (${ex.message})` : '' + }` + ); } else { Logger.error(ex, `Searching for repositories (depth=${depth}) in '${folderUri.fsPath}' FAILED`); @@ -234,12 +301,20 @@ export class GitService extends Disposable { } const duration = process.hrtime(start); - Logger.log(`Searching for repositories (depth=${depth}) in '${folderUri.fsPath}' took ${(duration[0] * 1000) + Math.floor(duration[1] / 1000000)} ms`); + Logger.log( + `Searching for repositories (depth=${depth}) in '${folderUri.fsPath}' took ${duration[0] * 1000 + + Math.floor(duration[1] / 1000000)} ms` + ); return repositories; } - private async repositorySearchCore(root: string, depth: number, excludes: { [key: string]: boolean }, repositories: string[] = []): Promise<string[]> { + private async repositorySearchCore( + root: string, + depth: number, + excludes: { [key: string]: boolean }, + repositories: string[] = [] + ): Promise<string[]> { return new Promise<string[]>((resolve, reject) => { fs.readdir(root, async (err, files) => { if (err != null) { @@ -348,7 +423,12 @@ export class GitService extends Disposable { const nextFileName = await this.findNextFileName(repoPath, fileName, ref); if (nextFileName) { - log = await this.getLogForFile(repoPath, nextFileName, { maxCount: 1, ref: ref, renames: true, reverse: true }); + log = await this.getLogForFile(repoPath, nextFileName, { + maxCount: 1, + ref: ref, + renames: true, + reverse: true + }); commit = log && Iterables.first(log.commits.values()); } @@ -382,8 +462,16 @@ export class GitService extends Disposable { } async findWorkingFileName(commit: GitCommit): Promise<[string | undefined, string | undefined]>; - async findWorkingFileName(fileName: string, repoPath?: string, ref?: string): Promise<[string | undefined, string | undefined]>; - async findWorkingFileName(commitOrFileName: GitCommit | string, repoPath?: string, ref?: string): Promise<[string | undefined, string | undefined]> { + async findWorkingFileName( + fileName: string, + repoPath?: string, + ref?: string + ): Promise<[string | undefined, string | undefined]>; + async findWorkingFileName( + commitOrFileName: GitCommit | string, + repoPath?: string, + ref?: string + ): Promise<[string | undefined, string | undefined]> { let fileName; if (typeof commitOrFileName === 'string') { fileName = commitOrFileName; @@ -398,7 +486,9 @@ export class GitService extends Disposable { else { const c = commitOrFileName; repoPath = c.repoPath; - if (c.workingFileName && await this.fileExists(repoPath, c.workingFileName)) return [c.workingFileName, repoPath]; + if (c.workingFileName && (await this.fileExists(repoPath, c.workingFileName))) { + return [c.workingFileName, repoPath]; + } fileName = c.fileName; } @@ -474,7 +564,11 @@ export class GitService extends Disposable { return promise; } - private async getBlameForFileCore(uri: GitUri, document: TrackedDocument<GitDocumentState>, key: string): Promise<GitBlame | undefined> { + private async getBlameForFileCore( + uri: GitUri, + document: TrackedDocument<GitDocumentState>, + key: string + ): Promise<GitBlame | undefined> { if (!(await this.isTracked(uri))) { Logger.log(`Skipping blame; '${uri.fsPath}' is not tracked`); return GitService.emptyPromise as Promise<GitBlame>; @@ -483,15 +577,10 @@ export class GitService extends Disposable { const [file, root] = Git.splitPath(uri.fsPath, uri.repoPath, false); try { - const data = await Git.blame( - root, - file, - uri.sha, - { - args: Container.config.advanced.blame.customArguments, - ignoreWhitespace: Container.config.blame.ignoreWhitespace - } - ); + const data = await Git.blame(root, file, uri.sha, { + args: Container.config.advanced.blame.customArguments, + ignoreWhitespace: Container.config.blame.ignoreWhitespace + }); const blame = GitBlameParser.parse(data, root, file, await this.getCurrentUsername(root)); return blame; } @@ -523,7 +612,9 @@ export class GitService extends Disposable { if (doc.state !== undefined) { const cachedBlame = doc.state.get<CachedBlame>(key); if (cachedBlame !== undefined) { - Logger.log(`getBlameForFileContents[Cached(${key})]('${uri.repoPath}', '${uri.fsPath}', '${uri.sha}')`); + Logger.log( + `getBlameForFileContents[Cached(${key})]('${uri.repoPath}', '${uri.fsPath}', '${uri.sha}')` + ); return cachedBlame.item; } } @@ -551,7 +642,12 @@ export class GitService extends Disposable { return promise; } - async getBlameForFileContentsCore(uri: GitUri, contents: string, document: TrackedDocument<GitDocumentState>, key: string): Promise<GitBlame | undefined> { + async getBlameForFileContentsCore( + uri: GitUri, + contents: string, + document: TrackedDocument<GitDocumentState>, + key: string + ): Promise<GitBlame | undefined> { if (!(await this.isTracked(uri))) { Logger.log(`Skipping blame; '${uri.fsPath}' is not tracked`); return GitService.emptyPromise as Promise<GitBlame>; @@ -560,16 +656,11 @@ export class GitService extends Disposable { const [file, root] = Git.splitPath(uri.fsPath, uri.repoPath, false); try { - const data = await Git.blame_contents( - root, - file, - contents, - { - args: Container.config.advanced.blame.customArguments, - correlationKey: `:${key}`, - ignoreWhitespace: Container.config.blame.ignoreWhitespace - } - ); + const data = await Git.blame_contents(root, file, contents, { + args: Container.config.advanced.blame.customArguments, + correlationKey: `:${key}`, + ignoreWhitespace: Container.config.blame.ignoreWhitespace + }); const blame = GitBlameParser.parse(data, root, file, await this.getCurrentUsername(root)); return blame; } @@ -592,7 +683,11 @@ export class GitService extends Disposable { } } - async getBlameForLine(uri: GitUri, line: number, options: { skipCache?: boolean } = {}): Promise<GitBlameLine | undefined> { + async getBlameForLine( + uri: GitUri, + line: number, + options: { skipCache?: boolean } = {} + ): Promise<GitBlameLine | undefined> { Logger.log(`getBlameForLine('${uri.repoPath}', '${uri.fsPath}', '${uri.sha}', ${line})`); if (!options.skipCache && this.UseCaching) { @@ -619,18 +714,18 @@ export class GitService extends Disposable { const fileName = uri.fsPath; try { - const data = await Git.blame( + const data = await Git.blame(uri.repoPath, fileName, uri.sha, { + args: Container.config.advanced.blame.customArguments, + ignoreWhitespace: Container.config.blame.ignoreWhitespace, + startLine: lineToBlame, + endLine: lineToBlame + }); + const blame = GitBlameParser.parse( + data, uri.repoPath, fileName, - uri.sha, - { - args: Container.config.advanced.blame.customArguments, - ignoreWhitespace: Container.config.blame.ignoreWhitespace, - startLine: lineToBlame, - endLine: lineToBlame - } + await this.getCurrentUsername(uri.repoPath!) ); - const blame = GitBlameParser.parse(data, uri.repoPath, fileName, await this.getCurrentUsername(uri.repoPath!)); if (blame === undefined) return undefined; return { @@ -644,7 +739,12 @@ export class GitService extends Disposable { } } - async getBlameForLineContents(uri: GitUri, line: number, contents: string, options: { skipCache?: boolean } = {}): Promise<GitBlameLine | undefined> { + async getBlameForLineContents( + uri: GitUri, + line: number, + contents: string, + options: { skipCache?: boolean } = {} + ): Promise<GitBlameLine | undefined> { Logger.log(`getBlameForLineContents('${uri.repoPath}', '${uri.fsPath}', ${line})`); if (!options.skipCache && this.UseCaching) { @@ -671,17 +771,12 @@ export class GitService extends Disposable { const fileName = uri.fsPath; try { - const data = await Git.blame_contents( - uri.repoPath, - fileName, - contents, - { - args: Container.config.advanced.blame.customArguments, - ignoreWhitespace: Container.config.blame.ignoreWhitespace, - startLine: lineToBlame, - endLine: lineToBlame - } - ); + const data = await Git.blame_contents(uri.repoPath, fileName, contents, { + args: Container.config.advanced.blame.customArguments, + ignoreWhitespace: Container.config.blame.ignoreWhitespace, + startLine: lineToBlame, + endLine: lineToBlame + }); const currentUser = await this.getCurrentUsername(uri.repoPath!); const blame = GitBlameParser.parse(data, uri.repoPath, fileName, currentUser); if (blame === undefined) return undefined; @@ -698,7 +793,11 @@ export class GitService extends Disposable { } async getBlameForRange(uri: GitUri, range: Range): Promise<GitBlameLines | undefined> { - Logger.log(`getBlameForRange('${uri.repoPath}', '${uri.fsPath}', '${uri.sha}', [${range.start.line}, ${range.end.line}])`); + Logger.log( + `getBlameForRange('${uri.repoPath}', '${uri.fsPath}', '${uri.sha}', [${range.start.line}, ${ + range.end.line + }])` + ); const blame = await this.getBlameForFile(uri); if (blame === undefined) return undefined; @@ -707,7 +806,11 @@ export class GitService extends Disposable { } getBlameForRangeSync(blame: GitBlame, uri: GitUri, range: Range): GitBlameLines | undefined { - Logger.log(`getBlameForRangeSync('${uri.repoPath}', '${uri.fsPath}', '${uri.sha}', [${range.start.line}, ${range.end.line}])`); + Logger.log( + `getBlameForRangeSync('${uri.repoPath}', '${uri.fsPath}', '${uri.sha}', [${range.start.line}, ${ + range.end.line + }])` + ); if (blame.lines.length === 0) return { allLines: blame.lines, ...blame }; @@ -723,7 +826,9 @@ export class GitService extends Disposable { for (const c of blame.commits.values()) { if (!shas.has(c.sha)) continue; - const commit = c.with({ lines: c.lines.filter(l => l.line >= range.start.line && l.line <= range.end.line) }); + const commit = c.with({ + lines: c.lines.filter(l => l.line >= range.start.line && l.line <= range.end.line) + }); commits.set(c.sha, commit); let author = authors.get(commit.author); @@ -818,7 +923,9 @@ export class GitService extends Disposable { if (doc.state !== undefined) { const cachedDiff = doc.state.get<CachedDiff>(key); if (cachedDiff !== undefined) { - Logger.log(`getDiffForFile[Cached(${key})]('${uri.repoPath}', '${uri.fsPath}', '${sha1}', '${sha2}')`); + Logger.log( + `getDiffForFile[Cached(${key})]('${uri.repoPath}', '${uri.fsPath}', '${sha1}', '${sha2}')` + ); return cachedDiff.item; } } @@ -833,7 +940,15 @@ export class GitService extends Disposable { Logger.log(`getDiffForFile('${uri.repoPath}', '${uri.fsPath}', '${sha1}', '${sha2}')`); } - const promise = this.getDiffForFileCore(uri.repoPath, uri.fsPath, sha1, sha2, { encoding: GitService.getEncoding(uri) }, doc, key); + const promise = this.getDiffForFileCore( + uri.repoPath, + uri.fsPath, + sha1, + sha2, + { encoding: GitService.getEncoding(uri) }, + doc, + key + ); if (doc.state !== undefined) { Logger.log(`Add log cache for '${doc.state.key}:${key}'`); @@ -846,7 +961,15 @@ export class GitService extends Disposable { return promise; } - private async getDiffForFileCore(repoPath: string | undefined, fileName: string, sha1: string | undefined, sha2: string | undefined, options: { encoding?: string }, document: TrackedDocument<GitDocumentState>, key: string): Promise<GitDiff | undefined> { + private async getDiffForFileCore( + repoPath: string | undefined, + fileName: string, + sha1: string | undefined, + sha2: string | undefined, + options: { encoding?: string }, + document: TrackedDocument<GitDocumentState>, + key: string + ): Promise<GitDiff | undefined> { const [file, root] = Git.splitPath(fileName, repoPath, false); try { @@ -872,7 +995,12 @@ export class GitService extends Disposable { } } - async getDiffForLine(uri: GitUri, line: number, sha1?: string, sha2?: string): Promise<GitDiffChunkLine | undefined> { + async getDiffForLine( + uri: GitUri, + line: number, + sha1?: string, + sha2?: string + ): Promise<GitDiffChunkLine | undefined> { Logger.log(`getDiffForLine('${uri.repoPath}', '${uri.fsPath}', ${line}, '${sha1}', '${sha2}')`); try { @@ -889,7 +1017,12 @@ export class GitService extends Disposable { } } - async getDiffStatus(repoPath: string, sha1?: string, sha2?: string, options: { filter?: string } = {}): Promise<GitStatusFile[] | undefined> { + async getDiffStatus( + repoPath: string, + sha1?: string, + sha2?: string, + options: { filter?: string } = {} + ): Promise<GitStatusFile[] | undefined> { Logger.log(`getDiffStatus('${repoPath}', '${sha1}', '${sha2}', ${options.filter})`); try { @@ -919,7 +1052,11 @@ export class GitService extends Disposable { return log.commits.get(ref); } - async getLogCommitForFile(repoPath: string | undefined, fileName: string, options: { ref?: string, firstIfNotFound?: boolean } = {}): Promise<GitLogCommit | undefined> { + async getLogCommitForFile( + repoPath: string | undefined, + fileName: string, + options: { ref?: string; firstIfNotFound?: boolean } = {} + ): Promise<GitLogCommit | undefined> { Logger.log(`getFileLogCommit('${repoPath}', '${fileName}', '${options.ref}', ${options.firstIfNotFound})`); const log = await this.getLogForFile(repoPath, fileName, { maxCount: 2, ref: options.ref }); @@ -934,14 +1071,15 @@ export class GitService extends Disposable { return commit || Iterables.first(log.commits.values()); } - async getLog(repoPath: string, options: { maxCount?: number, ref?: string, reverse?: boolean } = {}): Promise<GitLog | undefined> { + async getLog( + repoPath: string, + options: { maxCount?: number; ref?: string; reverse?: boolean } = {} + ): Promise<GitLog | undefined> { options = { reverse: false, ...options }; Logger.log(`getLog('${repoPath}', '${options.ref}', ${options.maxCount}, ${options.reverse})`); - const maxCount = options.maxCount == null - ? Container.config.advanced.maxListItems || 0 - : options.maxCount; + const maxCount = options.maxCount == null ? Container.config.advanced.maxListItems || 0 : options.maxCount; try { const data = await Git.log(repoPath, { maxCount: maxCount, ref: options.ref, reverse: options.reverse }); @@ -969,12 +1107,15 @@ export class GitService extends Disposable { } } - async getLogForSearch(repoPath: string, search: string, searchBy: GitRepoSearchBy, options: { maxCount?: number } = {}): Promise<GitLog | undefined> { + async getLogForSearch( + repoPath: string, + search: string, + searchBy: GitRepoSearchBy, + options: { maxCount?: number } = {} + ): Promise<GitLog | undefined> { Logger.log(`getLogForSearch('${repoPath}', '${search}', '${searchBy}', ${options.maxCount})`); - let maxCount = options.maxCount == null - ? Container.config.advanced.maxListItems || 0 - : options.maxCount; + let maxCount = options.maxCount == null ? Container.config.advanced.maxListItems || 0 : options.maxCount; let searchArgs: string[] | undefined = undefined; switch (searchBy) { @@ -1015,7 +1156,8 @@ export class GitService extends Disposable { if (log !== undefined) { const opts = { ...options }; - log.query = (maxCount: number | undefined) => this.getLogForSearch(repoPath, search, searchBy, { ...opts, maxCount: maxCount }); + log.query = (maxCount: number | undefined) => + this.getLogForSearch(repoPath, search, searchBy, { ...opts, maxCount: maxCount }); } return log; @@ -1025,8 +1167,14 @@ export class GitService extends Disposable { } } - async getLogForFile(repoPath: string | undefined, fileName: string, options: { maxCount?: number, range?: Range, ref?: string, renames?: boolean, reverse?: boolean } = {}): Promise<GitLog | undefined> { - if (repoPath !== undefined && repoPath === Strings.normalizePath(fileName)) throw new Error(`File name cannot match the repository path; fileName=${fileName}`); + async getLogForFile( + repoPath: string | undefined, + fileName: string, + options: { maxCount?: number; range?: Range; ref?: string; renames?: boolean; reverse?: boolean } = {} + ): Promise<GitLog | undefined> { + if (repoPath !== undefined && repoPath === Strings.normalizePath(fileName)) { + throw new Error(`File name cannot match the repository path; fileName=${fileName}`); + } options = { reverse: false, ...options }; @@ -1045,12 +1193,18 @@ export class GitService extends Disposable { key += `:follow`; } - const doc = await Container.tracker.getOrAdd(new GitUri(Uri.file(fileName), { repoPath: repoPath!, sha: options.ref })); + const doc = await Container.tracker.getOrAdd( + new GitUri(Uri.file(fileName), { repoPath: repoPath!, sha: options.ref }) + ); if (this.UseCaching && options.range === undefined && !options.reverse) { if (doc.state !== undefined) { const cachedLog = doc.state.get<CachedLog>(key); if (cachedLog !== undefined) { - Logger.log(`getLogForFile[Cached(${key})]('${repoPath}', '${fileName}', '${options.ref}', ${options.maxCount}, undefined, ${options.renames}, ${options.reverse})`); + Logger.log( + `getLogForFile[Cached(${key})]('${repoPath}', '${fileName}', '${options.ref}', ${ + options.maxCount + }, undefined, ${options.renames}, ${options.reverse})` + ); return cachedLog.item; } @@ -1059,28 +1213,47 @@ export class GitService extends Disposable { const cachedLog = doc.state.get<CachedLog>('log'); if (cachedLog !== undefined) { if (options.ref === undefined) { - Logger.log(`getLogForFile[Cached(~${key})]('${repoPath}', '${fileName}', '', ${options.maxCount}, undefined, ${options.renames}, ${options.reverse})`); + Logger.log( + `getLogForFile[Cached(~${key})]('${repoPath}', '${fileName}', '', ${ + options.maxCount + }, undefined, ${options.renames}, ${options.reverse})` + ); return cachedLog.item; } - Logger.log(`getLogForFile[? Cache(${key})]('${repoPath}', '${fileName}', '${options.ref}', ${options.maxCount}, undefined, ${options.renames}, ${options.reverse})`); + Logger.log( + `getLogForFile[? Cache(${key})]('${repoPath}', '${fileName}', '${options.ref}', ${ + options.maxCount + }, undefined, ${options.renames}, ${options.reverse})` + ); const log = await cachedLog.item; if (log !== undefined && log.commits.has(options.ref)) { - Logger.log(`getLogForFile[Cached(${key})]('${repoPath}', '${fileName}', '${options.ref}', ${options.maxCount}, undefined, ${options.renames}, ${options.reverse})`); + Logger.log( + `getLogForFile[Cached(${key})]('${repoPath}', '${fileName}', '${options.ref}', ${ + options.maxCount + }, undefined, ${options.renames}, ${options.reverse})` + ); return cachedLog.item; } } } } - Logger.log(`getLogForFile[Not Cached(${key})]('${repoPath}', '${fileName}', ${options.ref}, ${options.maxCount}, undefined, ${options.reverse})`); + Logger.log( + `getLogForFile[Not Cached(${key})]('${repoPath}', '${fileName}', ${options.ref}, ${ + options.maxCount + }, undefined, ${options.reverse})` + ); if (doc.state === undefined) { doc.state = new GitDocumentState(doc.key); } } else { - Logger.log(`getLogForFile('${repoPath}', '${fileName}', ${options.ref}, ${options.maxCount}, ${options.range && `[${options.range.start.line}, ${options.range.end.line}]`}, ${options.reverse})`); + Logger.log( + `getLogForFile('${repoPath}', '${fileName}', ${options.ref}, ${options.maxCount}, ${options.range && + `[${options.range.start.line}, ${options.range.end.line}]`}, ${options.reverse})` + ); } const promise = this.getLogForFileCore(repoPath, fileName, options, doc, key); @@ -1096,7 +1269,13 @@ export class GitService extends Disposable { return promise; } - private async getLogForFileCore(repoPath: string | undefined, fileName: string, options: { maxCount?: number, range?: Range, ref?: string, renames?: boolean, reverse?: boolean }, document: TrackedDocument<GitDocumentState>, key: string): Promise<GitLog | undefined> { + private async getLogForFileCore( + repoPath: string | undefined, + fileName: string, + options: { maxCount?: number; range?: Range; ref?: string; renames?: boolean; reverse?: boolean }, + document: TrackedDocument<GitDocumentState>, + key: string + ): Promise<GitLog | undefined> { if (!(await this.isTracked(fileName, repoPath, { ref: options.ref }))) { Logger.log(`Skipping log; '${fileName}' is not tracked`); return GitService.emptyPromise as Promise<GitLog>; @@ -1107,11 +1286,14 @@ export class GitService extends Disposable { try { const { range, ...opts } = options; - const maxCount = options.maxCount == null - ? Container.config.advanced.maxListItems || 0 - : options.maxCount; + const maxCount = options.maxCount == null ? Container.config.advanced.maxListItems || 0 : options.maxCount; - const data = await Git.log_file(root, file, { ...opts, maxCount: maxCount, startLine: range && range.start.line + 1, endLine: range && range.end.line + 1 }); + const data = await Git.log_file(root, file, { + ...opts, + maxCount: maxCount, + startLine: range && range.start.line + 1, + endLine: range && range.end.line + 1 + }); const log = GitLogParser.parse( data, GitCommitType.File, @@ -1126,7 +1308,8 @@ export class GitService extends Disposable { if (log !== undefined) { const opts = { ...options }; - log.query = (maxCount: number | undefined) => this.getLogForFile(repoPath, fileName, { ...opts, maxCount: maxCount }); + log.query = (maxCount: number | undefined) => + this.getLogForFile(repoPath, fileName, { ...opts, maxCount: maxCount }); } return log; @@ -1186,9 +1369,7 @@ export class GitService extends Disposable { Logger.log(`getRemotes('${repoPath}')`); const repository = await this.getRepository(repoPath); - const remotes = repository !== undefined - ? repository.getRemotes() - : this.getRemotesCore(repoPath); + const remotes = repository !== undefined ? repository.getRemotes() : this.getRemotesCore(repoPath); if (options.includeAll) return remotes; @@ -1200,7 +1381,11 @@ export class GitService extends Disposable { Logger.log(`getRemotesCore('${repoPath}')`); - providerMap = providerMap || RemoteProviderFactory.createMap(configuration.get<IRemotesConfig[] | null | undefined>(configuration.name('remotes').value, null)); + providerMap = + providerMap || + RemoteProviderFactory.createMap( + configuration.get<IRemotesConfig[] | null | undefined>(configuration.name('remotes').value, null) + ); try { const data = await Git.remote(repoPath); @@ -1214,7 +1399,10 @@ export class GitService extends Disposable { async getRepoPath(filePath: string, options?: { ref?: string }): Promise<string | undefined>; async getRepoPath(uri: Uri | undefined, options?: { ref?: string }): Promise<string | undefined>; - async getRepoPath(filePathOrUri: string | Uri | undefined, options: { ref?: string } = {}): Promise<string | undefined> { + async getRepoPath( + filePathOrUri: string | Uri | undefined, + options: { ref?: string } = {} + ): Promise<string | undefined> { if (filePathOrUri == null) return await this.getActiveRepoPath(); if (filePathOrUri instanceof GitUri) return filePathOrUri.repoPath; @@ -1227,7 +1415,10 @@ export class GitService extends Disposable { if (versionedUri !== undefined) return versionedUri.repoPath; } - const rp = await this.getRepoPathCore(typeof filePathOrUri === 'string' ? filePathOrUri : filePathOrUri.fsPath, false); + const rp = await this.getRepoPathCore( + typeof filePathOrUri === 'string' ? filePathOrUri : filePathOrUri.fsPath, + false + ); if (rp === undefined) return undefined; // Recheck this._repositoryTree.get(rp) to make sure we haven't already tried adding this due to awaits @@ -1235,9 +1426,7 @@ export class GitService extends Disposable { // If this new repo is inside one of our known roots and we we don't already know about, add it const root = this._repositoryTree.findSubstr(rp); - let folder = root === undefined - ? workspace.getWorkspaceFolder(Uri.file(rp)) - : root.folder; + let folder = root === undefined ? workspace.getWorkspaceFolder(Uri.file(rp)) : root.folder; if (folder === undefined) { const parts = rp.split('/'); @@ -1278,9 +1467,7 @@ export class GitService extends Disposable { const repositoryTree = await this.getRepositoryTree(); const values = repositoryTree.values(); - return predicate !== undefined - ? Iterables.filter(values, predicate) - : values; + return predicate !== undefined ? Iterables.filter(values, predicate) : values; } private async getRepositoryTree(): Promise<TernarySearchTree<Repository>> { @@ -1292,10 +1479,22 @@ export class GitService extends Disposable { return this._repositoryTree; } - async getRepository(repoPath: string, options?: { ref?: string, skipCacheUpdate?: boolean }): Promise<Repository | undefined>; - async getRepository(uri: Uri, options?: { ref?: string, skipCacheUpdate?: boolean }): Promise<Repository | undefined>; - async getRepository(repoPathOrUri: string | Uri, options?: { ref?: string, skipCacheUpdate?: boolean }): Promise<Repository | undefined>; - async getRepository(repoPathOrUri: string | Uri, options: { ref?: string, skipCacheUpdate?: boolean } = {}): Promise<Repository | undefined> { + async getRepository( + repoPath: string, + options?: { ref?: string; skipCacheUpdate?: boolean } + ): Promise<Repository | undefined>; + async getRepository( + uri: Uri, + options?: { ref?: string; skipCacheUpdate?: boolean } + ): Promise<Repository | undefined>; + async getRepository( + repoPathOrUri: string | Uri, + options?: { ref?: string; skipCacheUpdate?: boolean } + ): Promise<Repository | undefined>; + async getRepository( + repoPathOrUri: string | Uri, + options: { ref?: string; skipCacheUpdate?: boolean } = {} + ): Promise<Repository | undefined> { const repositoryTree = await this.getRepositoryTree(); let path: string; @@ -1323,7 +1522,7 @@ export class GitService extends Disposable { if (repo === undefined) return undefined; // Make sure the file is tracked in this repo before returning -- it could be from a submodule - if (!await this.isTracked(path, repo.path, options)) return undefined; + if (!(await this.isTracked(path, repo.path, options))) return undefined; return repo; } @@ -1389,7 +1588,10 @@ export class GitService extends Disposable { const file = await Git.getVersionedFile(repoPath, fileName, sha); if (file === undefined) return undefined; - this._versionedUriCache.set(GitUri.toKey(file), new GitUri(Uri.file(fileName), { sha: sha, repoPath: repoPath!, versionedPath: file })); + this._versionedUriCache.set( + GitUri.toKey(file), + new GitUri(Uri.file(fileName), { sha: sha, repoPath: repoPath!, versionedPath: file }) + ); return file; } @@ -1415,12 +1617,22 @@ export class GitService extends Disposable { scheme = schemeOruri.scheme; } - return scheme === DocumentSchemes.File || scheme === DocumentSchemes.Git || scheme === DocumentSchemes.GitLensGit; + return ( + scheme === DocumentSchemes.File || scheme === DocumentSchemes.Git || scheme === DocumentSchemes.GitLensGit + ); } - async isTracked(fileName: string, repoPath?: string, options?: { ref?: string, skipCacheUpdate?: boolean }): Promise<boolean>; + async isTracked( + fileName: string, + repoPath?: string, + options?: { ref?: string; skipCacheUpdate?: boolean } + ): Promise<boolean>; async isTracked(uri: GitUri): Promise<boolean>; - async isTracked(fileNameOrUri: string | GitUri, repoPath?: string, options: { ref?: string, skipCacheUpdate?: boolean } = {}): Promise<boolean> { + async isTracked( + fileNameOrUri: string | GitUri, + repoPath?: string, + options: { ref?: string; skipCacheUpdate?: boolean } = {} + ): Promise<boolean> { if (options.ref === GitService.deletedSha) return false; let ref = options.ref; @@ -1476,12 +1688,14 @@ export class GitService extends Disposable { try { // Even if we have a sha, check first to see if the file exists (that way the cache will be better reused) - let tracked = !!await Git.ls_files(repoPath === undefined ? '' : repoPath, fileName); + let tracked = !!(await Git.ls_files(repoPath === undefined ? '' : repoPath, fileName)); if (!tracked && ref !== undefined) { - tracked = !!await Git.ls_files(repoPath === undefined ? '' : repoPath, fileName, { ref: ref }); + tracked = !!(await Git.ls_files(repoPath === undefined ? '' : repoPath, fileName, { ref: ref })); // If we still haven't found this file, make sure it wasn't deleted in that sha (i.e. check the previous) if (!tracked) { - tracked = !!await Git.ls_files(repoPath === undefined ? '' : repoPath, fileName, { ref: `${ref}^` }); + tracked = !!(await Git.ls_files(repoPath === undefined ? '' : repoPath, fileName, { + ref: `${ref}^` + })); } } return tracked; @@ -1493,7 +1707,7 @@ export class GitService extends Disposable { } async getDiffTool(repoPath?: string) { - return await Git.config_get('diff.guitool', repoPath) || await Git.config_get('diff.tool', repoPath); + return (await Git.config_get('diff.guitool', repoPath)) || (await Git.config_get('diff.tool', repoPath)); } async openDiffTool(repoPath: string, uri: Uri, staged: boolean, tool?: string) { @@ -1525,7 +1739,9 @@ export class GitService extends Disposable { if (uri == null) return (await Git.revparse(repoPath, ref)) || ref; - return (await Git.log_resolve(repoPath, Strings.normalizePath(path.relative(repoPath, uri.fsPath)), ref)) || ref; + return ( + (await Git.log_resolve(repoPath, Strings.normalizePath(path.relative(repoPath, uri.fsPath)), ref)) || ref + ); } stopWatchingFileSystem() { @@ -1558,9 +1774,7 @@ export class GitService extends Disposable { static getEncoding(repoPath: string, fileName: string): string; static getEncoding(uri: Uri): string; static getEncoding(repoPathOrUri: string | Uri, fileName?: string): string { - const uri = (typeof repoPathOrUri === 'string') - ? Uri.file(path.join(repoPathOrUri, fileName!)) - : repoPathOrUri; + const uri = typeof repoPathOrUri === 'string' ? Uri.file(path.join(repoPathOrUri, fileName!)) : repoPathOrUri; return Git.getEncoding(workspace.getConfiguration('files', uri).get<string>('encoding')); } @@ -1592,7 +1806,10 @@ export class GitService extends Disposable { return Git.isUncommitted(sha); } - static shortenSha(sha: string | undefined, strings: { deleted?: string, stagedUncommitted?: string, uncommitted?: string, working?: string } = {}) { + static shortenSha( + sha: string | undefined, + strings: { deleted?: string; stagedUncommitted?: string; uncommitted?: string; working?: string } = {} + ) { if (sha === undefined) return undefined; strings = { deleted: '(deleted)', working: '', ...strings }; @@ -1600,9 +1817,7 @@ export class GitService extends Disposable { if (sha === '') return strings.working; if (sha === GitService.deletedSha) return strings.deleted; - return Git.isSha(sha) || Git.isStagedUncommitted(sha) - ? Git.shortenSha(sha, strings) - : sha; + return Git.isSha(sha) || Git.isStagedUncommitted(sha) ? Git.shortenSha(sha, strings) : sha; } static compareGitVersion(version: string, throwIfLessThan?: Error) { @@ -1612,7 +1827,9 @@ export class GitService extends Disposable { static ensureGitVersion(version: string, feature: string): void { const gitVersion = this.getGitVersion(); if (Versions.compare(Versions.fromString(gitVersion), Versions.fromString(version)) === -1) { - throw new Error(`${feature} requires a newer version of Git (>= ${version}) than is currently installed (${gitVersion}). Please install a more recent version of Git to use this GitLens feature.`); + throw new Error( + `${feature} requires a newer version of Git (>= ${version}) than is currently installed (${gitVersion}). Please install a more recent version of Git to use this GitLens feature.` + ); } } } diff --git a/src/keyboard.ts b/src/keyboard.ts index 8e50ab5..67178d1 100644 --- a/src/keyboard.ts +++ b/src/keyboard.ts @@ -11,22 +11,15 @@ const keyNoopCommand = Object.create(null) as KeyCommand; export { keyNoopCommand as KeyNoopCommand }; export declare type Keys = 'left' | 'right' | ',' | '.' | 'escape'; -export const keys: Keys[] = [ - 'left', - 'right', - ',', - '.', - 'escape' -]; +export const keys: Keys[] = ['left', 'right', ',', '.', 'escape']; export declare interface KeyMapping { - [id: string]: (KeyCommand | (() => Promise<KeyCommand>) | undefined); + [id: string]: KeyCommand | (() => Promise<KeyCommand>) | undefined; } const mappings: KeyMapping[] = []; export class KeyboardScope extends Disposable { - constructor( private readonly mapping: KeyMapping ) { @@ -40,7 +33,7 @@ export class KeyboardScope extends Disposable { async dispose() { const index = mappings.indexOf(this.mapping); Logger.log('KeyboardScope.dispose', mappings.length, index); - if (index === (mappings.length - 1)) { + if (index === mappings.length - 1) { mappings.pop(); await this.updateKeyCommandsContext(mappings[mappings.length - 1]); } @@ -89,13 +82,14 @@ export class KeyboardScope extends Disposable { } export class Keyboard extends Disposable { - private _disposable: Disposable; constructor() { super(() => this.dispose()); - const subscriptions = keys.map(key => commands.registerCommand(`${extensionId}.key.${key}`, () => this.execute(key), this)); + const subscriptions = keys.map(key => + commands.registerCommand(`${extensionId}.key.${key}`, () => this.execute(key), this) + ); this._disposable = Disposable.from(...subscriptions); } @@ -105,7 +99,9 @@ export class Keyboard extends Disposable { async beginScope(mapping?: KeyMapping): Promise<KeyboardScope> { Logger.log('Keyboard.beginScope', mappings.length); - return await new KeyboardScope(mapping ? Object.assign(Object.create(null), mapping) : Object.create(null)).begin(); + return await new KeyboardScope( + mapping ? Object.assign(Object.create(null), mapping) : Object.create(null) + ).begin(); } async execute(key: Keys): Promise<{} | undefined> { diff --git a/src/logger.ts b/src/logger.ts index ece1b6e..d7e54ff 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -9,7 +9,6 @@ const ConsolePrefix = `[${extensionOutputChannelName}]`; const isDebuggingRegex = /^--inspect(-brk)?=?/; export class Logger { - static level: OutputLevel = OutputLevel.Silent; static output: OutputChannel | undefined; @@ -45,7 +44,9 @@ export class Logger { } if (this.output !== undefined) { - this.output.appendLine((Logger.isDebugging ? [this.timestamp, message, ...params] : [message, ...params]).join(' ')); + this.output.appendLine( + (Logger.isDebugging ? [this.timestamp, message, ...params] : [message, ...params]).join(' ') + ); } } @@ -57,7 +58,12 @@ export class Logger { } if (this.output !== undefined) { - this.output.appendLine((Logger.isDebugging ? [this.timestamp, classOrMethod, ...params, ex] : [classOrMethod, ...params, ex]).join(' ')); + this.output.appendLine( + (Logger.isDebugging + ? [this.timestamp, classOrMethod, ...params, ex] + : [classOrMethod, ...params, ex] + ).join(' ') + ); } // Telemetry.trackException(ex); @@ -71,13 +77,19 @@ export class Logger { } if (this.output !== undefined) { - this.output.appendLine((Logger.isDebugging ? [this.timestamp, message, ...params] : [message, ...params]).join(' ')); + this.output.appendLine( + (Logger.isDebugging ? [this.timestamp, message, ...params] : [message, ...params]).join(' ') + ); } } private static get timestamp(): string { const now = new Date(); - return `[${now.toISOString().replace(/T/, ' ').replace(/\..+/, '')}:${('00' + now.getUTCMilliseconds()).slice(-3)}]`; + const time = now + .toISOString() + .replace(/T/, ' ') + .replace(/\..+/, ''); + return `[${time}:${('00' + now.getUTCMilliseconds()).slice(-3)}]`; } static gitOutput: OutputChannel | undefined; @@ -88,7 +100,9 @@ export class Logger { if (this.gitOutput === undefined) { this.gitOutput = window.createOutputChannel(`${extensionOutputChannelName} (Git)`); } - this.gitOutput.appendLine(`${this.timestamp} ${command} (${cwd})${ex === undefined ? '' : `\n\n${ex.toString()}`}`); + this.gitOutput.appendLine( + `${this.timestamp} ${command} (${cwd})${ex === undefined ? '' : `\n\n${ex.toString()}`}` + ); } private static _isDebugging: boolean | undefined; @@ -97,10 +111,9 @@ export class Logger { try { const args = process.execArgv; - this._isDebugging = args - ? args.some(arg => isDebuggingRegex.test(arg)) - : false; - } catch { } + this._isDebugging = args ? args.some(arg => isDebuggingRegex.test(arg)) : false; + } + catch {} } return this._isDebugging; diff --git a/src/messages.ts b/src/messages.ts index 2f77c8c..6c9afc0 100644 --- a/src/messages.ts +++ b/src/messages.ts @@ -17,26 +17,51 @@ export enum SuppressedMessages { } export class Messages { - static showCommitHasNoPreviousCommitWarningMessage(commit?: GitCommit): Promise<MessageItem | undefined> { - if (commit === undefined) return Messages.showMessage('info', `Commit has no previous commit.`, SuppressedMessages.CommitHasNoPreviousCommitWarning); - return Messages.showMessage('info', `Commit ${commit.shortSha} (${commit.author}, ${commit.formattedDate}) has no previous commit.`, SuppressedMessages.CommitHasNoPreviousCommitWarning); + if (commit === undefined) { + return Messages.showMessage( + 'info', + `Commit has no previous commit.`, + SuppressedMessages.CommitHasNoPreviousCommitWarning + ); + } + return Messages.showMessage( + 'info', + `Commit ${commit.shortSha} (${commit.author}, ${commit.formattedDate}) has no previous commit.`, + SuppressedMessages.CommitHasNoPreviousCommitWarning + ); } static showCommitNotFoundWarningMessage(message: string): Promise<MessageItem | undefined> { - return Messages.showMessage('warn', `${message}. The commit could not be found.`, SuppressedMessages.CommitNotFoundWarning); + return Messages.showMessage( + 'warn', + `${message}. The commit could not be found.`, + SuppressedMessages.CommitNotFoundWarning + ); } static showFileNotUnderSourceControlWarningMessage(message: string): Promise<MessageItem | undefined> { - return Messages.showMessage('warn', `${message}. The file is probably not under source control.`, SuppressedMessages.FileNotUnderSourceControlWarning); + return Messages.showMessage( + 'warn', + `${message}. The file is probably not under source control.`, + SuppressedMessages.FileNotUnderSourceControlWarning + ); } static showGitDisabledErrorMessage() { - return Messages.showMessage('error', `GitLens requires Git to be enabled. Please re-enable Git \u2014 set \`git.enabled\` to true and reload`, SuppressedMessages.GitDisabledWarning); + return Messages.showMessage( + 'error', + `GitLens requires Git to be enabled. Please re-enable Git \u2014 set \`git.enabled\` to true and reload`, + SuppressedMessages.GitDisabledWarning + ); } static showGitVersionUnsupportedErrorMessage(version: string): Promise<MessageItem | undefined> { - 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.`, SuppressedMessages.GitVersionWarning); + 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.`, + SuppressedMessages.GitVersionWarning + ); } static async showKeyBindingsInfoMessage(): Promise<MessageItem | undefined> { @@ -63,7 +88,11 @@ export class Messages { switch (result) { case actions[1]: - await configuration.update(configuration.name('keymap').value, KeyMap.Chorded, ConfigurationTarget.Global); + await configuration.update( + configuration.name('keymap').value, + KeyMap.Chorded, + ConfigurationTarget.Global + ); break; case actions[2]: @@ -75,14 +104,28 @@ export class Messages { } static showLineUncommittedWarningMessage(message: string): Promise<MessageItem | undefined> { - return Messages.showMessage('warn', `${message}. The line has uncommitted changes.`, SuppressedMessages.LineUncommittedWarning); + return Messages.showMessage( + 'warn', + `${message}. The line has uncommitted changes.`, + SuppressedMessages.LineUncommittedWarning + ); } static showNoRepositoryWarningMessage(message: string): Promise<MessageItem | undefined> { - return Messages.showMessage('warn', `${message}. No repository could be found.`, SuppressedMessages.NoRepositoryWarning); + return Messages.showMessage( + 'warn', + `${message}. No repository could be found.`, + SuppressedMessages.NoRepositoryWarning + ); } - private static async showMessage<T extends MessageItem>(type: 'info' | 'warn' | 'error', message: string, suppressionKey: SuppressedMessages, dontShowAgain: T | null = { title: 'Don\'t Show Again' } as T, ...actions: T[]): Promise<T | undefined> { + private static async showMessage<T extends MessageItem>( + type: 'info' | 'warn' | 'error', + message: string, + suppressionKey: SuppressedMessages, + dontShowAgain: T | null = { title: "Don't Show Again" } as T, + ...actions: T[] + ): Promise<T | undefined> { Logger.log(`ShowMessage(${type}, '${message}', ${suppressionKey}, ${dontShowAgain})`); if (configuration.get<boolean>(configuration.name('advanced')('messages')(suppressionKey).value)) { @@ -110,13 +153,19 @@ export class Messages { } if (dontShowAgain === null || result === dontShowAgain) { - Logger.log(`ShowMessage(${type}, '${message}', ${suppressionKey}, ${dontShowAgain}) don't show again requested`); + Logger.log( + `ShowMessage(${type}, '${message}', ${suppressionKey}, ${dontShowAgain}) don't show again requested` + ); await this.suppressedMessage(suppressionKey); if (result === dontShowAgain) return undefined; } - Logger.log(`ShowMessage(${type}, '${message}', ${suppressionKey}, ${dontShowAgain}) returned ${result ? result.title : result}`); + Logger.log( + `ShowMessage(${type}, '${message}', ${suppressionKey}, ${dontShowAgain}) returned ${ + result ? result.title : result + }` + ); return result; } @@ -134,4 +183,4 @@ export class Messages { return configuration.update(section, messages, ConfigurationTarget.Global); } -} \ No newline at end of file +} diff --git a/src/quickPicks/branchHistoryQuickPick.ts b/src/quickPicks/branchHistoryQuickPick.ts index 2290d40..0c61dce 100644 --- a/src/quickPicks/branchHistoryQuickPick.ts +++ b/src/quickPicks/branchHistoryQuickPick.ts @@ -2,7 +2,12 @@ import { Iterables, Strings } from '../system'; import { CancellationTokenSource, QuickPickOptions, window } from 'vscode'; import { Commands, ShowCommitSearchCommandArgs, ShowQuickBranchHistoryCommandArgs } from '../commands'; -import { CommandQuickPickItem, CommitQuickPickItem, getQuickPickIgnoreFocusOut, showQuickPickProgress } from './commonQuickPicks'; +import { + CommandQuickPickItem, + CommitQuickPickItem, + getQuickPickIgnoreFocusOut, + showQuickPickProgress +} from './commonQuickPicks'; import { GlyphChars } from '../constants'; import { Container } from '../container'; import { GitLog, GitUri, RemoteResource } from '../gitService'; @@ -10,23 +15,38 @@ import { KeyNoopCommand } from '../keyboard'; import { OpenRemotesCommandQuickPickItem } from './remotesQuickPick'; export class BranchHistoryQuickPick { - static showProgress(branch: string) { - return showQuickPickProgress(`${branch} history ${GlyphChars.Dash} search by commit message, filename, or commit id`, + return showQuickPickProgress( + `${branch} history ${GlyphChars.Dash} search by commit message, filename, or commit id`, { left: KeyNoopCommand, ',': KeyNoopCommand, '.': KeyNoopCommand - }); + } + ); } - static async show(log: GitLog, uri: GitUri | undefined, branch: string, progressCancellation: CancellationTokenSource, goBackCommand?: CommandQuickPickItem, nextPageCommand?: CommandQuickPickItem): Promise<CommitQuickPickItem | CommandQuickPickItem | undefined> { - const items = Array.from(Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c))) as (CommitQuickPickItem | CommandQuickPickItem)[]; - - const currentCommand = new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to ${GlyphChars.Space}$(git-branch) ${branch} history` - }, Commands.ShowQuickBranchHistory, [ + static async show( + log: GitLog, + uri: GitUri | undefined, + branch: string, + progressCancellation: CancellationTokenSource, + goBackCommand?: CommandQuickPickItem, + nextPageCommand?: CommandQuickPickItem + ): Promise<CommitQuickPickItem | CommandQuickPickItem | undefined> { + const items = Array.from(Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c))) as ( + | CommitQuickPickItem + | CommandQuickPickItem)[]; + + const currentCommand = new CommandQuickPickItem( + { + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to ${ + GlyphChars.Space + }$(git-branch) ${branch} history` + }, + Commands.ShowQuickBranchHistory, + [ uri, { branch, @@ -34,41 +54,70 @@ export class BranchHistoryQuickPick { maxCount: log.maxCount, goBackCommand } as ShowQuickBranchHistoryCommandArgs - ]); + ] + ); const remotes = await Container.git.getRemotes((uri && uri.repoPath) || log.repoPath); if (remotes.length) { - items.splice(0, 0, new OpenRemotesCommandQuickPickItem(remotes, { - type: 'branch', - branch - } as RemoteResource, currentCommand)); + items.splice( + 0, + 0, + new OpenRemotesCommandQuickPickItem( + remotes, + { + type: 'branch', + branch + } as RemoteResource, + currentCommand + ) + ); } - items.splice(0, 0, new CommandQuickPickItem({ - label: `$(search) Show Commit Search`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} search for commits by message, author, files, or commit id` - }, Commands.ShowCommitSearch, [ - GitUri.fromRepoPath(log.repoPath), + items.splice( + 0, + 0, + new CommandQuickPickItem( { - goBackCommand: currentCommand - } as ShowCommitSearchCommandArgs - ])); + label: `$(search) Show Commit Search`, + description: `${Strings.pad( + GlyphChars.Dash, + 2, + 3 + )} search for commits by message, author, files, or commit id` + }, + Commands.ShowCommitSearch, + [ + GitUri.fromRepoPath(log.repoPath), + { + goBackCommand: currentCommand + } as ShowCommitSearchCommandArgs + ] + ) + ); let previousPageCommand: CommandQuickPickItem | undefined = undefined; if (log.truncated || log.sha) { if (log.truncated) { - items.splice(0, 0, new CommandQuickPickItem({ - label: `$(sync) Show All Commits`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} this may take a while` - }, Commands.ShowQuickBranchHistory, [ - GitUri.fromRepoPath(log.repoPath), + items.splice( + 0, + 0, + new CommandQuickPickItem( { - branch, - maxCount: 0, - goBackCommand - } as ShowQuickBranchHistoryCommandArgs - ])); + label: `$(sync) Show All Commits`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} this may take a while` + }, + Commands.ShowQuickBranchHistory, + [ + GitUri.fromRepoPath(log.repoPath), + { + branch, + maxCount: 0, + goBackCommand + } as ShowQuickBranchHistoryCommandArgs + ] + ) + ); } if (nextPageCommand) { @@ -76,24 +125,31 @@ export class BranchHistoryQuickPick { } if (log.truncated) { - const npc = new CommandQuickPickItem({ - label: `$(arrow-right) Show Next Commits`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} newer commits` - }, Commands.ShowQuickBranchHistory, [ + const npc = new CommandQuickPickItem( + { + label: `$(arrow-right) Show Next Commits`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} newer commits` + }, + Commands.ShowQuickBranchHistory, + [ uri, { branch, maxCount: log.maxCount, nextPageCommand } as ShowQuickBranchHistoryCommandArgs - ]); + ] + ); const last = Iterables.last(log.commits.values()); if (last != null) { - previousPageCommand = new CommandQuickPickItem({ - label: `$(arrow-left) Show Previous Commits`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} older commits` - }, Commands.ShowQuickBranchHistory, [ + previousPageCommand = new CommandQuickPickItem( + { + label: `$(arrow-left) Show Previous Commits`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${log.maxCount} older commits` + }, + Commands.ShowQuickBranchHistory, + [ new GitUri(uri ? uri : last.uri, last), { branch, @@ -101,7 +157,8 @@ export class BranchHistoryQuickPick { goBackCommand, nextPageCommand: npc } as ShowQuickBranchHistoryCommandArgs - ]); + ] + ); items.splice(0, 0, previousPageCommand); } @@ -136,4 +193,4 @@ export class BranchHistoryQuickPick { return pick; } -} \ No newline at end of file +} diff --git a/src/quickPicks/branchesAndTagsQuickPick.ts b/src/quickPicks/branchesAndTagsQuickPick.ts index e14c2e2..fe9afc7 100644 --- a/src/quickPicks/branchesAndTagsQuickPick.ts +++ b/src/quickPicks/branchesAndTagsQuickPick.ts @@ -7,7 +7,6 @@ import { GitBranch, GitTag } from '../gitService'; import { KeyNoopCommand } from '../keyboard'; export class BranchOrTagQuickPickItem implements QuickPickItem { - label: string; description: string; detail: string | undefined; @@ -16,7 +15,9 @@ export class BranchOrTagQuickPickItem implements QuickPickItem { public readonly branchOrTag: GitBranch | GitTag ) { if (branchOrTag instanceof GitBranch) { - this.label = `${branchOrTag.current ? `$(check)${GlyphChars.Space}` : GlyphChars.Space.repeat(4)} ${branchOrTag.name}`; + this.label = `${branchOrTag.current ? `$(check)${GlyphChars.Space}` : GlyphChars.Space.repeat(4)} ${ + branchOrTag.name + }`; this.description = branchOrTag.remote ? `${GlyphChars.Space.repeat(2)} remote branch` : ''; } else { @@ -35,17 +36,20 @@ export class BranchOrTagQuickPickItem implements QuickPickItem { } export class BranchesAndTagsQuickPick { - static showProgress(placeHolder: string) { - return showQuickPickProgress(placeHolder, - { - left: KeyNoopCommand, - ',': KeyNoopCommand, - '.': KeyNoopCommand - }); + return showQuickPickProgress(placeHolder, { + left: KeyNoopCommand, + ',': KeyNoopCommand, + '.': KeyNoopCommand + }); } - static async show(branches: GitBranch[], tags: GitTag[], placeHolder: string, options: { goBackCommand?: CommandQuickPickItem, progressCancellation?: CancellationTokenSource } = {}): Promise<BranchOrTagQuickPickItem | CommandQuickPickItem | undefined> { + static async show( + branches: GitBranch[], + tags: GitTag[], + placeHolder: string, + options: { goBackCommand?: CommandQuickPickItem; progressCancellation?: CancellationTokenSource } = {} + ): Promise<BranchOrTagQuickPickItem | CommandQuickPickItem | undefined> { const items = [ ...branches.filter(b => !b.remote).map(b => new BranchOrTagQuickPickItem(b)), ...tags.map(t => new BranchOrTagQuickPickItem(t)), @@ -56,20 +60,21 @@ export class BranchesAndTagsQuickPick { items.splice(0, 0, options.goBackCommand); } - if (options.progressCancellation !== undefined && options.progressCancellation.token.isCancellationRequested) return undefined; + if (options.progressCancellation !== undefined && options.progressCancellation.token.isCancellationRequested) { + return undefined; + } const scope = await Container.keyboard.beginScope({ left: options.goBackCommand || KeyNoopCommand }); options.progressCancellation && options.progressCancellation.cancel(); - const pick = await window.showQuickPick(items, - { - placeHolder: placeHolder, - ignoreFocusOut: getQuickPickIgnoreFocusOut() - } as QuickPickOptions); + const pick = await window.showQuickPick(items, { + placeHolder: placeHolder, + ignoreFocusOut: getQuickPickIgnoreFocusOut() + } as QuickPickOptions); await scope.dispose(); return pick; } -} \ No newline at end of file +} diff --git a/src/quickPicks/branchesQuickPick.ts b/src/quickPicks/branchesQuickPick.ts index c04453c..b1b253e 100644 --- a/src/quickPicks/branchesQuickPick.ts +++ b/src/quickPicks/branchesQuickPick.ts @@ -5,7 +5,6 @@ import { GlyphChars } from '../constants'; import { GitBranch } from '../gitService'; export class BranchQuickPickItem implements QuickPickItem { - label: string; description: string; detail: string | undefined; @@ -19,8 +18,11 @@ export class BranchQuickPickItem implements QuickPickItem { } export class BranchesQuickPick { - - static async show(branches: GitBranch[], placeHolder: string, options: { goBackCommand?: CommandQuickPickItem} = {}): Promise<BranchQuickPickItem | CommandQuickPickItem | undefined> { + static async show( + branches: GitBranch[], + placeHolder: string, + options: { goBackCommand?: CommandQuickPickItem } = {} + ): Promise<BranchQuickPickItem | CommandQuickPickItem | undefined> { const items = branches.map(b => new BranchQuickPickItem(b)) as (BranchQuickPickItem | CommandQuickPickItem)[]; if (options.goBackCommand !== undefined) { @@ -29,14 +31,13 @@ export class BranchesQuickPick { // const scope = await Container.keyboard.beginScope({ left: goBackCommand }); - const pick = await window.showQuickPick(items, - { - placeHolder: placeHolder, - ignoreFocusOut: getQuickPickIgnoreFocusOut() - } as QuickPickOptions); + const pick = await window.showQuickPick(items, { + placeHolder: placeHolder, + ignoreFocusOut: getQuickPickIgnoreFocusOut() + } as QuickPickOptions); // await scope.dispose(); return pick; } -} \ No newline at end of file +} diff --git a/src/quickPicks/commitFileQuickPick.ts b/src/quickPicks/commitFileQuickPick.ts index 2afc770..2eedf45 100644 --- a/src/quickPicks/commitFileQuickPick.ts +++ b/src/quickPicks/commitFileQuickPick.ts @@ -1,8 +1,23 @@ 'use strict'; import { Iterables, Strings } from '../system'; import { QuickPickItem, QuickPickOptions, Uri, window } from 'vscode'; -import { Commands, CopyMessageToClipboardCommandArgs, CopyShaToClipboardCommandArgs, DiffWithPreviousCommandArgs, DiffWithWorkingCommandArgs, openEditor, ShowQuickCommitDetailsCommandArgs, ShowQuickCommitFileDetailsCommandArgs, ShowQuickFileHistoryCommandArgs } from '../commands'; -import { CommandQuickPickItem, getQuickPickIgnoreFocusOut, KeyCommandQuickPickItem, OpenFileCommandQuickPickItem } from './commonQuickPicks'; +import { + Commands, + CopyMessageToClipboardCommandArgs, + CopyShaToClipboardCommandArgs, + DiffWithPreviousCommandArgs, + DiffWithWorkingCommandArgs, + openEditor, + ShowQuickCommitDetailsCommandArgs, + ShowQuickCommitFileDetailsCommandArgs, + ShowQuickFileHistoryCommandArgs +} from '../commands'; +import { + CommandQuickPickItem, + getQuickPickIgnoreFocusOut, + KeyCommandQuickPickItem, + OpenFileCommandQuickPickItem +} from './commonQuickPicks'; import { GlyphChars } from '../constants'; import { Container } from '../container'; import { GitLog, GitLogCommit, GitUri, RemoteResource } from '../gitService'; @@ -15,10 +30,16 @@ export class ApplyCommitFileChangesCommandQuickPickItem extends CommandQuickPick private readonly commit: GitLogCommit, item?: QuickPickItem ) { - super(item || { - label: `$(git-pull-request) Apply Changes`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(file-text) ${path.basename(commit.fileName)} in ${GlyphChars.Space}$(git-commit) ${commit.shortSha}` - }, undefined, undefined); + super( + item || { + label: `$(git-pull-request) Apply Changes`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(file-text) ${path.basename(commit.fileName)} in ${ + GlyphChars.Space + }$(git-commit) ${commit.shortSha}` + }, + undefined, + undefined + ); } async execute(): Promise<{} | undefined> { @@ -29,50 +50,58 @@ export class ApplyCommitFileChangesCommandQuickPickItem extends CommandQuickPick } export class OpenCommitFileCommandQuickPickItem extends OpenFileCommandQuickPickItem { - - constructor( - commit: GitLogCommit, - item?: QuickPickItem - ) { + constructor(commit: GitLogCommit, item?: QuickPickItem) { const uri = Uri.file(path.resolve(commit.repoPath, commit.fileName)); - super(uri, item || { - label: `$(file-symlink-file) Open File`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${path.basename(commit.fileName)}` - }); + super( + uri, + item || { + label: `$(file-symlink-file) Open File`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${path.basename(commit.fileName)}` + } + ); } } export class OpenCommitFileRevisionCommandQuickPickItem extends OpenFileCommandQuickPickItem { - - constructor( - commit: GitLogCommit, - item?: QuickPickItem - ) { + constructor(commit: GitLogCommit, item?: QuickPickItem) { let description: string; let uri: Uri; if (commit.status === 'D') { uri = GitUri.toRevisionUri(commit.previousFileSha, commit.previousUri.fsPath, commit.repoPath); - description = `${Strings.pad(GlyphChars.Dash, 2, 3)} ${path.basename(commit.fileName)} in ${GlyphChars.Space}$(git-commit) ${commit.previousShortSha} (deleted in ${GlyphChars.Space}$(git-commit) ${commit.shortSha})`; + description = `${Strings.pad(GlyphChars.Dash, 2, 3)} ${path.basename(commit.fileName)} in ${ + GlyphChars.Space + }$(git-commit) ${commit.previousShortSha} (deleted in ${GlyphChars.Space}$(git-commit) ${commit.shortSha})`; } else { uri = GitUri.toRevisionUri(commit.sha, commit.uri.fsPath, commit.repoPath); - description = `${Strings.pad(GlyphChars.Dash, 2, 3)} ${path.basename(commit.fileName)} in ${GlyphChars.Space}$(git-commit) ${commit.shortSha}`; + description = `${Strings.pad(GlyphChars.Dash, 2, 3)} ${path.basename(commit.fileName)} in ${ + GlyphChars.Space + }$(git-commit) ${commit.shortSha}`; } - super(uri, item || { - label: `$(file-symlink-file) Open Revision`, - description: description - }); + super( + uri, + item || { + label: `$(file-symlink-file) Open Revision`, + description: description + } + ); } } export class CommitFileQuickPick { - - static async show(commit: GitLogCommit, uri: Uri, goBackCommand?: CommandQuickPickItem, currentCommand?: CommandQuickPickItem, fileLog?: GitLog): Promise<CommandQuickPickItem | undefined> { + static async show( + commit: GitLogCommit, + uri: Uri, + goBackCommand?: CommandQuickPickItem, + currentCommand?: CommandQuickPickItem, + fileLog?: GitLog + ): Promise<CommandQuickPickItem | undefined> { const items: CommandQuickPickItem[] = []; const stash = commit.isStash; - const workingName = (commit.workingFileName && path.basename(commit.workingFileName)) || path.basename(commit.fileName); + const workingName = + (commit.workingFileName && path.basename(commit.workingFileName)) || path.basename(commit.fileName); const isUncommitted = commit.isUncommitted; if (isUncommitted) { @@ -90,28 +119,42 @@ export class CommitFileQuickPick { } if (commit.previousFileShortSha) { - items.push(new CommandQuickPickItem({ - label: `$(git-compare) Open Changes`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${commit.previousFileShortSha} ${GlyphChars.Space} $(git-compare) ${GlyphChars.Space} $(git-commit) ${commit.shortSha}` - }, Commands.DiffWithPrevious, [ - commit.uri, + items.push( + new CommandQuickPickItem( { - commit - } as DiffWithPreviousCommandArgs - ]) + label: `$(git-compare) Open Changes`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${ + commit.previousFileShortSha + } ${GlyphChars.Space} $(git-compare) ${GlyphChars.Space} $(git-commit) ${commit.shortSha}` + }, + Commands.DiffWithPrevious, + [ + commit.uri, + { + commit + } as DiffWithPreviousCommandArgs + ] + ) ); } if (commit.workingFileName) { - items.push(new CommandQuickPickItem({ - label: `$(git-compare) Open Changes with Working Tree`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${commit.shortSha} ${GlyphChars.Space} $(git-compare) ${GlyphChars.Space} $(file-text) ${workingName}` - }, Commands.DiffWithWorking, [ - Uri.file(path.resolve(commit.repoPath, commit.workingFileName)), + items.push( + new CommandQuickPickItem( { - commit - } as DiffWithWorkingCommandArgs - ]) + label: `$(git-compare) Open Changes with Working Tree`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${commit.shortSha} ${ + GlyphChars.Space + } $(git-compare) ${GlyphChars.Space} $(file-text) ${workingName}` + }, + Commands.DiffWithWorking, + [ + Uri.file(path.resolve(commit.repoPath, commit.workingFileName)), + { + commit + } as DiffWithWorkingCommandArgs + ] + ) ); } @@ -125,84 +168,128 @@ export class CommitFileQuickPick { if (commit.workingFileName && commit.status !== 'D') { const branch = await Container.git.getBranch(commit.repoPath); if (branch !== undefined) { - items.push(new OpenRemotesCommandQuickPickItem(remotes, { - type: 'file', - fileName: commit.workingFileName, - branch: branch.name - } as RemoteResource, currentCommand)); + items.push( + new OpenRemotesCommandQuickPickItem( + remotes, + { + type: 'file', + fileName: commit.workingFileName, + branch: branch.name + } as RemoteResource, + currentCommand + ) + ); } } if (!stash) { - items.push(new OpenRemotesCommandQuickPickItem(remotes, { - type: 'revision', - fileName: commit.fileName, - commit - } as RemoteResource, currentCommand)); + items.push( + new OpenRemotesCommandQuickPickItem( + remotes, + { + type: 'revision', + fileName: commit.fileName, + commit + } as RemoteResource, + currentCommand + ) + ); } } if (!stash) { items.push(new ApplyCommitFileChangesCommandQuickPickItem(commit)); - items.push(new CommandQuickPickItem({ - label: `$(clippy) Copy Commit ID to Clipboard`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${commit.shortSha}` - }, Commands.CopyShaToClipboard, [ - uri, + items.push( + new CommandQuickPickItem( { - sha: commit.sha - } as CopyShaToClipboardCommandArgs - ]) + label: `$(clippy) Copy Commit ID to Clipboard`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${commit.shortSha}` + }, + Commands.CopyShaToClipboard, + [ + uri, + { + sha: commit.sha + } as CopyShaToClipboardCommandArgs + ] + ) ); - items.push(new CommandQuickPickItem({ - label: `$(clippy) Copy Commit Message to Clipboard`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${commit.getShortMessage()}` - }, Commands.CopyMessageToClipboard, [ - uri, + items.push( + new CommandQuickPickItem( { - message: commit.message, - sha: commit.sha - } as CopyMessageToClipboardCommandArgs - ])); + label: `$(clippy) Copy Commit Message to Clipboard`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${commit.getShortMessage()}` + }, + Commands.CopyMessageToClipboard, + [ + uri, + { + message: commit.message, + sha: commit.sha + } as CopyMessageToClipboardCommandArgs + ] + ) + ); } if (commit.workingFileName) { - items.push(new CommandQuickPickItem({ - label: `$(history) Show File History`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} of ${path.basename(commit.fileName)}` - }, Commands.ShowQuickFileHistory, [ - Uri.file(path.resolve(commit.repoPath, commit.workingFileName)), + items.push( + new CommandQuickPickItem( { - fileLog, - goBackCommand: currentCommand - } as ShowQuickFileHistoryCommandArgs - ])); + label: `$(history) Show File History`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} of ${path.basename(commit.fileName)}` + }, + Commands.ShowQuickFileHistory, + [ + Uri.file(path.resolve(commit.repoPath, commit.workingFileName)), + { + fileLog, + goBackCommand: currentCommand + } as ShowQuickFileHistoryCommandArgs + ] + ) + ); } if (!stash) { - items.push(new CommandQuickPickItem({ - label: `$(history) Show ${commit.workingFileName ? 'Previous ' : ''}File History`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} of ${path.basename(commit.fileName)} ${Strings.pad(GlyphChars.Dot, 1, 1)} from ${GlyphChars.Space}$(git-commit) ${commit.shortSha}` - }, Commands.ShowQuickFileHistory, [ - commit.toGitUri(), + items.push( + new CommandQuickPickItem( { - goBackCommand: currentCommand - } as ShowQuickFileHistoryCommandArgs - ])); - - items.push(new CommandQuickPickItem({ - label: `$(git-commit) Show Commit Details`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${commit.shortSha}` - }, Commands.ShowQuickCommitDetails, [ - commit.toGitUri(), + label: `$(history) Show ${commit.workingFileName ? 'Previous ' : ''}File History`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} of ${path.basename( + commit.fileName + )} ${Strings.pad(GlyphChars.Dot, 1, 1)} from ${GlyphChars.Space}$(git-commit) ${ + commit.shortSha + }` + }, + Commands.ShowQuickFileHistory, + [ + commit.toGitUri(), + { + goBackCommand: currentCommand + } as ShowQuickFileHistoryCommandArgs + ] + ) + ); + + items.push( + new CommandQuickPickItem( { - commit, - sha: commit.sha, - goBackCommand: currentCommand - } as ShowQuickCommitDetailsCommandArgs - ]) + label: `$(git-commit) Show Commit Details`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${commit.shortSha}` + }, + Commands.ShowQuickCommitDetails, + [ + commit.toGitUri(), + { + commit, + sha: commit.sha, + goBackCommand: currentCommand + } as ShowQuickCommitDetailsCommandArgs + ] + ) ); } @@ -215,27 +302,29 @@ export class CommitFileQuickPick { if (!stash) { // If we have the full history, we are good if (fileLog !== undefined && !fileLog.truncated && fileLog.sha === undefined) { - previousCommand = commit.previousSha === undefined - ? undefined - : new KeyCommandQuickPickItem(Commands.ShowQuickCommitFileDetails, [ - commit.previousUri, - { - fileLog, - sha: commit.previousSha, - goBackCommand - } as ShowQuickCommitFileDetailsCommandArgs - ]); - - nextCommand = commit.nextSha === undefined - ? undefined - : new KeyCommandQuickPickItem(Commands.ShowQuickCommitFileDetails, [ - commit.nextUri, - { - fileLog, - sha: commit.nextSha, - goBackCommand - } as ShowQuickCommitFileDetailsCommandArgs - ]); + previousCommand = + commit.previousSha === undefined + ? undefined + : new KeyCommandQuickPickItem(Commands.ShowQuickCommitFileDetails, [ + commit.previousUri, + { + fileLog, + sha: commit.previousSha, + goBackCommand + } as ShowQuickCommitFileDetailsCommandArgs + ]); + + nextCommand = + commit.nextSha === undefined + ? undefined + : new KeyCommandQuickPickItem(Commands.ShowQuickCommitFileDetails, [ + commit.nextUri, + { + fileLog, + sha: commit.nextSha, + goBackCommand + } as ShowQuickCommitFileDetailsCommandArgs + ]); } else { previousCommand = async () => { @@ -244,7 +333,11 @@ export class CommitFileQuickPick { // If we can't find the commit or the previous commit isn't available (since it isn't trustworthy) if (c === undefined || c.previousSha === undefined) { - log = await Container.git.getLogForFile(commit.repoPath, uri.fsPath, { maxCount: Container.config.advanced.maxListItems, ref: commit.sha, renames: true }); + log = await Container.git.getLogForFile(commit.repoPath, uri.fsPath, { + maxCount: Container.config.advanced.maxListItems, + ref: commit.sha, + renames: true + }); if (log === undefined) return KeyNoopCommand; c = log && log.commits.get(commit.sha); @@ -312,7 +405,11 @@ export class CommitFileQuickPick { const pick = await window.showQuickPick(items, { matchOnDescription: true, - placeHolder: `${commit.getFormattedPath()} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${isUncommitted ? `Uncommitted ${GlyphChars.ArrowRightHollow} ` : ''}${commit.shortSha} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${commit.author}, ${commit.formattedDate} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${commit.getShortMessage()}`, + placeHolder: `${commit.getFormattedPath()} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${ + isUncommitted ? `Uncommitted ${GlyphChars.ArrowRightHollow} ` : '' + }${commit.shortSha} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${commit.author}, ${ + commit.formattedDate + } ${Strings.pad(GlyphChars.Dot, 1, 1)} ${commit.getShortMessage()}`, ignoreFocusOut: getQuickPickIgnoreFocusOut(), onDidSelectItem: (item: QuickPickItem) => { scope.setKeyCommand('right', item as KeyCommand); @@ -323,4 +420,4 @@ export class CommitFileQuickPick { return pick; } -} \ No newline at end of file +} diff --git a/src/quickPicks/commitQuickPick.ts b/src/quickPicks/commitQuickPick.ts index 5e19da3..8817341 100644 --- a/src/quickPicks/commitQuickPick.ts +++ b/src/quickPicks/commitQuickPick.ts @@ -1,25 +1,48 @@ 'use strict'; import { Arrays, Iterables, Strings } from '../system'; import { commands, QuickPickOptions, TextDocumentShowOptions, Uri, window } from 'vscode'; -import { Commands, CopyMessageToClipboardCommandArgs, CopyShaToClipboardCommandArgs, DiffDirectoryCommandArgs, DiffWithPreviousCommandArgs, ShowQuickCommitDetailsCommandArgs, StashApplyCommandArgs, StashDeleteCommandArgs } from '../commands'; -import { CommandQuickPickItem, getQuickPickIgnoreFocusOut, KeyCommandQuickPickItem, OpenFileCommandQuickPickItem, OpenFilesCommandQuickPickItem, QuickPickItem, ShowCommitInResultsQuickPickItem } from './commonQuickPicks'; +import { + Commands, + CopyMessageToClipboardCommandArgs, + CopyShaToClipboardCommandArgs, + DiffDirectoryCommandArgs, + DiffWithPreviousCommandArgs, + ShowQuickCommitDetailsCommandArgs, + StashApplyCommandArgs, + StashDeleteCommandArgs +} from '../commands'; +import { + CommandQuickPickItem, + getQuickPickIgnoreFocusOut, + KeyCommandQuickPickItem, + OpenFileCommandQuickPickItem, + OpenFilesCommandQuickPickItem, + QuickPickItem, + ShowCommitInResultsQuickPickItem +} from './commonQuickPicks'; import { GlyphChars } from '../constants'; import { Container } from '../container'; -import { getGitStatusOcticon, GitLog, GitLogCommit, GitStashCommit, GitStatusFile, GitStatusFileStatus, GitUri, IGitStatusFile, RemoteResource } from '../gitService'; +import { + getGitStatusOcticon, + GitLog, + GitLogCommit, + GitStashCommit, + GitStatusFile, + GitStatusFileStatus, + GitUri, + IGitStatusFile, + RemoteResource +} from '../gitService'; import { KeyCommand, KeyNoopCommand, Keys } from '../keyboard'; import { OpenRemotesCommandQuickPickItem } from './remotesQuickPick'; import * as path from 'path'; export class CommitWithFileStatusQuickPickItem extends OpenFileCommandQuickPickItem { - readonly status: GitStatusFileStatus; readonly commit: GitLogCommit; - constructor( - commit: GitLogCommit, - status: IGitStatusFile - ) { + constructor(commit: GitLogCommit, status: IGitStatusFile) { const octicon = getGitStatusOcticon(status.status); const description = GitStatusFile.getFormattedDirectory(status, true); @@ -39,89 +62,107 @@ export class CommitWithFileStatusQuickPickItem extends OpenFileCommandQuickPickI onDidPressKey(key: Keys): Promise<{} | undefined> { if (this.commit.previousSha === undefined) return super.onDidPressKey(key); - return commands.executeCommand(Commands.DiffWithPrevious, - this.commit.toGitUri(), - { - commit: this.commit, - showOptions: { - preserveFocus: true, - preview: false - } as TextDocumentShowOptions - } as DiffWithPreviousCommandArgs) as Promise<{} | undefined>; + return commands.executeCommand(Commands.DiffWithPrevious, this.commit.toGitUri(), { + commit: this.commit, + showOptions: { + preserveFocus: true, + preview: false + } as TextDocumentShowOptions + } as DiffWithPreviousCommandArgs) as Promise<{} | undefined>; } } export class OpenCommitFilesCommandQuickPickItem extends OpenFilesCommandQuickPickItem { - - constructor( - commit: GitLogCommit, - versioned: boolean = false, - item?: QuickPickItem - ) { + constructor(commit: GitLogCommit, versioned: boolean = false, item?: QuickPickItem) { const repoPath = commit.repoPath; - const uris = Arrays.filterMap(commit.fileStatuses, - f => GitUri.fromFileStatus(f, repoPath)); - - super(uris, item || { - label: `$(file-symlink-file) Open Files`, - description: '' - // detail: `Opens all of the changed file in the working tree` - }); + const uris = Arrays.filterMap(commit.fileStatuses, f => GitUri.fromFileStatus(f, repoPath)); + + super( + uris, + item || { + label: `$(file-symlink-file) Open Files`, + description: '' + // detail: `Opens all of the changed file in the working tree` + } + ); } } export class OpenCommitFileRevisionsCommandQuickPickItem extends OpenFilesCommandQuickPickItem { + constructor(commit: GitLogCommit, item?: QuickPickItem) { + const uris = Arrays.filterMap(commit.fileStatuses, f => + GitUri.toRevisionUri(f.status === 'D' ? commit.previousFileSha : commit.sha, f, commit.repoPath) + ); - constructor( - commit: GitLogCommit, - item?: QuickPickItem - ) { - const uris = Arrays.filterMap(commit.fileStatuses, - f => GitUri.toRevisionUri(f.status === 'D' ? commit.previousFileSha : commit.sha, f, commit.repoPath)); - - super(uris, item || { - label: `$(file-symlink-file) Open Revisions`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} in ${GlyphChars.Space}$(git-commit) ${commit.shortSha}` - // detail: `Opens all of the changed files in $(git-commit) ${commit.shortSha}` - }); + super( + uris, + item || { + label: `$(file-symlink-file) Open Revisions`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} in ${GlyphChars.Space}$(git-commit) ${ + commit.shortSha + }` + // detail: `Opens all of the changed files in $(git-commit) ${commit.shortSha}` + } + ); } } export class CommitQuickPick { - - static async show(commit: GitLogCommit, uri: Uri, goBackCommand?: CommandQuickPickItem, currentCommand?: CommandQuickPickItem, repoLog?: GitLog): Promise<CommitWithFileStatusQuickPickItem | CommandQuickPickItem | undefined> { + static async show( + commit: GitLogCommit, + uri: Uri, + goBackCommand?: CommandQuickPickItem, + currentCommand?: CommandQuickPickItem, + repoLog?: GitLog + ): Promise<CommitWithFileStatusQuickPickItem | CommandQuickPickItem | undefined> { await commit.resolvePreviousFileSha(); - const items: (CommitWithFileStatusQuickPickItem | CommandQuickPickItem)[] = commit.fileStatuses.map(fs => new CommitWithFileStatusQuickPickItem(commit, fs)); + const items: (CommitWithFileStatusQuickPickItem | CommandQuickPickItem)[] = commit.fileStatuses.map( + fs => new CommitWithFileStatusQuickPickItem(commit, fs) + ); const stash = commit.isStash; let index = 0; if (stash) { - items.splice(index++, 0, new CommandQuickPickItem({ - label: `$(git-pull-request) Apply Stashed Changes`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${commit.getShortMessage()}` - }, Commands.StashApply, [ + items.splice( + index++, + 0, + new CommandQuickPickItem( { - confirm: true, - deleteAfter: false, - stashItem: commit as GitStashCommit, - goBackCommand: currentCommand - } as StashApplyCommandArgs - ]) + label: `$(git-pull-request) Apply Stashed Changes`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${commit.getShortMessage()}` + }, + Commands.StashApply, + [ + { + confirm: true, + deleteAfter: false, + stashItem: commit as GitStashCommit, + goBackCommand: currentCommand + } as StashApplyCommandArgs + ] + ) ); - items.splice(index++, 0, new CommandQuickPickItem({ - label: `$(x) Delete Stashed Changes`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${commit.getShortMessage()}` - }, Commands.StashDelete, [ + items.splice( + index++, + 0, + new CommandQuickPickItem( { - confirm: true, - stashItem: commit as GitStashCommit, - goBackCommand: currentCommand - } as StashDeleteCommandArgs - ]) + label: `$(x) Delete Stashed Changes`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${commit.getShortMessage()}` + }, + Commands.StashDelete, + [ + { + confirm: true, + stashItem: commit as GitStashCommit, + goBackCommand: currentCommand + } as StashDeleteCommandArgs + ] + ) ); items.splice(index++, 0, new ShowCommitInResultsQuickPickItem(commit)); @@ -131,76 +172,123 @@ export class CommitQuickPick { const remotes = await Container.git.getRemotes(commit.repoPath); if (remotes.length) { - items.splice(index++, 0, new OpenRemotesCommandQuickPickItem(remotes, { - type: 'commit', - sha: commit.sha - } as RemoteResource, currentCommand)); + items.splice( + index++, + 0, + new OpenRemotesCommandQuickPickItem( + remotes, + { + type: 'commit', + sha: commit.sha + } as RemoteResource, + currentCommand + ) + ); } } items.splice(index++, 0, new OpenCommitFilesCommandQuickPickItem(commit)); items.splice(index++, 0, new OpenCommitFileRevisionsCommandQuickPickItem(commit)); - items.splice(index++, 0, new CommandQuickPickItem({ - label: `$(git-compare) Open Directory Compare with Previous Revision`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${commit.previousFileShortSha} ${GlyphChars.Space} $(git-compare) ${GlyphChars.Space} $(git-commit) ${commit.shortSha}` - }, Commands.DiffDirectory, [ - commit.uri, + items.splice( + index++, + 0, + new CommandQuickPickItem( { - ref1: commit.previousFileSha, - ref2: commit.sha - } as DiffDirectoryCommandArgs - ]) + label: `$(git-compare) Open Directory Compare with Previous Revision`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${commit.previousFileShortSha} ${ + GlyphChars.Space + } $(git-compare) ${GlyphChars.Space} $(git-commit) ${commit.shortSha}` + }, + Commands.DiffDirectory, + [ + commit.uri, + { + ref1: commit.previousFileSha, + ref2: commit.sha + } as DiffDirectoryCommandArgs + ] + ) ); - items.splice(index++, 0, new CommandQuickPickItem({ - label: `$(git-compare) Open Directory Compare with Working Tree`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${commit.shortSha} ${GlyphChars.Space} $(git-compare) ${GlyphChars.Space} $(file-directory) Working Tree` - }, Commands.DiffDirectory, [ - uri, + items.splice( + index++, + 0, + new CommandQuickPickItem( { - ref1: commit.sha - } as DiffDirectoryCommandArgs - ]) + label: `$(git-compare) Open Directory Compare with Working Tree`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${commit.shortSha} ${ + GlyphChars.Space + } $(git-compare) ${GlyphChars.Space} $(file-directory) Working Tree` + }, + Commands.DiffDirectory, + [ + uri, + { + ref1: commit.sha + } as DiffDirectoryCommandArgs + ] + ) ); if (!stash) { - items.splice(index++, 0, new CommandQuickPickItem({ - label: `$(clippy) Copy Commit ID to Clipboard`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${commit.shortSha}` - }, Commands.CopyShaToClipboard, [ - uri, + items.splice( + index++, + 0, + new CommandQuickPickItem( { - sha: commit.sha - } as CopyShaToClipboardCommandArgs - ]) + label: `$(clippy) Copy Commit ID to Clipboard`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${commit.shortSha}` + }, + Commands.CopyShaToClipboard, + [ + uri, + { + sha: commit.sha + } as CopyShaToClipboardCommandArgs + ] + ) ); } - items.splice(index++, 0, new CommandQuickPickItem({ - label: `$(clippy) Copy Commit Message to Clipboard`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${commit.getShortMessage()}` - }, Commands.CopyMessageToClipboard, [ - uri, + items.splice( + index++, + 0, + new CommandQuickPickItem( { - message: commit.message, - sha: commit.sha - } as CopyMessageToClipboardCommandArgs - ]) + label: `$(clippy) Copy Commit Message to Clipboard`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${commit.getShortMessage()}` + }, + Commands.CopyMessageToClipboard, + [ + uri, + { + message: commit.message, + sha: commit.sha + } as CopyMessageToClipboardCommandArgs + ] + ) ); - items.splice(index++, 0, new CommandQuickPickItem({ - label: `Changed Files`, - description: commit.getDiffStatus() - }, Commands.ShowQuickCommitDetails, [ - uri, + items.splice( + index++, + 0, + new CommandQuickPickItem( { - commit, - repoLog, - sha: commit.sha, - goBackCommand - } as ShowQuickCommitDetailsCommandArgs - ]) + label: `Changed Files`, + description: commit.getDiffStatus() + }, + Commands.ShowQuickCommitDetails, + [ + uri, + { + commit, + repoLog, + sha: commit.sha, + goBackCommand + } as ShowQuickCommitDetailsCommandArgs + ] + ) ); if (goBackCommand) { @@ -212,27 +300,29 @@ export class CommitQuickPick { if (!stash) { // If we have the full history, we are good if (repoLog !== undefined && !repoLog.truncated && repoLog.sha === undefined) { - previousCommand = commit.previousSha === undefined - ? undefined - : new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [ - commit.previousUri, - { - repoLog, - sha: commit.previousSha, - goBackCommand - } as ShowQuickCommitDetailsCommandArgs - ]); - - nextCommand = commit.nextSha === undefined - ? undefined - : new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [ - commit.nextUri, - { - repoLog, - sha: commit.nextSha, - goBackCommand - } as ShowQuickCommitDetailsCommandArgs - ]); + previousCommand = + commit.previousSha === undefined + ? undefined + : new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [ + commit.previousUri, + { + repoLog, + sha: commit.previousSha, + goBackCommand + } as ShowQuickCommitDetailsCommandArgs + ]); + + nextCommand = + commit.nextSha === undefined + ? undefined + : new KeyCommandQuickPickItem(Commands.ShowQuickCommitDetails, [ + commit.nextUri, + { + repoLog, + sha: commit.nextSha, + goBackCommand + } as ShowQuickCommitDetailsCommandArgs + ]); } else { previousCommand = async () => { @@ -241,7 +331,10 @@ export class CommitQuickPick { // If we can't find the commit or the previous commit isn't available (since it isn't trustworthy) if (c === undefined || c.previousSha === undefined) { - log = await Container.git.getLog(commit.repoPath, { maxCount: Container.config.advanced.maxListItems, ref: commit.sha }); + log = await Container.git.getLog(commit.repoPath, { + maxCount: Container.config.advanced.maxListItems, + ref: commit.sha + }); c = log && log.commits.get(commit.sha); if (c) { @@ -272,7 +365,11 @@ export class CommitQuickPick { c = undefined; // Try to find the next commit - const nextLog = await Container.git.getLog(commit.repoPath, { maxCount: 1, reverse: true, ref: commit.sha }); + const nextLog = await Container.git.getLog(commit.repoPath, { + maxCount: 1, + reverse: true, + ref: commit.sha + }); const next = nextLog && Iterables.first(nextLog.commits.values()); if (next !== undefined && next.sha !== commit.sha) { c = commit; @@ -303,7 +400,9 @@ export class CommitQuickPick { const pick = await window.showQuickPick(items, { matchOnDescription: true, matchOnDetail: true, - placeHolder: `${commit.shortSha} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${commit.author ? `${commit.author}, ` : ''}${commit.formattedDate} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${commit.getShortMessage()}`, + placeHolder: `${commit.shortSha} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${ + commit.author ? `${commit.author}, ` : '' + }${commit.formattedDate} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${commit.getShortMessage()}`, ignoreFocusOut: getQuickPickIgnoreFocusOut(), onDidSelectItem: (item: QuickPickItem) => { scope.setKeyCommand('right', item); @@ -317,4 +416,4 @@ export class CommitQuickPick { return pick; } -} \ No newline at end of file +} diff --git a/src/quickPicks/commitsQuickPick.ts b/src/quickPicks/commitsQuickPick.ts index d2d3b0c..9a3f1aa 100644 --- a/src/quickPicks/commitsQuickPick.ts +++ b/src/quickPicks/commitsQuickPick.ts @@ -4,21 +4,36 @@ import { CancellationTokenSource, QuickPickOptions, window } from 'vscode'; import { Container } from '../container'; import { GitLog } from '../gitService'; import { KeyNoopCommand } from '../keyboard'; -import { CommandQuickPickItem, CommitQuickPickItem, getQuickPickIgnoreFocusOut, MessageQuickPickItem, showQuickPickProgress } from '../quickPicks/quickPicks'; +import { + CommandQuickPickItem, + CommitQuickPickItem, + getQuickPickIgnoreFocusOut, + MessageQuickPickItem, + showQuickPickProgress +} from '../quickPicks/quickPicks'; export class CommitsQuickPick { - static showProgress(message: string) { - return showQuickPickProgress(message, - { - left: KeyNoopCommand, - ',': KeyNoopCommand, - '.': KeyNoopCommand - }); + return showQuickPickProgress(message, { + left: KeyNoopCommand, + ',': KeyNoopCommand, + '.': KeyNoopCommand + }); } - static async show(log: GitLog | undefined, placeHolder: string, progressCancellation: CancellationTokenSource, options: { goBackCommand?: CommandQuickPickItem, showAllCommand?: CommandQuickPickItem, showInResultsExplorerCommand?: CommandQuickPickItem }): Promise<CommitQuickPickItem | CommandQuickPickItem | undefined> { - const items = ((log && [...Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c))]) || [new MessageQuickPickItem('No results found')]) as (CommitQuickPickItem | CommandQuickPickItem)[]; + static async show( + log: GitLog | undefined, + placeHolder: string, + progressCancellation: CancellationTokenSource, + options: { + goBackCommand?: CommandQuickPickItem; + showAllCommand?: CommandQuickPickItem; + showInResultsExplorerCommand?: CommandQuickPickItem; + } + ): Promise<CommitQuickPickItem | CommandQuickPickItem | undefined> { + const items = ((log && [...Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c))]) || [ + new MessageQuickPickItem('No results found') + ]) as (CommitQuickPickItem | CommandQuickPickItem)[]; if (options.showInResultsExplorerCommand !== undefined) { items.splice(0, 0, options.showInResultsExplorerCommand); @@ -51,4 +66,4 @@ export class CommitsQuickPick { return pick; } -} \ No newline at end of file +} diff --git a/src/quickPicks/commonQuickPicks.ts b/src/quickPicks/commonQuickPicks.ts index d5244d7..11a2fc8 100644 --- a/src/quickPicks/commonQuickPicks.ts +++ b/src/quickPicks/commonQuickPicks.ts @@ -1,6 +1,15 @@ 'use strict'; import { Strings } from '../system'; -import { CancellationTokenSource, commands, QuickPickItem, QuickPickOptions, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode'; +import { + CancellationTokenSource, + commands, + QuickPickItem, + QuickPickOptions, + TextDocumentShowOptions, + TextEditor, + Uri, + window +} from 'vscode'; import { BranchesAndTagsQuickPick, BranchOrTagQuickPickItem } from './branchesAndTagsQuickPick'; import { Commands, openEditor } from '../commands'; import { configuration } from '../configuration'; @@ -20,13 +29,17 @@ export function showQuickPickProgress(message: string, mapping?: KeyMapping): Ca } async function _showQuickPickProgress(message: string, cancellation: CancellationTokenSource, mapping?: KeyMapping) { - const scope = mapping && await Container.keyboard.beginScope(mapping); + const scope = mapping && (await Container.keyboard.beginScope(mapping)); try { - await window.showQuickPick(_getInfiniteCancellablePromise(cancellation), { - placeHolder: message, - ignoreFocusOut: getQuickPickIgnoreFocusOut() - } as QuickPickOptions, cancellation.token); + await window.showQuickPick( + _getInfiniteCancellablePromise(cancellation), + { + placeHolder: message, + ignoreFocusOut: getQuickPickIgnoreFocusOut() + } as QuickPickOptions, + cancellation.token + ); } catch (ex) { // Not sure why this throws @@ -52,7 +65,6 @@ export interface QuickPickItem extends QuickPickItem { } export class CommandQuickPickItem implements QuickPickItem { - label!: string; description!: string; detail?: string | undefined; @@ -89,22 +101,22 @@ export class CommandQuickPickItem implements QuickPickItem { } export class MessageQuickPickItem extends CommandQuickPickItem { - constructor(message: string) { super({ label: message, description: '' } as QuickPickItem); } } export class KeyCommandQuickPickItem extends CommandQuickPickItem { - constructor(command: Commands, args?: any[]) { super({ label: '', description: '' } as QuickPickItem, command, args); } } export class OpenFileCommandQuickPickItem extends CommandQuickPickItem { - - constructor(public readonly uri: Uri, item: QuickPickItem) { + constructor( + public readonly uri: Uri, + item: QuickPickItem + ) { super(item, undefined, undefined); } @@ -128,12 +140,16 @@ export class OpenFileCommandQuickPickItem extends CommandQuickPickItem { } export class OpenFilesCommandQuickPickItem extends CommandQuickPickItem { - - constructor(public readonly uris: Uri[], item: QuickPickItem) { + constructor( + public readonly uris: Uri[], + item: QuickPickItem + ) { super(item, undefined, undefined); } - async execute(options: TextDocumentShowOptions = { preserveFocus: false, preview: false }): Promise<{} | undefined> { + async execute( + options: TextDocumentShowOptions = { preserveFocus: false, preview: false } + ): Promise<{} | undefined> { for (const uri of this.uris) { await openEditor(uri, options); } @@ -149,22 +165,29 @@ export class OpenFilesCommandQuickPickItem extends CommandQuickPickItem { } export class CommitQuickPickItem implements QuickPickItem { - label: string; description: string; detail: string; - constructor(public readonly commit: GitLogCommit) { + constructor( + public readonly commit: GitLogCommit + ) { const message = commit.getShortMessage(); if (commit.isStash) { this.label = message; this.description = ''; - this.detail = `${GlyphChars.Space} ${(commit as GitStashCommit).stashName || commit.shortSha} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${commit.formattedDate} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${commit.getDiffStatus()}`; + this.detail = `${GlyphChars.Space} ${(commit as GitStashCommit).stashName || commit.shortSha} ${Strings.pad( + GlyphChars.Dot, + 1, + 1 + )} ${commit.formattedDate} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${commit.getDiffStatus()}`; } else { this.label = message; this.description = `${Strings.pad('$(git-commit)', 1, 1)} ${commit.shortSha}`; - this.detail = `${GlyphChars.Space} ${commit.author}, ${commit.formattedDate}${commit.isFile ? '' : ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${commit.getDiffStatus()}`}`; + this.detail = `${GlyphChars.Space} ${commit.author}, ${commit.formattedDate}${ + commit.isFile ? '' : ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${commit.getDiffStatus()}` + }`; } } } @@ -180,17 +203,18 @@ export class ShowCommitInResultsQuickPickItem extends CommandQuickPickItem { super(item, undefined, undefined); } - async execute(options: TextDocumentShowOptions = { preserveFocus: false, preview: false }): Promise<{} | undefined> { + async execute( + options: TextDocumentShowOptions = { preserveFocus: false, preview: false } + ): Promise<{} | undefined> { Container.resultsExplorer.showCommitInResults(this.commit); return undefined; } } export class ShowCommitsInResultsQuickPickItem extends CommandQuickPickItem { - constructor( public readonly results: GitLog, - public readonly resultsLabel: string | { label: string, resultsType?: { singular: string, plural: string } }, + public readonly resultsLabel: string | { label: string; resultsType?: { singular: string; plural: string } }, item: QuickPickItem = { label: 'Show in Results', description: `${Strings.pad(GlyphChars.Dash, 2, 2)} displays commits in the GitLens Results explorer` @@ -199,14 +223,15 @@ export class ShowCommitsInResultsQuickPickItem extends CommandQuickPickItem { super(item, undefined, undefined); } - async execute(options: TextDocumentShowOptions = { preserveFocus: false, preview: false }): Promise<{} | undefined> { + async execute( + options: TextDocumentShowOptions = { preserveFocus: false, preview: false } + ): Promise<{} | undefined> { Container.resultsExplorer.showCommitsInResults(this.results, this.resultsLabel); return undefined; } } export class ShowCommitsSearchInResultsQuickPickItem extends ShowCommitsInResultsQuickPickItem { - constructor( public readonly results: GitLog, public readonly search: string, @@ -220,7 +245,6 @@ export class ShowCommitsSearchInResultsQuickPickItem extends ShowCommitsInResult } export class ShowBranchesAndTagsQuickPickItem extends CommandQuickPickItem { - constructor( private readonly repoPath: string, private readonly placeHolder: string, @@ -233,7 +257,9 @@ export class ShowBranchesAndTagsQuickPickItem extends CommandQuickPickItem { super(item, undefined, undefined); } - async execute(options: TextDocumentShowOptions = { preserveFocus: false, preview: false }): Promise<CommandQuickPickItem | BranchOrTagQuickPickItem | undefined> { + async execute( + options: TextDocumentShowOptions = { preserveFocus: false, preview: false } + ): Promise<CommandQuickPickItem | BranchOrTagQuickPickItem | undefined> { const progressCancellation = BranchesAndTagsQuickPick.showProgress(this.placeHolder); try { @@ -244,10 +270,13 @@ export class ShowBranchesAndTagsQuickPickItem extends CommandQuickPickItem { if (progressCancellation.token.isCancellationRequested) return undefined; - return BranchesAndTagsQuickPick.show(branches, tags, this.placeHolder, { progressCancellation: progressCancellation, goBackCommand: this.goBackCommand }); + return BranchesAndTagsQuickPick.show(branches, tags, this.placeHolder, { + progressCancellation: progressCancellation, + goBackCommand: this.goBackCommand + }); } finally { progressCancellation.cancel(); } } -} \ No newline at end of file +} diff --git a/src/quickPicks/fileHistoryQuickPick.ts b/src/quickPicks/fileHistoryQuickPick.ts index 1da8617..8790bd0 100644 --- a/src/quickPicks/fileHistoryQuickPick.ts +++ b/src/quickPicks/fileHistoryQuickPick.ts @@ -2,7 +2,13 @@ import { Iterables, Strings } from '../system'; import { CancellationTokenSource, QuickPickOptions, Uri, window } from 'vscode'; import { Commands, ShowQuickCurrentBranchHistoryCommandArgs, ShowQuickFileHistoryCommandArgs } from '../commands'; -import { CommandQuickPickItem, CommitQuickPickItem, getQuickPickIgnoreFocusOut, ShowBranchesAndTagsQuickPickItem, showQuickPickProgress } from './commonQuickPicks'; +import { + CommandQuickPickItem, + CommitQuickPickItem, + getQuickPickIgnoreFocusOut, + ShowBranchesAndTagsQuickPickItem, + showQuickPickProgress +} from './commonQuickPicks'; import { GlyphChars } from '../constants'; import { Container } from '../container'; import { GitLog, GitUri, RemoteResource } from '../gitService'; @@ -11,20 +17,34 @@ import { OpenRemotesCommandQuickPickItem } from './remotesQuickPick'; import * as path from 'path'; export class FileHistoryQuickPick { - static showProgress(placeHolder: string) { - return showQuickPickProgress(placeHolder, - { - left: KeyNoopCommand, - ',': KeyNoopCommand, - '.': KeyNoopCommand - }); + return showQuickPickProgress(placeHolder, { + left: KeyNoopCommand, + ',': KeyNoopCommand, + '.': KeyNoopCommand + }); } - static async show(log: GitLog, uri: GitUri, placeHolder: string, options: { currentCommand?: CommandQuickPickItem, goBackCommand?: CommandQuickPickItem, nextPageCommand?: CommandQuickPickItem, previousPageCommand?: CommandQuickPickItem, pickerOnly?: boolean, progressCancellation?: CancellationTokenSource, showAllCommand?: CommandQuickPickItem, showInResultsExplorerCommand?: CommandQuickPickItem } = {}): Promise<CommitQuickPickItem | CommandQuickPickItem | undefined> { + static async show( + log: GitLog, + uri: GitUri, + placeHolder: string, + options: { + currentCommand?: CommandQuickPickItem; + goBackCommand?: CommandQuickPickItem; + nextPageCommand?: CommandQuickPickItem; + previousPageCommand?: CommandQuickPickItem; + pickerOnly?: boolean; + progressCancellation?: CancellationTokenSource; + showAllCommand?: CommandQuickPickItem; + showInResultsExplorerCommand?: CommandQuickPickItem; + } = {} + ): Promise<CommitQuickPickItem | CommandQuickPickItem | undefined> { options = { pickerOnly: false, ...options }; - const items = Array.from(Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c))) as (CommitQuickPickItem | CommandQuickPickItem)[]; + const items = Array.from(Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c))) as ( + | CommitQuickPickItem + | CommandQuickPickItem)[]; let index = 0; @@ -44,29 +64,50 @@ export class FileHistoryQuickPick { items.splice(0, 0, options.showAllCommand); } else if (!options.pickerOnly) { - const [workingFileName] = await Container.git.findWorkingFileName(path.relative(log.repoPath, uri.fsPath), log.repoPath); + const [workingFileName] = await Container.git.findWorkingFileName( + path.relative(log.repoPath, uri.fsPath), + log.repoPath + ); if (workingFileName) { index++; - items.splice(0, 0, new CommandQuickPickItem({ - label: `$(history) Show File History`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} of ${path.basename(workingFileName)}` - }, Commands.ShowQuickFileHistory, [ - Uri.file(path.resolve(log.repoPath, workingFileName)), + items.splice( + 0, + 0, + new CommandQuickPickItem( { - goBackCommand: new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to history of ${GlyphChars.Space}$(file-text) ${path.basename(uri.fsPath)}${uri.sha ? ` from ${GlyphChars.Space}$(git-commit) ${uri.shortSha}` : ''}` - }, Commands.ShowQuickFileHistory, [ - uri, + label: `$(history) Show File History`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} of ${path.basename( + workingFileName + )}` + }, + Commands.ShowQuickFileHistory, + [ + Uri.file(path.resolve(log.repoPath, workingFileName)), + { + goBackCommand: new CommandQuickPickItem( { - log: log, - maxCount: log.maxCount, - range: log.range, - goBackCommand: options.goBackCommand - } as ShowQuickFileHistoryCommandArgs - ]) - } as ShowQuickFileHistoryCommandArgs - ])); + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to history of ${ + GlyphChars.Space + }$(file-text) ${path.basename(uri.fsPath)}${ + uri.sha ? ` from ${GlyphChars.Space}$(git-commit) ${uri.shortSha}` : '' + }` + }, + Commands.ShowQuickFileHistory, + [ + uri, + { + log: log, + maxCount: log.maxCount, + range: log.range, + goBackCommand: options.goBackCommand + } as ShowQuickFileHistoryCommandArgs + ] + ) + } as ShowQuickFileHistoryCommandArgs + ] + ) + ); } } @@ -85,46 +126,64 @@ export class FileHistoryQuickPick { const branch = await Container.git.getBranch(uri.repoPath!); if (branch !== undefined) { - const currentCommand = new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to history of ${GlyphChars.Space}$(file-text) ${path.basename(uri.fsPath)}${uri.sha ? ` from ${GlyphChars.Space}$(git-commit) ${uri.shortSha}` : ''}` - }, Commands.ShowQuickFileHistory, [ + const currentCommand = new CommandQuickPickItem( + { + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to history of ${ + GlyphChars.Space + }$(file-text) ${path.basename(uri.fsPath)}${ + uri.sha ? ` from ${GlyphChars.Space}$(git-commit) ${uri.shortSha}` : '' + }` + }, + Commands.ShowQuickFileHistory, + [ uri, { log, maxCount: log.maxCount, range: log.range } as ShowQuickFileHistoryCommandArgs - ]); + ] + ); // Only show the full repo option if we are the root if (options.goBackCommand === undefined) { - items.splice(index++, 0, new CommandQuickPickItem({ - label: `$(history) Show Branch History`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${GlyphChars.Space}$(git-branch) ${branch.name} history` - }, Commands.ShowQuickCurrentBranchHistory, - [ - undefined, + items.splice( + index++, + 0, + new CommandQuickPickItem( { - goBackCommand: currentCommand - } as ShowQuickCurrentBranchHistoryCommandArgs - ])); + label: `$(history) Show Branch History`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows ${ + GlyphChars.Space + }$(git-branch) ${branch.name} history` + }, + Commands.ShowQuickCurrentBranchHistory, + [ + undefined, + { + goBackCommand: currentCommand + } as ShowQuickCurrentBranchHistoryCommandArgs + ] + ) + ); } const remotes = await Container.git.getRemotes(uri.repoPath!); if (remotes.length) { - const resource = uri.sha !== undefined - ? { - type: 'revision', - branch: branch.name, - fileName: uri.getRelativePath(), - sha: uri.sha - } as RemoteResource - : { - type: 'file', - branch: branch.name, - fileName: uri.getRelativePath() - } as RemoteResource; + const resource = + uri.sha !== undefined + ? ({ + type: 'revision', + branch: branch.name, + fileName: uri.getRelativePath(), + sha: uri.sha + } as RemoteResource) + : ({ + type: 'file', + branch: branch.name, + fileName: uri.getRelativePath() + } as RemoteResource); items.splice(index++, 0, new OpenRemotesCommandQuickPickItem(remotes, resource, currentCommand)); } } @@ -134,7 +193,9 @@ export class FileHistoryQuickPick { } } - if (options.progressCancellation !== undefined && options.progressCancellation.token.isCancellationRequested) return undefined; + if (options.progressCancellation !== undefined && options.progressCancellation.token.isCancellationRequested) { + return undefined; + } const scope = await Container.keyboard.beginScope({ left: options.goBackCommand, @@ -158,4 +219,4 @@ export class FileHistoryQuickPick { return pick; } -} \ No newline at end of file +} diff --git a/src/quickPicks/modesQuickPick.ts b/src/quickPicks/modesQuickPick.ts index 8595ae8..36017c4 100644 --- a/src/quickPicks/modesQuickPick.ts +++ b/src/quickPicks/modesQuickPick.ts @@ -8,7 +8,6 @@ export interface ModesQuickPickItem extends QuickPickItem { } export class ModesQuickPick { - static async show(): Promise<ModesQuickPickItem | undefined> { const modes = Object.keys(Container.config.modes); if (modes.length === 0) return undefined; @@ -18,7 +17,9 @@ export class ModesQuickPick { const items = modes.map(key => { const modeCfg = Container.config.modes[key]; return { - label: `${mode === key ? '$(check)\u00a0\u00a0' : '\u00a0\u00a0\u00a0\u00a0\u00a0'}${modeCfg.name} mode`, + label: `${mode === key ? '$(check)\u00a0\u00a0' : '\u00a0\u00a0\u00a0\u00a0\u00a0'}${ + modeCfg.name + } mode`, description: modeCfg.description ? `\u00a0${GlyphChars.Dash}\u00a0 ${modeCfg.description}` : '', key: key } as ModesQuickPickItem; @@ -37,4 +38,4 @@ export class ModesQuickPick { return pick; } -} \ No newline at end of file +} diff --git a/src/quickPicks/remotesQuickPick.ts b/src/quickPicks/remotesQuickPick.ts index 752108a..4a88032 100644 --- a/src/quickPicks/remotesQuickPick.ts +++ b/src/quickPicks/remotesQuickPick.ts @@ -4,22 +4,29 @@ import { QuickPickOptions, window } from 'vscode'; import { Commands, OpenInRemoteCommandArgs } from '../commands'; import { CommandQuickPickItem, getQuickPickIgnoreFocusOut } from './commonQuickPicks'; import { GlyphChars } from '../constants'; -import { getNameFromRemoteResource, GitLogCommit, GitRemote, GitService, RemoteResource, RemoteResourceType } from '../gitService'; +import { + getNameFromRemoteResource, + GitLogCommit, + GitRemote, + GitService, + RemoteResource, + RemoteResourceType +} from '../gitService'; import * as path from 'path'; export class OpenRemoteCommandQuickPickItem extends CommandQuickPickItem { - private remote: GitRemote; private resource: RemoteResource; - constructor( - remote: GitRemote, - resource: RemoteResource - ) { - super({ - label: `$(link-external) Open ${getNameFromRemoteResource(resource)} in ${remote.provider!.name}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(repo) ${remote.provider!.path}` - }, undefined, undefined); + constructor(remote: GitRemote, resource: RemoteResource) { + super( + { + label: `$(link-external) Open ${getNameFromRemoteResource(resource)} in ${remote.provider!.name}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(repo) ${remote.provider!.path}` + }, + undefined, + undefined + ); this.remote = remote; this.resource = resource; @@ -31,12 +38,7 @@ export class OpenRemoteCommandQuickPickItem extends CommandQuickPickItem { } export class OpenRemotesCommandQuickPickItem extends CommandQuickPickItem { - - constructor( - remotes: GitRemote[], - resource: RemoteResource, - goBackCommand?: CommandQuickPickItem - ) { + constructor(remotes: GitRemote[], resource: RemoteResource, goBackCommand?: CommandQuickPickItem) { const name = getNameFromRemoteResource(resource); let description = ''; @@ -66,33 +68,49 @@ export class OpenRemotesCommandQuickPickItem extends CommandQuickPickItem { if (resource.commit !== undefined && resource.commit instanceof GitLogCommit) { if (resource.commit.status === 'D') { resource.sha = resource.commit.previousSha; - description = `$(file-text) ${path.basename(resource.fileName)} in ${GlyphChars.Space}$(git-commit) ${resource.commit.previousShortSha} (deleted in ${GlyphChars.Space}$(git-commit) ${resource.commit.shortSha})`; + description = `$(file-text) ${path.basename(resource.fileName)} in ${ + GlyphChars.Space + }$(git-commit) ${resource.commit.previousShortSha} (deleted in ${ + GlyphChars.Space + }$(git-commit) ${resource.commit.shortSha})`; } else { resource.sha = resource.commit.sha; - description = `$(file-text) ${path.basename(resource.fileName)} in ${GlyphChars.Space}$(git-commit) ${resource.commit.shortSha}`; + description = `$(file-text) ${path.basename(resource.fileName)} in ${ + GlyphChars.Space + }$(git-commit) ${resource.commit.shortSha}`; } } else { const shortFileSha = resource.sha === undefined ? '' : GitService.shortenSha(resource.sha); - description = `$(file-text) ${path.basename(resource.fileName)}${shortFileSha ? ` in ${GlyphChars.Space}$(git-commit) ${shortFileSha}` : ''}`; + description = `$(file-text) ${path.basename(resource.fileName)}${ + shortFileSha ? ` in ${GlyphChars.Space}$(git-commit) ${shortFileSha}` : '' + }`; } break; } const remote = remotes[0]; if (remotes.length === 1) { - super({ - label: `$(link-external) Open ${name} in ${remote.provider!.name}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(repo) ${remote.provider!.path} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${description}` - }, Commands.OpenInRemote, [ + super( + { + label: `$(link-external) Open ${name} in ${remote.provider!.name}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(repo) ${remote.provider!.path} ${Strings.pad( + GlyphChars.Dot, + 1, + 1 + )} ${description}` + }, + Commands.OpenInRemote, + [ undefined, { remotes, resource, goBackCommand } as OpenInRemoteCommandArgs - ]); + ] + ); return; } @@ -101,24 +119,34 @@ export class OpenRemotesCommandQuickPickItem extends CommandQuickPickItem { ? remote.provider!.name : 'Remote'; - super({ - label: `$(link-external) Open ${name} in ${provider}${GlyphChars.Ellipsis}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${description}` - }, Commands.OpenInRemote, [ + super( + { + label: `$(link-external) Open ${name} in ${provider}${GlyphChars.Ellipsis}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${description}` + }, + Commands.OpenInRemote, + [ undefined, { remotes, resource, goBackCommand } as OpenInRemoteCommandArgs - ]); + ] + ); } } export class RemotesQuickPick { - - static async show(remotes: GitRemote[], placeHolder: string, resource: RemoteResource, goBackCommand?: CommandQuickPickItem): Promise<OpenRemoteCommandQuickPickItem | CommandQuickPickItem | undefined> { - const items = remotes.map(r => new OpenRemoteCommandQuickPickItem(r, resource)) as (OpenRemoteCommandQuickPickItem | CommandQuickPickItem)[]; + static async show( + remotes: GitRemote[], + placeHolder: string, + resource: RemoteResource, + goBackCommand?: CommandQuickPickItem + ): Promise<OpenRemoteCommandQuickPickItem | CommandQuickPickItem | undefined> { + const items = remotes.map(r => new OpenRemoteCommandQuickPickItem(r, resource)) as ( + | OpenRemoteCommandQuickPickItem + | CommandQuickPickItem)[]; if (goBackCommand) { items.splice(0, 0, goBackCommand); @@ -136,4 +164,4 @@ export class RemotesQuickPick { return pick; } -} \ No newline at end of file +} diff --git a/src/quickPicks/repoStatusQuickPick.ts b/src/quickPicks/repoStatusQuickPick.ts index 0452f14..4e6a976 100644 --- a/src/quickPicks/repoStatusQuickPick.ts +++ b/src/quickPicks/repoStatusQuickPick.ts @@ -1,43 +1,94 @@ 'use strict'; import { Iterables, Strings } from '../system'; import { commands, QuickPickOptions, TextDocumentShowOptions, window } from 'vscode'; -import { Commands, DiffWithPreviousCommandArgs, OpenChangedFilesCommandArgs, ShowQuickBranchHistoryCommandArgs, ShowQuickRepoStatusCommandArgs, ShowQuickStashListCommandArgs } from '../commands'; -import { CommandQuickPickItem, getQuickPickIgnoreFocusOut, OpenFileCommandQuickPickItem, QuickPickItem } from './commonQuickPicks'; +import { + Commands, + DiffWithPreviousCommandArgs, + OpenChangedFilesCommandArgs, + ShowQuickBranchHistoryCommandArgs, + ShowQuickRepoStatusCommandArgs, + ShowQuickStashListCommandArgs +} from '../commands'; +import { + CommandQuickPickItem, + getQuickPickIgnoreFocusOut, + OpenFileCommandQuickPickItem, + QuickPickItem +} from './commonQuickPicks'; import { GlyphChars } from '../constants'; import { Container } from '../container'; -import { GitCommitType, GitLogCommit, GitService, GitStatus, GitStatusFile, GitStatusFileStatus, GitUri } from '../gitService'; +import { + GitCommitType, + GitLogCommit, + GitService, + GitStatus, + GitStatusFile, + GitStatusFileStatus, + GitUri +} from '../gitService'; import { Keys } from '../keyboard'; import * as path from 'path'; export class OpenStatusFileCommandQuickPickItem extends OpenFileCommandQuickPickItem { - public readonly status: GitStatusFile; private readonly commit: GitLogCommit; - constructor( - status: GitStatusFile, - realIndexStatus?: GitStatusFileStatus, - item?: QuickPickItem - ) { + constructor(status: GitStatusFile, realIndexStatus?: GitStatusFileStatus, item?: QuickPickItem) { const octicon = status.getOcticon(); const description = status.getFormattedDirectory(true); - super(status.uri, item || { - label: `${status.staged ? '$(check)' : GlyphChars.Space.repeat(3)}${Strings.pad(octicon, 2, 2)} ${path.basename(status.fileName)}`, - description: description - }); + super( + status.uri, + item || { + label: `${status.staged ? '$(check)' : GlyphChars.Space.repeat(3)}${Strings.pad( + octicon, + 2, + 2 + )} ${path.basename(status.fileName)}`, + description: description + } + ); this.status = status; if (status.indexStatus !== undefined) { - this.commit = new GitLogCommit(GitCommitType.File, status.repoPath, GitService.stagedUncommittedSha, 'You', undefined, new Date(), '', status.fileName, [status], status.status, status.originalFileName, 'HEAD', status.fileName); + this.commit = new GitLogCommit( + GitCommitType.File, + status.repoPath, + GitService.stagedUncommittedSha, + 'You', + undefined, + new Date(), + '', + status.fileName, + [status], + status.status, + status.originalFileName, + 'HEAD', + status.fileName + ); } else { - this.commit = new GitLogCommit(GitCommitType.File, status.repoPath, GitService.uncommittedSha, 'You', undefined, new Date(), '', status.fileName, [status], status.status, status.originalFileName, realIndexStatus !== undefined ? GitService.stagedUncommittedSha : 'HEAD', status.fileName); + this.commit = new GitLogCommit( + GitCommitType.File, + status.repoPath, + GitService.uncommittedSha, + 'You', + undefined, + new Date(), + '', + status.fileName, + [status], + status.status, + status.originalFileName, + realIndexStatus !== undefined ? GitService.stagedUncommittedSha : 'HEAD', + status.fileName + ); } } onDidPressKey(key: Keys): Promise<{} | undefined> { - return commands.executeCommand(Commands.DiffWithPrevious, + return commands.executeCommand( + Commands.DiffWithPrevious, GitUri.fromFileStatus(this.status, this.status.repoPath), { commit: this.commit, @@ -46,23 +97,23 @@ export class OpenStatusFileCommandQuickPickItem extends OpenFileCommandQuickPick preserveFocus: true, preview: false } as TextDocumentShowOptions - } as DiffWithPreviousCommandArgs) as Promise<{} | undefined>; + } as DiffWithPreviousCommandArgs + ) as Promise<{} | undefined>; } } export class OpenStatusFilesCommandQuickPickItem extends CommandQuickPickItem { - - constructor( - statuses: GitStatusFile[], - item?: QuickPickItem - ) { + constructor(statuses: GitStatusFile[], item?: QuickPickItem) { const uris = statuses.map(f => f.uri); - super(item || { - label: `$(file-symlink-file) Open Changed Files`, - description: '' - // detail: `Opens all of the changed files in the repository` - }, Commands.OpenChangedFiles, [ + super( + item || { + label: `$(file-symlink-file) Open Changed Files`, + description: '' + // detail: `Opens all of the changed files in the repository` + }, + Commands.OpenChangedFiles, + [ undefined, { uris @@ -83,7 +134,6 @@ interface ComputedStatus { } export class RepoStatusQuickPick { - private static computeStatus(files: GitStatusFile[]): ComputedStatus { let stagedAdds = 0; let unstagedAdds = 0; @@ -150,7 +200,12 @@ export class RepoStatusQuickPick { }; } - static async show(status: GitStatus, goBackCommand?: CommandQuickPickItem): Promise<OpenStatusFileCommandQuickPickItem | OpenStatusFilesCommandQuickPickItem | CommandQuickPickItem | undefined> { + static async show( + status: GitStatus, + goBackCommand?: CommandQuickPickItem + ): Promise< + OpenStatusFileCommandQuickPickItem | OpenStatusFilesCommandQuickPickItem | CommandQuickPickItem | undefined + > { const items = [ ...Iterables.flatMap(status.files, s => { if (s.workTreeStatus !== undefined && s.indexStatus !== undefined) { @@ -163,16 +218,27 @@ export class RepoStatusQuickPick { return [new OpenStatusFileCommandQuickPickItem(s)]; } }) - ] as (OpenStatusFileCommandQuickPickItem | OpenStatusFilesCommandQuickPickItem | CommandQuickPickItem)[]; + ] as (OpenStatusFileCommandQuickPickItem | OpenStatusFilesCommandQuickPickItem | CommandQuickPickItem)[]; // Sort the status by staged and then filename - items.sort((a, b) => ((a as OpenStatusFileCommandQuickPickItem).status.staged ? -1 : 1) - ((b as OpenStatusFileCommandQuickPickItem).status.staged ? -1 : 1) || - (a as OpenStatusFileCommandQuickPickItem).status.fileName.localeCompare((b as OpenStatusFileCommandQuickPickItem).status.fileName)); + items.sort( + (a, b) => + ((a as OpenStatusFileCommandQuickPickItem).status.staged ? -1 : 1) - + ((b as OpenStatusFileCommandQuickPickItem).status.staged ? -1 : 1) || + (a as OpenStatusFileCommandQuickPickItem).status.fileName.localeCompare( + (b as OpenStatusFileCommandQuickPickItem).status.fileName + ) + ); - const currentCommand = new CommandQuickPickItem({ - label: `go back ${GlyphChars.ArrowBack}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to ${GlyphChars.Space}$(git-branch) ${status.branch} status` - }, Commands.ShowQuickRepoStatus, [ + const currentCommand = new CommandQuickPickItem( + { + label: `go back ${GlyphChars.ArrowBack}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to ${GlyphChars.Space}$(git-branch) ${ + status.branch + } status` + }, + Commands.ShowQuickRepoStatus, + [ undefined, { goBackCommand @@ -185,123 +251,206 @@ export class RepoStatusQuickPick { let index = 0; const unstagedIndex = computed.unstaged > 0 ? status.files.findIndex(f => !f.staged) : -1; if (unstagedIndex > -1) { - items.splice(unstagedIndex, 0, new CommandQuickPickItem({ - label: `Unstaged Files`, - description: computed.unstagedStatus - }, Commands.ShowQuickRepoStatus, [ - undefined, + items.splice( + unstagedIndex, + 0, + new CommandQuickPickItem( { - goBackCommand - } as ShowQuickRepoStatusCommandArgs - ]) + label: `Unstaged Files`, + description: computed.unstagedStatus + }, + Commands.ShowQuickRepoStatus, + [ + undefined, + { + goBackCommand + } as ShowQuickRepoStatusCommandArgs + ] + ) ); - items.splice(unstagedIndex, 0, new OpenStatusFilesCommandQuickPickItem(computed.stagedAddsAndChanges, { - label: `${GlyphChars.Space.repeat(4)} $(file-symlink-file) Open Staged Files`, - description: '' - })); + items.splice( + unstagedIndex, + 0, + new OpenStatusFilesCommandQuickPickItem(computed.stagedAddsAndChanges, { + label: `${GlyphChars.Space.repeat(4)} $(file-symlink-file) Open Staged Files`, + description: '' + }) + ); - items.push(new OpenStatusFilesCommandQuickPickItem(computed.unstagedAddsAndChanges, { - label: `${GlyphChars.Space.repeat(4)} $(file-symlink-file) Open Unstaged Files`, - description: '' - })); + items.push( + new OpenStatusFilesCommandQuickPickItem(computed.unstagedAddsAndChanges, { + label: `${GlyphChars.Space.repeat(4)} $(file-symlink-file) Open Unstaged Files`, + description: '' + }) + ); } - items.splice(index++, 0, new CommandQuickPickItem({ - label: `Staged Files`, - description: computed.stagedStatus - }, Commands.ShowQuickRepoStatus, [ - undefined, + items.splice( + index++, + 0, + new CommandQuickPickItem( { - goBackCommand - } as ShowQuickRepoStatusCommandArgs - ]) + label: `Staged Files`, + description: computed.stagedStatus + }, + Commands.ShowQuickRepoStatus, + [ + undefined, + { + goBackCommand + } as ShowQuickRepoStatusCommandArgs + ] + ) ); } else if (status.files.some(f => !f.staged)) { - items.splice(0, 0, new CommandQuickPickItem({ - label: `Unstaged Files`, - description: computed.unstagedStatus - }, Commands.ShowQuickRepoStatus, [ - undefined, + items.splice( + 0, + 0, + new CommandQuickPickItem( { - goBackCommand - } as ShowQuickRepoStatusCommandArgs - ]) + label: `Unstaged Files`, + description: computed.unstagedStatus + }, + Commands.ShowQuickRepoStatus, + [ + undefined, + { + goBackCommand + } as ShowQuickRepoStatusCommandArgs + ] + ) ); } if (status.files.length) { - items.push(new OpenStatusFilesCommandQuickPickItem(computed.stagedAddsAndChanges.concat(computed.unstagedAddsAndChanges))); - items.push(new CommandQuickPickItem({ - label: '$(x) Close Unchanged Files', - description: '' - }, Commands.CloseUnchangedFiles)); + items.push( + new OpenStatusFilesCommandQuickPickItem( + computed.stagedAddsAndChanges.concat(computed.unstagedAddsAndChanges) + ) + ); + items.push( + new CommandQuickPickItem( + { + label: '$(x) Close Unchanged Files', + description: '' + }, + Commands.CloseUnchangedFiles + ) + ); } else { - items.push(new CommandQuickPickItem({ - label: `No changes in the working tree`, - description: '' - }, Commands.ShowQuickRepoStatus, [ - undefined, + items.push( + new CommandQuickPickItem( { - goBackCommand - } as ShowQuickRepoStatusCommandArgs - ]) + label: `No changes in the working tree`, + description: '' + }, + Commands.ShowQuickRepoStatus, + [ + undefined, + { + goBackCommand + } as ShowQuickRepoStatusCommandArgs + ] + ) ); } - items.splice(0, 0, new CommandQuickPickItem({ - label: `$(inbox) Show Stashed Changes`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows stashed changes in the repository` - }, Commands.ShowQuickStashList, [ - GitUri.fromRepoPath(status.repoPath), + items.splice( + 0, + 0, + new CommandQuickPickItem( { - goBackCommand: currentCommand - } as ShowQuickStashListCommandArgs - ]) + label: `$(inbox) Show Stashed Changes`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows stashed changes in the repository` + }, + Commands.ShowQuickStashList, + [ + GitUri.fromRepoPath(status.repoPath), + { + goBackCommand: currentCommand + } as ShowQuickStashListCommandArgs + ] + ) ); if (status.upstream && status.state.ahead) { - items.splice(0, 0, new CommandQuickPickItem({ - label: `$(cloud-upload)${GlyphChars.Space} ${status.state.ahead} Commit${status.state.ahead > 1 ? 's' : ''} ahead of ${GlyphChars.Space}$(git-branch) ${status.upstream}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows commits in ${GlyphChars.Space}$(git-branch) ${status.branch} but not ${GlyphChars.Space}$(git-branch) ${status.upstream}` - }, Commands.ShowQuickBranchHistory, [ - GitUri.fromRepoPath(status.repoPath, `${status.upstream}..${status.branch}`), + items.splice( + 0, + 0, + new CommandQuickPickItem( { - branch: status.branch, - maxCount: 0, - goBackCommand: currentCommand - } as ShowQuickBranchHistoryCommandArgs - ]) + label: `$(cloud-upload)${GlyphChars.Space} ${status.state.ahead} Commit${ + status.state.ahead > 1 ? 's' : '' + } ahead of ${GlyphChars.Space}$(git-branch) ${status.upstream}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows commits in ${ + GlyphChars.Space + }$(git-branch) ${status.branch} but not ${GlyphChars.Space}$(git-branch) ${status.upstream}` + }, + Commands.ShowQuickBranchHistory, + [ + GitUri.fromRepoPath(status.repoPath, `${status.upstream}..${status.branch}`), + { + branch: status.branch, + maxCount: 0, + goBackCommand: currentCommand + } as ShowQuickBranchHistoryCommandArgs + ] + ) ); } if (status.upstream && status.state.behind) { - items.splice(0, 0, new CommandQuickPickItem({ - label: `$(cloud-download)${GlyphChars.Space} ${status.state.behind} Commit${status.state.behind > 1 ? 's' : ''} behind ${GlyphChars.Space}$(git-branch) ${status.upstream}`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows commits in ${GlyphChars.Space}$(git-branch) ${status.upstream} but not ${GlyphChars.Space}$(git-branch) ${status.branch}${status.sha ? ` (since ${GlyphChars.Space}$(git-commit) ${GitService.shortenSha(status.sha)})` : ''}` - }, Commands.ShowQuickBranchHistory, [ - GitUri.fromRepoPath(status.repoPath, `${status.branch}..${status.upstream}`), + items.splice( + 0, + 0, + new CommandQuickPickItem( { - branch: status.upstream, - maxCount: 0, - goBackCommand: currentCommand - } as ShowQuickBranchHistoryCommandArgs - ]) + label: `$(cloud-download)${GlyphChars.Space} ${status.state.behind} Commit${ + status.state.behind > 1 ? 's' : '' + } behind ${GlyphChars.Space}$(git-branch) ${status.upstream}`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows commits in ${ + GlyphChars.Space + }$(git-branch) ${status.upstream} but not ${GlyphChars.Space}$(git-branch) ${status.branch}${ + status.sha + ? ` (since ${GlyphChars.Space}$(git-commit) ${GitService.shortenSha(status.sha)})` + : '' + }` + }, + Commands.ShowQuickBranchHistory, + [ + GitUri.fromRepoPath(status.repoPath, `${status.branch}..${status.upstream}`), + { + branch: status.upstream, + maxCount: 0, + goBackCommand: currentCommand + } as ShowQuickBranchHistoryCommandArgs + ] + ) ); } if (status.upstream && !status.state.ahead && !status.state.behind) { - items.splice(0, 0, new CommandQuickPickItem({ - label: `$(git-branch) ${status.branch} is up-to-date with ${GlyphChars.Space}$(git-branch) ${status.upstream}`, - description: '' - }, Commands.ShowQuickRepoStatus, [ - undefined, + items.splice( + 0, + 0, + new CommandQuickPickItem( { - goBackCommand - } as ShowQuickRepoStatusCommandArgs - ]) + label: `$(git-branch) ${status.branch} is up-to-date with ${GlyphChars.Space}$(git-branch) ${ + status.upstream + }`, + description: '' + }, + Commands.ShowQuickRepoStatus, + [ + undefined, + { + goBackCommand + } as ShowQuickRepoStatusCommandArgs + ] + ) ); } @@ -313,7 +462,9 @@ export class RepoStatusQuickPick { const pick = await window.showQuickPick(items, { matchOnDescription: true, - placeHolder: `status of ${status.branch}${status.upstream ? ` ${Strings.pad(GlyphChars.ArrowLeftRightLong, 1, 1)} ${status.upstream}` : ''}`, + placeHolder: `status of ${status.branch}${ + status.upstream ? ` ${Strings.pad(GlyphChars.ArrowLeftRightLong, 1, 1)} ${status.upstream}` : '' + }`, ignoreFocusOut: getQuickPickIgnoreFocusOut(), onDidSelectItem: (item: QuickPickItem) => { scope.setKeyCommand('right', item); @@ -324,4 +475,4 @@ export class RepoStatusQuickPick { return pick; } -} \ No newline at end of file +} diff --git a/src/quickPicks/repositoriesQuickPick.ts b/src/quickPicks/repositoriesQuickPick.ts index 5f4fa72..02abce0 100644 --- a/src/quickPicks/repositoriesQuickPick.ts +++ b/src/quickPicks/repositoriesQuickPick.ts @@ -6,7 +6,6 @@ import { Container } from '../container'; import { Repository } from '../gitService'; export class RepositoryQuickPickItem implements QuickPickItem { - label: string; description: string; detail: string | undefined; @@ -24,9 +23,13 @@ export class RepositoryQuickPickItem implements QuickPickItem { } export class RepositoriesQuickPick { - - static async show(placeHolder: string, goBackCommand?: CommandQuickPickItem): Promise<RepositoryQuickPickItem | CommandQuickPickItem | undefined> { - const items = ([...Iterables.map(await Container.git.getRepositories(), r => new RepositoryQuickPickItem(r))]) as (RepositoryQuickPickItem | CommandQuickPickItem)[]; + static async show( + placeHolder: string, + goBackCommand?: CommandQuickPickItem + ): Promise<RepositoryQuickPickItem | CommandQuickPickItem | undefined> { + const items = [ + ...Iterables.map(await Container.git.getRepositories(), r => new RepositoryQuickPickItem(r)) + ] as (RepositoryQuickPickItem | CommandQuickPickItem)[]; if (goBackCommand !== undefined) { items.splice(0, 0, goBackCommand); @@ -43,4 +46,4 @@ export class RepositoriesQuickPick { return pick; } -} \ No newline at end of file +} diff --git a/src/quickPicks/stashListQuickPick.ts b/src/quickPicks/stashListQuickPick.ts index 846eb14..49e72be 100644 --- a/src/quickPicks/stashListQuickPick.ts +++ b/src/quickPicks/stashListQuickPick.ts @@ -6,34 +6,53 @@ import { GlyphChars } from '../constants'; import { Container } from '../container'; import { GitStash } from '../gitService'; import { KeyNoopCommand } from '../keyboard'; -import { CommandQuickPickItem, CommitQuickPickItem, getQuickPickIgnoreFocusOut, showQuickPickProgress } from '../quickPicks/quickPicks'; +import { + CommandQuickPickItem, + CommitQuickPickItem, + getQuickPickIgnoreFocusOut, + showQuickPickProgress +} from '../quickPicks/quickPicks'; export class StashListQuickPick { - static showProgress(mode: 'list' | 'apply') { - const message = mode === 'apply' - ? `Apply stashed changes to your working tree${GlyphChars.Ellipsis}` - : `stashed changes ${GlyphChars.Dash} search by message, filename, or commit id`; - return showQuickPickProgress(message, - { - left: KeyNoopCommand, - ',': KeyNoopCommand, - '.': KeyNoopCommand - }); + const message = + mode === 'apply' + ? `Apply stashed changes to your working tree${GlyphChars.Ellipsis}` + : `stashed changes ${GlyphChars.Dash} search by message, filename, or commit id`; + return showQuickPickProgress(message, { + left: KeyNoopCommand, + ',': KeyNoopCommand, + '.': KeyNoopCommand + }); } - static async show(stash: GitStash, mode: 'list' | 'apply', progressCancellation: CancellationTokenSource, goBackCommand?: CommandQuickPickItem, currentCommand?: CommandQuickPickItem): Promise<CommitQuickPickItem | CommandQuickPickItem | undefined> { - const items = ((stash && Array.from(Iterables.map(stash.commits.values(), c => new CommitQuickPickItem(c)))) || []) as (CommitQuickPickItem | CommandQuickPickItem)[]; + static async show( + stash: GitStash, + mode: 'list' | 'apply', + progressCancellation: CancellationTokenSource, + goBackCommand?: CommandQuickPickItem, + currentCommand?: CommandQuickPickItem + ): Promise<CommitQuickPickItem | CommandQuickPickItem | undefined> { + const items = ((stash && Array.from(Iterables.map(stash.commits.values(), c => new CommitQuickPickItem(c)))) || + []) as (CommitQuickPickItem | CommandQuickPickItem)[]; if (mode === 'list') { - items.splice(0, 0, new CommandQuickPickItem({ - label: `$(plus) Stash Changes`, - description: `${Strings.pad(GlyphChars.Dash, 2, 3)} stashes all changes` - }, Commands.StashSave, [ + items.splice( + 0, + 0, + new CommandQuickPickItem( { - goBackCommand: currentCommand - } as StashSaveCommandArgs - ])); + label: `$(plus) Stash Changes`, + description: `${Strings.pad(GlyphChars.Dash, 2, 3)} stashes all changes` + }, + Commands.StashSave, + [ + { + goBackCommand: currentCommand + } as StashSaveCommandArgs + ] + ) + ); } if (goBackCommand) { @@ -48,9 +67,10 @@ export class StashListQuickPick { const pick = await window.showQuickPick(items, { matchOnDescription: true, - placeHolder: mode === 'apply' - ? `Apply stashed changes to your working tree${GlyphChars.Ellipsis}` - : `stashed changes ${GlyphChars.Dash} search by message, filename, or commit id`, + placeHolder: + mode === 'apply' + ? `Apply stashed changes to your working tree${GlyphChars.Ellipsis}` + : `stashed changes ${GlyphChars.Dash} search by message, filename, or commit id`, ignoreFocusOut: getQuickPickIgnoreFocusOut() // onDidSelectItem: (item: QuickPickItem) => { // scope.setKeyCommand('right', item); @@ -61,4 +81,4 @@ export class StashListQuickPick { return pick; } -} \ No newline at end of file +} diff --git a/src/statusBarController.ts b/src/statusBarController.ts index 869afee..84d067b 100644 --- a/src/statusBarController.ts +++ b/src/statusBarController.ts @@ -8,7 +8,6 @@ import { LinesChangeEvent } from './trackers/gitLineTracker'; import { CommitFormatter, GitCommit, ICommitFormatOptions } from './gitService'; export class StatusBarController extends Disposable { - private _blameStatusBarItem: StatusBarItem | undefined; private _disposable: Disposable; private _modeStatusBarItem: StatusBarItem | undefined; @@ -16,9 +15,7 @@ export class StatusBarController extends Disposable { constructor() { super(() => this.dispose()); - this._disposable = Disposable.from( - configuration.onDidChange(this.onConfigurationChanged, this) - ); + this._disposable = Disposable.from(configuration.onDidChange(this.onConfigurationChanged, this)); this.onConfigurationChanged(configuration.initializingChangeEvent); } @@ -36,11 +33,15 @@ export class StatusBarController extends Disposable { const initializing = configuration.initializing(e); if (initializing || configuration.changed(e, configuration.name('mode').value)) { - const mode = Container.config.mode.active && Container.config.mode.statusBar.enabled - ? Container.config.modes[Container.config.mode.active] - : undefined; + const mode = + Container.config.mode.active && Container.config.mode.statusBar.enabled + ? Container.config.modes[Container.config.mode.active] + : undefined; if (mode && mode.statusBarItemName) { - const alignment = Container.config.mode.statusBar.alignment !== 'left' ? StatusBarAlignment.Right : StatusBarAlignment.Left; + const alignment = + Container.config.mode.statusBar.alignment !== 'left' + ? StatusBarAlignment.Right + : StatusBarAlignment.Left; if (configuration.changed(e, configuration.name('mode')('statusBar')('alignment').value)) { if (this._modeStatusBarItem !== undefined && this._modeStatusBarItem.alignment !== alignment) { @@ -49,7 +50,9 @@ export class StatusBarController extends Disposable { } } - this._modeStatusBarItem = this._modeStatusBarItem || window.createStatusBarItem(alignment, alignment === StatusBarAlignment.Right ? 999 : 1); + this._modeStatusBarItem = + this._modeStatusBarItem || + window.createStatusBarItem(alignment, alignment === StatusBarAlignment.Right ? 999 : 1); this._modeStatusBarItem.command = Commands.SwitchMode; this._modeStatusBarItem.text = mode.statusBarItemName; this._modeStatusBarItem.tooltip = `Switch GitLens Mode`; @@ -66,7 +69,8 @@ export class StatusBarController extends Disposable { if (!initializing && !configuration.changed(e, configuration.name('statusBar').value)) return; if (Container.config.statusBar.enabled) { - const alignment = Container.config.statusBar.alignment !== 'left' ? StatusBarAlignment.Right : StatusBarAlignment.Left; + const alignment = + Container.config.statusBar.alignment !== 'left' ? StatusBarAlignment.Right : StatusBarAlignment.Left; if (configuration.changed(e, configuration.name('statusBar')('alignment').value)) { if (this._blameStatusBarItem !== undefined && this._blameStatusBarItem.alignment !== alignment) { @@ -75,7 +79,9 @@ export class StatusBarController extends Disposable { } } - this._blameStatusBarItem = this._blameStatusBarItem || window.createStatusBarItem(alignment, alignment === StatusBarAlignment.Right ? 1000 : 0); + this._blameStatusBarItem = + this._blameStatusBarItem || + window.createStatusBarItem(alignment, alignment === StatusBarAlignment.Right ? 1000 : 0); this._blameStatusBarItem.command = Container.config.statusBar.command; if (initializing || configuration.changed(e, configuration.name('statusBar')('enabled').value)) { @@ -99,7 +105,11 @@ export class StatusBarController extends Disposable { private onActiveLinesChanged(e: LinesChangeEvent) { // If we need to reduceFlicker, don't clear if only the selected lines changed - let clear = !(Container.config.statusBar.reduceFlicker && e.reason === 'selection' && (e.pending || e.lines !== undefined)); + let clear = !( + Container.config.statusBar.reduceFlicker && + e.reason === 'selection' && + (e.pending || e.lines !== undefined) + ); if (!e.pending && e.lines !== undefined) { const state = Container.lineTracker.getState(e.lines[0]); if (state !== undefined && state.commit !== undefined) { @@ -162,4 +172,4 @@ export class StatusBarController extends Disposable { this._blameStatusBarItem.show(); } -} \ No newline at end of file +} diff --git a/src/system/array.ts b/src/system/array.ts index e118ad3..27f63f8 100644 --- a/src/system/array.ts +++ b/src/system/array.ts @@ -11,24 +11,36 @@ export namespace Arrays { return uniqueCounts; } - export function filterMap<T, TMapped>(source: T[], predicateMapper: (item: T) => TMapped | null | undefined): TMapped[] { - return source.reduce((accumulator, current) => { - const mapped = predicateMapper(current); - if (mapped != null) { - accumulator.push(mapped); - } - return accumulator; - }, [] as TMapped[]); + export function filterMap<T, TMapped>( + source: T[], + predicateMapper: (item: T) => TMapped | null | undefined + ): TMapped[] { + return source.reduce( + (accumulator, current) => { + const mapped = predicateMapper(current); + if (mapped != null) { + accumulator.push(mapped); + } + return accumulator; + }, + [] as TMapped[] + ); } - export async function filterMapAsync<T, TMapped>(source: T[], predicateMapper: (item: T) => Promise<TMapped | null | undefined>): Promise<TMapped[]> { - return source.reduce(async (accumulator, current) => { - const mapped = await predicateMapper(current); - if (mapped != null) { - accumulator.push(mapped); - } - return accumulator; - }, [] as any); + export async function filterMapAsync<T, TMapped>( + source: T[], + predicateMapper: (item: T) => Promise<TMapped | null | undefined> + ): Promise<TMapped[]> { + return source.reduce( + async (accumulator, current) => { + const mapped = await predicateMapper(current); + if (mapped != null) { + accumulator.push(mapped); + } + return accumulator; + }, + [] as any + ); } export function groupBy<T>(source: T[], accessor: (item: T) => string): { [key: string]: T[] } { @@ -50,7 +62,11 @@ export namespace Arrays { }, new Map<TKey, TValue[]>()); } - export function groupByFilterMap<TKey, TValue, TMapped>(source: TValue[], accessor: (item: TValue) => TKey, predicateMapper: (item: TValue) => TMapped | null | undefined): Map<TKey, TMapped[]> { + export function groupByFilterMap<TKey, TValue, TMapped>( + source: TValue[], + accessor: (item: TValue) => TKey, + predicateMapper: (item: TValue) => TMapped | null | undefined + ): Map<TKey, TMapped[]> { return source.reduce((groupings, current) => { const mapped = predicateMapper(current); if (mapped != null) { @@ -73,7 +89,12 @@ export namespace Arrays { descendants: T[] | undefined; } - export function makeHierarchical<T>(values: T[], splitPath: (i: T) => string[], joinPath: (...paths: string[]) => string, compact: boolean = false): IHierarchicalItem<T> { + export function makeHierarchical<T>( + values: T[], + splitPath: (i: T) => string[], + joinPath: (...paths: string[]) => string, + compact: boolean = false + ): IHierarchicalItem<T> { const seed = { name: '', relativePath: '', @@ -119,7 +140,11 @@ export namespace Arrays { return hierarchy; } - export function compactHierarchy<T>(root: IHierarchicalItem<T>, joinPath: (...paths: string[]) => string, isRoot: boolean = true): IHierarchicalItem<T> { + export function compactHierarchy<T>( + root: IHierarchicalItem<T>, + joinPath: (...paths: string[]) => string, + isRoot: boolean = true + ): IHierarchicalItem<T> { if (root.children === undefined) return root; const children = [...Objects.values(root.children)]; @@ -163,4 +188,4 @@ export namespace Arrays { return predicate ? predicate(item) : true; }); } -} \ No newline at end of file +} diff --git a/src/system/asyncIterable.ts b/src/system/asyncIterable.ts index 2d81ca3..f37e419 100644 --- a/src/system/asyncIterable.ts +++ b/src/system/asyncIterable.ts @@ -10,4 +10,4 @@ // if (mapped != null) yield mapped; // } // } -// } \ No newline at end of file +// } diff --git a/src/system/date.ts b/src/system/date.ts index 1b942e8..517af39 100644 --- a/src/system/date.ts +++ b/src/system/date.ts @@ -7,7 +7,7 @@ const MillisecondsPerDay = 86400000; // 24 * 60 * 60 * 1000 // Taken from https://github.com/date-fns/date-fns/blob/601bc8e5708cbaebee5389bdaf51c2b4b33b73c4/src/locale/en/build_distance_in_words_locale/index.js function buildDistanceInWordsLocale() { - const distanceInWordsLocale: { [key: string]: string | { one: string, other: string } } = { + const distanceInWordsLocale: { [key: string]: string | { one: string; other: string } } = { lessThanXSeconds: { one: 'less than a second', other: 'less than {{count}} seconds' @@ -112,16 +112,15 @@ function buildDistanceInWordsLocale() { } // Monkey patch the locale to customize the wording -const patch = (en as any); +const patch = en as any; patch.distanceInWords = buildDistanceInWordsLocale(); const formatterOptions = { addSuffix: true, locale: patch }; export namespace Dates { - export interface IDateFormatter { - fromNow: () => string; - format: (format: string) => string; + fromNow(): string; + format(format: string): string; } export function dateDaysFromNow(date: Date, now: number = Date.now()) { @@ -148,4 +147,4 @@ export namespace Dates { format: (format: string) => _format(date, format) }; } -} \ No newline at end of file +} diff --git a/src/system/function.ts b/src/system/function.ts index fee8817..133412f 100644 --- a/src/system/function.ts +++ b/src/system/function.ts @@ -5,7 +5,7 @@ const _once = require('lodash.once'); export interface IDeferrable { cancel(): void; flush(...args: any[]): void; - pending?: () => boolean; + pending?(): boolean; } interface IPropOfValue { @@ -14,26 +14,43 @@ interface IPropOfValue { } export namespace Functions { - export function debounce<T extends Function>(fn: T, wait?: number, options?: { leading?: boolean, maxWait?: number, track?: boolean, trailing?: boolean }): T & IDeferrable { - const { track, ...opts } = { track: false, ...(options || {}) } as { leading?: boolean, maxWait?: number, track?: boolean, trailing?: boolean }; + export function debounce<T extends Function>( + fn: T, + wait?: number, + options?: { leading?: boolean; maxWait?: number; track?: boolean; trailing?: boolean } + ): T & IDeferrable { + const { track, ...opts } = { + track: false, + ...(options || {}) + } as { leading?: boolean; maxWait?: number; track?: boolean; trailing?: boolean }; if (track !== true) return _debounce(fn, wait, opts); let pending = false; - const debounced = _debounce(function(this: any) { - pending = false; - return fn.apply(this, arguments); - } as any as T, wait, options) as T & IDeferrable; + const debounced = _debounce( + (function(this: any) { + pending = false; + return fn.apply(this, arguments); + } as any) as T, + wait, + options + ) as T & IDeferrable; - const tracked = function(this: any) { + const tracked = (function(this: any) { pending = true; return debounced.apply(this, arguments); - } as any as T & IDeferrable; + } as any) as T & IDeferrable; - tracked.pending = function() { return pending; }; - tracked.cancel = function() { return debounced.cancel.apply(debounced, arguments); }; - tracked.flush = function(...args: any[]) { return debounced.flush.apply(debounced, arguments); }; + tracked.pending = function() { + return pending; + }; + tracked.cancel = function() { + return debounced.cancel.apply(debounced, arguments); + }; + tracked.flush = function(...args: any[]) { + return debounced.flush.apply(debounced, arguments); + }; return tracked; } @@ -44,9 +61,8 @@ export namespace Functions { export function propOf<T, K extends Extract<keyof T, string>>(o: T, key: K) { const propOfCore = <T, K extends Extract<keyof T, string>>(o: T, key: K) => { - const value: string = (propOfCore as IPropOfValue).value === undefined - ? key - : `${(propOfCore as IPropOfValue).value}.${key}`; + const value: string = + (propOfCore as IPropOfValue).value === undefined ? key : `${(propOfCore as IPropOfValue).value}.${key}`; (propOfCore as IPropOfValue).value = value; const fn = <Y extends Extract<keyof T[K], string>>(k: Y) => propOfCore(o[key], k); return Object.assign(fn, { value: value }); @@ -82,4 +98,4 @@ export namespace Functions { counter++; } } -} \ No newline at end of file +} diff --git a/src/system/iterable.ts b/src/system/iterable.ts index 500bfa8..43d1bb4 100644 --- a/src/system/iterable.ts +++ b/src/system/iterable.ts @@ -24,9 +24,14 @@ export namespace Iterables { return true; } - export function filter<T>(source: Iterable<T | undefined | null> | IterableIterator<T | undefined | null>): Iterable<T>; + export function filter<T>( + source: Iterable<T | undefined | null> | IterableIterator<T | undefined | null> + ): Iterable<T>; export function filter<T>(source: Iterable<T> | IterableIterator<T>, predicate: (item: T) => boolean): Iterable<T>; - export function* filter<T>(source: Iterable<T> | IterableIterator<T>, predicate?: (item: T) => boolean): Iterable<T> { + export function* filter<T>( + source: Iterable<T> | IterableIterator<T>, + predicate?: (item: T) => boolean + ): Iterable<T> { if (predicate === undefined) { for (const item of source) { if (item != null) yield item; @@ -39,7 +44,10 @@ export namespace Iterables { } } - export function* filterMap<T, TMapped>(source: Iterable<T> | IterableIterator<T>, predicateMapper: (item: T) => TMapped | undefined | null): Iterable<TMapped> { + export function* filterMap<T, TMapped>( + source: Iterable<T> | IterableIterator<T>, + predicateMapper: (item: T) => TMapped | undefined | null + ): Iterable<TMapped> { for (const item of source) { const mapped = predicateMapper(item); if (mapped != null) yield mapped; @@ -65,7 +73,10 @@ export namespace Iterables { return source[Symbol.iterator]().next().value; } - export function* flatMap<T, TMapped>(source: Iterable<T> | IterableIterator<T>, mapper: (item: T) => Iterable<TMapped>): Iterable<TMapped> { + export function* flatMap<T, TMapped>( + source: Iterable<T> | IterableIterator<T>, + mapper: (item: T) => Iterable<TMapped> + ): Iterable<TMapped> { for (const item of source) { yield* mapper(item); } @@ -103,11 +114,16 @@ export namespace Iterables { export function last<T>(source: Iterable<T>): T | null { let item: T | null = null; - for (item of source) { /* noop */ } + for (item of source) { + /* noop */ + } return item; } - export function* map<T, TMapped>(source: Iterable<T> | IterableIterator<T>, mapper: (item: T) => TMapped): Iterable<TMapped> { + export function* map<T, TMapped>( + source: Iterable<T> | IterableIterator<T>, + mapper: (item: T) => TMapped + ): Iterable<TMapped> { for (const item of source) { yield mapper(item); } @@ -117,7 +133,10 @@ export namespace Iterables { return source.next().value; } - export function* skip<T>(source: Iterable<T> | IterableIterator<T>, count: number): Iterable<T> | IterableIterator<T> { + export function* skip<T>( + source: Iterable<T> | IterableIterator<T>, + count: number + ): Iterable<T> | IterableIterator<T> { let i = 0; for (const item of source) { if (i >= count) yield item; @@ -150,4 +169,4 @@ export namespace Iterables { } } } -} \ No newline at end of file +} diff --git a/src/system/object.ts b/src/system/object.ts index 634cc2d..6dd091b 100644 --- a/src/system/object.ts +++ b/src/system/object.ts @@ -76,4 +76,4 @@ export namespace Objects { yield o[key]; } } -} \ No newline at end of file +} diff --git a/src/system/searchTree.ts b/src/system/searchTree.ts index ed97abb..c911435 100644 --- a/src/system/searchTree.ts +++ b/src/system/searchTree.ts @@ -13,7 +13,6 @@ export interface IKeyIterator { } export class StringIterator implements IKeyIterator { - private _value: string = ''; private _pos: number = 0; @@ -55,7 +54,6 @@ const enum CharCode { } export class PathIterator implements IKeyIterator { - private _value!: string; private _from!: number; private _to!: number; @@ -80,10 +78,12 @@ export class PathIterator implements IKeyIterator { if (ch === CharCode.Slash || ch === CharCode.Backslash) { if (justSeps) { this._from++; - } else { + } + else { break; } - } else { + } + else { justSeps = false; } } @@ -91,7 +91,6 @@ export class PathIterator implements IKeyIterator { } cmp(a: string): number { - let aPos = 0; const aLen = a.length; let thisPos = this._from; @@ -107,9 +106,11 @@ export class PathIterator implements IKeyIterator { if (aLen === this._to - this._from) { return 0; - } else if (aPos < aLen) { + } + else if (aPos < aLen) { return -1; - } else { + } + else { return 1; } } @@ -133,7 +134,6 @@ class TernarySearchTreeNode<E> { } export class TernarySearchTree<E> { - static forPaths<E>(): TernarySearchTree<E> { return new TernarySearchTree<E>(new PathIterator()); } @@ -172,16 +172,16 @@ export class TernarySearchTree<E> { node.left.segment = iter.value(); } node = node.left; - - } else if (val < 0) { + } + else if (val < 0) { // right if (!node.right) { node.right = new TernarySearchTreeNode<E>(); node.right.segment = iter.value(); } node = node.right; - - } else if (iter.hasNext()) { + } + else if (iter.hasNext()) { // mid iter.next(); if (!node.mid) { @@ -189,7 +189,8 @@ export class TernarySearchTree<E> { node.mid.segment = iter.value(); } node = node.mid; - } else { + } + else { break; } } @@ -207,14 +208,17 @@ export class TernarySearchTree<E> { if (val > 0) { // left node = node.left; - } else if (val < 0) { + } + else if (val < 0) { // right node = node.right; - } else if (iter.hasNext()) { + } + else if (iter.hasNext()) { // mid iter.next(); node = node.mid; - } else { + } + else { break; } } @@ -233,16 +237,19 @@ export class TernarySearchTree<E> { // left stack.push([1, node]); node = node.left; - } else if (val < 0) { + } + else if (val < 0) { // right stack.push([-1, node]); node = node.right; - } else if (iter.hasNext()) { + } + else if (iter.hasNext()) { // mid iter.next(); stack.push([0, node]); node = node.mid; - } else { + } + else { // remove element node.value = undefined; @@ -250,9 +257,15 @@ export class TernarySearchTree<E> { while (stack.length > 0 && node.isEmpty()) { const [dir, parent] = stack.pop()!; switch (dir) { - case 1: parent.left = undefined; break; - case 0: parent.mid = undefined; break; - case -1: parent.right = undefined; break; + case 1: + parent.left = undefined; + break; + case 0: + parent.mid = undefined; + break; + case -1: + parent.right = undefined; + break; } node = parent; } @@ -270,19 +283,22 @@ export class TernarySearchTree<E> { if (val > 0) { // left node = node.left; - } else if (val < 0) { + } + else if (val < 0) { // right node = node.right; - } else if (iter.hasNext()) { + } + else if (iter.hasNext()) { // mid iter.next(); candidate = node.value || candidate; node = node.mid; - } else { + } + else { break; } } - return node && node.value || candidate; + return (node && node.value) || candidate; } findSuperstr(key: string): TernarySearchTree<E> | undefined { @@ -293,14 +309,17 @@ export class TernarySearchTree<E> { if (val > 0) { // left node = node.left; - } else if (val < 0) { + } + else if (val < 0) { // right node = node.right; - } else if (iter.hasNext()) { + } + else if (iter.hasNext()) { // mid iter.next(); node = node.mid; - } else { + } + else { // collect if (!node.mid) { return undefined; diff --git a/src/system/string.ts b/src/system/string.ts index 412fb8f..4d5ed02 100644 --- a/src/system/string.ts +++ b/src/system/string.ts @@ -13,7 +13,7 @@ export namespace Strings { } export function getTokensFromTemplate(template: string) { - const tokens: { key: string, options: ITokenOptions }[] = []; + const tokens: { key: string; options: ITokenOptions }[] = []; let match = TokenRegex.exec(template); while (match != null) { @@ -55,7 +55,9 @@ export namespace Strings { } export function md5(s: string, encoding: HexBase64Latin1Encoding = 'base64'): string { - return createHash('md5').update(s).digest(encoding); + return createHash('md5') + .update(s) + .digest(encoding); } export function normalizePath(fileName: string) { @@ -74,7 +76,7 @@ export namespace Strings { export function padLeft(s: string, padTo: number, padding: string = '\u00a0') { const diff = padTo - width(s); - return (diff <= 0) ? s : padding.repeat(diff) + s; + return diff <= 0 ? s : padding.repeat(diff) + s; } export function padLeftOrTruncate(s: string, max: number, padding?: string) { @@ -86,7 +88,7 @@ export namespace Strings { export function padRight(s: string, padTo: number, padding: string = '\u00a0') { const diff = padTo - width(s); - return (diff <= 0) ? s : s + padding.repeat(diff); + return diff <= 0 ? s : s + padding.repeat(diff); } export function padOrTruncate(s: string, max: number, padding?: string) { @@ -115,7 +117,9 @@ export namespace Strings { } export function sha1(s: string, encoding: HexBase64Latin1Encoding = 'base64'): string { - return createHash('sha1').update(s).digest(encoding); + return createHash('sha1') + .update(s) + .digest(encoding); } export function truncate(s: string, truncateTo: number, ellipsis: string = '\u2026') { @@ -139,6 +143,7 @@ export namespace Strings { return `${s.substring(0, chars)}${ellipsis}`; } + // tslint:disable-next-line:max-line-length const ansiRegex = /[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))/g; export function width(s: string): number { @@ -155,24 +160,24 @@ export namespace Strings { const code = graphemes[i].codePointAt(0)!; // Ignore control characters - if (code <= 0x1F || (code >= 0x7F && code <= 0x9F)) continue; + if (code <= 0x1f || (code >= 0x7f && code <= 0x9f)) continue; // Ignore combining characters - if (code >= 0x300 && code <= 0x36F) continue; + if (code >= 0x300 && code <= 0x36f) continue; // https://stackoverflow.com/questions/30757193/find-out-if-character-in-string-is-emoji if ( - (code >= 0x1F600 && code <= 0x1F64F) || // Emoticons - (code >= 0x1F300 && code <= 0x1F5FF) || // Misc Symbols and Pictographs - (code >= 0x1F680 && code <= 0x1F6FF) || // Transport and Map - (code >= 0x2600 && code <= 0x26FF) || // Misc symbols - (code >= 0x2700 && code <= 0x27BF) || // Dingbats - (code >= 0xFE00 && code <= 0xFE0F) || // Variation Selectors - (code >= 0x1F900 && code <= 0x1F9FF) || // Supplemental Symbols and Pictographs - (code >= 65024 && code <= 65039) || // Variation selector - (code >= 8400 && code <= 8447) // Combining Diacritical Marks for Symbols + (code >= 0x1f600 && code <= 0x1f64f) || // Emoticons + (code >= 0x1f300 && code <= 0x1f5ff) || // Misc Symbols and Pictographs + (code >= 0x1f680 && code <= 0x1f6ff) || // Transport and Map + (code >= 0x2600 && code <= 0x26ff) || // Misc symbols + (code >= 0x2700 && code <= 0x27bf) || // Dingbats + (code >= 0xfe00 && code <= 0xfe0f) || // Variation Selectors + (code >= 0x1f900 && code <= 0x1f9ff) || // Supplemental Symbols and Pictographs + (code >= 65024 && code <= 65039) || // Variation selector + (code >= 8400 && code <= 8447) // Combining Diacritical Marks for Symbols ) { - if (code >= 0x1F3FB && code <= 0x1F3FF) continue; // emoji modifier fitzpatrick type + if (code >= 0x1f3fb && code <= 0x1f3ff) continue; // emoji modifier fitzpatrick type emoji++; count += 2; @@ -187,7 +192,7 @@ export namespace Strings { } // Surrogates - if (code > 0xFFFF) { + if (code > 0xffff) { i++; } @@ -205,10 +210,10 @@ export namespace Strings { // code points are derived from: // http://www.unix.org/Public/UNIDATA/EastAsianWidth.txt if ( - cp >= 0x1100 && ( - cp <= 0x115f || // Hangul Jamo - cp === 0x2329 || // LEFT-POINTING ANGLE BRACKET - cp === 0x232a || // RIGHT-POINTING ANGLE BRACKET + cp >= 0x1100 && + (cp <= 0x115f || // Hangul Jamo + cp === 0x2329 || // LEFT-POINTING ANGLE BRACKET + cp === 0x232a || // RIGHT-POINTING ANGLE BRACKET // CJK Radicals Supplement .. Enclosed CJK Letters and Months (0x2e80 <= cp && cp <= 0x3247 && cp !== 0x303f) || // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A @@ -233,12 +238,11 @@ export namespace Strings { // Enclosed Ideographic Supplement (0x1f200 <= cp && cp <= 0x1f251) || // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane - (0x20000 <= cp && cp <= 0x3fffd) - ) + (0x20000 <= cp && cp <= 0x3fffd)) ) { return true; } return false; } -} \ No newline at end of file +} diff --git a/src/system/version.ts b/src/system/version.ts index f9bb4fa..bc7d76d 100644 --- a/src/system/version.ts +++ b/src/system/version.ts @@ -23,12 +23,19 @@ export namespace Versions { if (v1.pre === undefined && v2.pre !== undefined) return 1; if (v1.pre !== undefined && v2.pre === undefined) return -1; - if (v1.pre !== undefined && v2.pre !== undefined) return v1.pre.localeCompare(v2.pre) as VersionComparisonResult; + if (v1.pre !== undefined && v2.pre !== undefined) { + return v1.pre.localeCompare(v2.pre) as VersionComparisonResult; + } return 0; } - export function from(major: string | number, minor: string | number, patch: string | number, pre?: string): Version { + export function from( + major: string | number, + minor: string | number, + patch: string | number, + pre?: string + ): Version { return { major: typeof major === 'string' ? parseInt(major, 10) : major, minor: typeof minor === 'string' ? parseInt(minor, 10) : minor, @@ -42,4 +49,4 @@ export namespace Versions { const [major, minor, patch] = ver.split('.'); return from(major, minor, patch, pre); } -} \ No newline at end of file +} diff --git a/src/telemetry.ts b/src/telemetry.ts index 543c5ea..8903c54 100644 --- a/src/telemetry.ts +++ b/src/telemetry.ts @@ -110,4 +110,4 @@ // client.context.tags[machineNameKey] = ''; // } // } -// } \ No newline at end of file +// } diff --git a/src/trackers/activeEditorTracker.ts b/src/trackers/activeEditorTracker.ts index 3c946db..7954285 100644 --- a/src/trackers/activeEditorTracker.ts +++ b/src/trackers/activeEditorTracker.ts @@ -1,11 +1,9 @@ - 'use strict'; import { Functions } from './../system'; import { commands, Disposable, TextEditor, window } from 'vscode'; import { BuiltInCommands } from './../constants'; export class ActiveEditorTracker extends Disposable { - private _disposable: Disposable; private _resolver: ((editor: TextEditor | undefined) => void) | undefined; @@ -59,4 +57,4 @@ export class ActiveEditorTracker extends Disposable { this._resolver = undefined; return editor; } -} \ No newline at end of file +} diff --git a/src/trackers/documentTracker.ts b/src/trackers/documentTracker.ts index 785c29e..2fd56fb 100644 --- a/src/trackers/documentTracker.ts +++ b/src/trackers/documentTracker.ts @@ -1,6 +1,21 @@ 'use strict'; import { Functions, IDeferrable } from './../system'; -import { ConfigurationChangeEvent, Disposable, EndOfLine, Event, EventEmitter, Position, Range, TextDocument, TextDocumentChangeEvent, TextEditor, TextLine, Uri, window, workspace } from 'vscode'; +import { + ConfigurationChangeEvent, + Disposable, + EndOfLine, + Event, + EventEmitter, + Position, + Range, + TextDocument, + TextDocumentChangeEvent, + TextEditor, + TextLine, + Uri, + window, + workspace +} from 'vscode'; import { configuration } from './../configuration'; import { CommandContext, DocumentSchemes, isActiveDocument, isTextEditor, setCommandContext } from './../constants'; import { GitUri } from '../gitService'; @@ -9,7 +24,6 @@ import { DocumentBlameStateChangeEvent, TrackedDocument } from './trackedDocumen export * from './trackedDocument'; export interface DocumentDirtyStateChangeEvent<T> { - readonly editor: TextEditor; readonly document: TrackedDocument<T>; readonly dirty: boolean; @@ -21,7 +35,6 @@ export interface DocumentDirtyIdleTriggerEvent<T> { } export class DocumentTracker<T> extends Disposable { - private _onDidChangeBlameState = new EventEmitter<DocumentBlameStateChangeEvent<T>>(); get onDidChangeBlameState(): Event<DocumentBlameStateChangeEvent<T>> { return this._onDidChangeBlameState.event; @@ -70,8 +83,11 @@ export class DocumentTracker<T> extends Disposable { const initializing = configuration.initializing(e); // Only rest the cached state if we aren't initializing - if (!initializing && (configuration.changed(e, configuration.name('blame')('ignoreWhitespace').value, null) || - configuration.changed(e, configuration.name('advanced')('caching')('enabled').value))) { + if ( + !initializing && + (configuration.changed(e, configuration.name('blame')('ignoreWhitespace').value, null) || + configuration.changed(e, configuration.name('advanced')('caching')('enabled').value)) + ) { for (const d of this._documentMap.values()) { d.reset('config'); } @@ -153,7 +169,7 @@ export class DocumentTracker<T> extends Disposable { private onTextDocumentSaved(document: TextDocument) { let doc = this._documentMap.get(document); if (doc !== undefined) { - doc.update({ forceBlameChange: true}); + doc.update({ forceBlameChange: true }); return; } @@ -293,14 +309,23 @@ export class DocumentTracker<T> extends Disposable { if (this._dirtyIdleTriggerDelay > 0) { if (this._dirtyIdleTriggeredDebounced === undefined) { - this._dirtyIdleTriggeredDebounced = Functions.debounce(async (e: DocumentDirtyIdleTriggerEvent<T>) => { - if (this._dirtyIdleTriggeredDebounced !== undefined && this._dirtyIdleTriggeredDebounced.pending!()) return; - - await e.document.ensureInitialized(); - - e.document.isDirtyIdle = true; - this._onDidTriggerDirtyIdle.fire(e); - }, this._dirtyIdleTriggerDelay, { track: true }); + this._dirtyIdleTriggeredDebounced = Functions.debounce( + async (e: DocumentDirtyIdleTriggerEvent<T>) => { + if ( + this._dirtyIdleTriggeredDebounced !== undefined && + this._dirtyIdleTriggeredDebounced.pending!() + ) { + return; + } + + await e.document.ensureInitialized(); + + e.document.isDirtyIdle = true; + this._onDidTriggerDirtyIdle.fire(e); + }, + this._dirtyIdleTriggerDelay, + { track: true } + ); } this._dirtyIdleTriggeredDebounced({ editor: e.editor, document: e.document }); @@ -323,7 +348,6 @@ export class DocumentTracker<T> extends Disposable { } class EmptyTextDocument implements TextDocument { - readonly eol: EndOfLine; readonly fileName: string; readonly isClosed: boolean; @@ -384,5 +408,5 @@ class EmptyTextDocument implements TextDocument { } } -class BinaryTextDocument extends EmptyTextDocument { } -class MissingRevisionTextDocument extends EmptyTextDocument { } \ No newline at end of file +class BinaryTextDocument extends EmptyTextDocument {} +class MissingRevisionTextDocument extends EmptyTextDocument {} diff --git a/src/trackers/gitDocumentTracker.ts b/src/trackers/gitDocumentTracker.ts index 6566879..a070d59 100644 --- a/src/trackers/gitDocumentTracker.ts +++ b/src/trackers/gitDocumentTracker.ts @@ -14,12 +14,11 @@ export type CachedDiff = CachedItem<GitDiff>; export type CachedLog = CachedItem<GitLog>; export class GitDocumentState { - private cache: Map<string, CachedBlame | CachedDiff | CachedLog> = new Map(); constructor( public readonly key: string - ) { } + ) {} get<T extends CachedBlame | CachedDiff | CachedLog>(key: string): T | undefined { return this.cache.get(key) as T; @@ -30,4 +29,4 @@ export class GitDocumentState { } } -export class GitDocumentTracker extends DocumentTracker<GitDocumentState> { } \ No newline at end of file +export class GitDocumentTracker extends DocumentTracker<GitDocumentState> {} diff --git a/src/trackers/gitLineTracker.ts b/src/trackers/gitLineTracker.ts index 9d6c3b6..fbd0bdd 100644 --- a/src/trackers/gitLineTracker.ts +++ b/src/trackers/gitLineTracker.ts @@ -3,20 +3,23 @@ import { Disposable, TextEditor } from 'vscode'; import { GitBlameCommit, GitLogCommit } from '../gitService'; import { LinesChangeEvent, LineTracker } from './lineTracker'; import { Container } from '../container'; -import { DocumentBlameStateChangeEvent, DocumentDirtyIdleTriggerEvent, DocumentDirtyStateChangeEvent, GitDocumentState } from './gitDocumentTracker'; +import { + DocumentBlameStateChangeEvent, + DocumentDirtyIdleTriggerEvent, + DocumentDirtyStateChangeEvent, + GitDocumentState +} from './gitDocumentTracker'; export * from './lineTracker'; export class GitLineState { - constructor( public readonly commit: GitBlameCommit | undefined, public logCommit?: GitLogCommit - ) { } + ) {} } export class GitLineTracker extends LineTracker<GitLineState> { - private _count = 0; private _subscriptions: Map<any, Disposable> = new Map(); diff --git a/src/trackers/lineTracker.ts b/src/trackers/lineTracker.ts index 9bba40b..c39b983 100644 --- a/src/trackers/lineTracker.ts +++ b/src/trackers/lineTracker.ts @@ -4,7 +4,6 @@ import { Disposable, Event, EventEmitter, TextEditor, TextEditorSelectionChangeE import { isTextEditor } from './../constants'; export interface LinesChangeEvent { - readonly editor: TextEditor | undefined; readonly lines: number[] | undefined; @@ -13,7 +12,6 @@ export interface LinesChangeEvent { } export class LineTracker<T> extends Disposable { - private _onDidChangeActiveLines = new EventEmitter<LinesChangeEvent>(); get onDidChangeActiveLines(): Event<LinesChangeEvent> { return this._onDidChangeActiveLines.event; @@ -135,13 +133,19 @@ export class LineTracker<T> extends Disposable { } if (this._linesChangedDebounced === undefined) { - this._linesChangedDebounced = Functions.debounce((e: LinesChangeEvent) => { - if (window.activeTextEditor !== e.editor) return; - // Make sure we are still on the same lines - if (!LineTracker.includesAll(e.lines , (e.editor && e.editor.selections.map(s => s.active.line)))) return; - - this.fireLinesChanged(e); - }, 250, { track: true }); + this._linesChangedDebounced = Functions.debounce( + (e: LinesChangeEvent) => { + if (window.activeTextEditor !== e.editor) return; + // Make sure we are still on the same lines + if (!LineTracker.includesAll(e.lines, e.editor && e.editor.selections.map(s => s.active.line))) { + return; + } + + this.fireLinesChanged(e); + }, + 250, + { track: true } + ); } // If we have no pending moves, then fire an immediate pending event, and defer the real event @@ -158,4 +162,4 @@ export class LineTracker<T> extends Disposable { return lines2.length === lines1.length && lines2.every((v, i) => v === lines1[i]); } -} \ No newline at end of file +} diff --git a/src/trackers/trackedDocument.ts b/src/trackers/trackedDocument.ts index 545c0b7..916cfc4 100644 --- a/src/trackers/trackedDocument.ts +++ b/src/trackers/trackedDocument.ts @@ -13,7 +13,6 @@ export interface DocumentBlameStateChangeEvent<T> { } export class TrackedDocument<T> extends Disposable { - private _onDidBlameStateChange = new EventEmitter<DocumentBlameStateChangeEvent<T>>(); get onDidBlameStateChange(): Event<DocumentBlameStateChangeEvent<T>> { return this._onDidBlameStateChange.event; @@ -30,7 +29,7 @@ export class TrackedDocument<T> extends Disposable { private readonly _document: TextDocument, public readonly key: string, public dirty: boolean, - private _eventDelegates: { onDidBlameStateChange: (e: DocumentBlameStateChangeEvent<T>) => void } + private _eventDelegates: { onDidBlameStateChange(e: DocumentBlameStateChangeEvent<T>): void } ) { super(() => this.dispose()); @@ -46,8 +45,11 @@ export class TrackedDocument<T> extends Disposable { private async initialize(uri: Uri): Promise<Repository | undefined> { // Since there is a bit of a chicken & egg problem with the DocumentTracker and the GitService, wait for the GitService to load if it isn't if (Container.git === undefined) { - if (!await Functions.waitUntil(() => Container.git !== undefined, 2000)) { - Logger.log(`TrackedDocument.initialize(${uri.toString()})`, 'Timed out waiting for the GitService to start'); + if (!(await Functions.waitUntil(() => Container.git !== undefined, 2000))) { + Logger.log( + `TrackedDocument.initialize(${uri.toString()})`, + 'Timed out waiting for the GitService to start' + ); throw new Error('TrackedDocument timed out waiting for the GitService to start'); } } @@ -165,7 +167,7 @@ export class TrackedDocument<T> extends Disposable { this._forceDirtyStateChangeOnNextDocumentChange = true; } - async update(options: { forceBlameChange?: boolean, initializing?: boolean, repo?: Repository } = {}) { + async update(options: { forceBlameChange?: boolean; initializing?: boolean; repo?: Repository } = {}) { if (this._disposed || this._uri === undefined) { this._hasRemotes = false; this._isTracked = false; diff --git a/src/ui/config.ts b/src/ui/config.ts index 132d633..96757ee 100644 --- a/src/ui/config.ts +++ b/src/ui/config.ts @@ -201,28 +201,36 @@ export interface IHistoryExplorerConfig { } export interface IMenuConfig { - editor: boolean | { - blame: boolean; - clipboard: boolean; - compare: boolean; - details: boolean; - history: boolean; - remote: boolean; - }; - editorGroup: boolean | { - compare: boolean; - history: boolean; - }; - editorTab: boolean | { - compare: boolean; - history: boolean; - remote: boolean; - }; - explorer: boolean | { - compare: boolean; - history: boolean; - remote: boolean; - }; + editor: + | boolean + | { + blame: boolean; + clipboard: boolean; + compare: boolean; + details: boolean; + history: boolean; + remote: boolean; + }; + editorGroup: + | boolean + | { + compare: boolean; + history: boolean; + }; + editorTab: + | boolean + | { + compare: boolean; + history: boolean; + remote: boolean; + }; + explorer: + | boolean + | { + compare: boolean; + history: boolean; + remote: boolean; + }; } export interface IModeConfig { @@ -312,14 +320,14 @@ export interface IConfig { changes: boolean; details: boolean; enabled: boolean; - over: 'line' | 'annotation' + over: 'line' | 'annotation'; }; currentLine: { changes: boolean; details: boolean; enabled: boolean; - over: 'line' | 'annotation' + over: 'line' | 'annotation'; }; avatars: boolean; @@ -334,7 +342,7 @@ export interface IConfig { statusBar: { enabled: boolean; alignment: 'left' | 'right'; - } + }; }; modes: { [key: string]: IModeConfig }; outputLevel: OutputLevel; @@ -342,7 +350,7 @@ export interface IConfig { recentChanges: { highlight: { locations: HighlightLocations[]; - } + }; toggleMode: AnnotationsToggleMode; }; @@ -367,9 +375,9 @@ export interface IConfig { recentChangeAndAuthors: string; recentChangeOnly: string; authorsOnly: string; - } - } + }; + }; }; advanced: IAdvancedConfig; -} \ No newline at end of file +} diff --git a/src/ui/ipc.ts b/src/ui/ipc.ts index ba0a832..25d1d92 100644 --- a/src/ui/ipc.ts +++ b/src/ui/ipc.ts @@ -10,13 +10,12 @@ export interface SettingsBootstrap extends Bootstrap { scopes: ['user' | 'workspace', string][]; } -export interface WelcomeBootstrap extends Bootstrap { -} +export interface WelcomeBootstrap extends Bootstrap {} export interface SaveSettingsMessage { type: 'saveSettings'; changes: { - [key: string]: any + [key: string]: any; }; removes: string[]; scope: 'user' | 'workspace'; diff --git a/src/ui/settings/app.ts b/src/ui/settings/app.ts index 15aeb3c..09d0cb4 100644 --- a/src/ui/settings/app.ts +++ b/src/ui/settings/app.ts @@ -6,7 +6,6 @@ import { SettingsBootstrap } from '../ipc'; const bootstrap: SettingsBootstrap = (window as any).bootstrap; export class SettingsApp extends App<SettingsBootstrap> { - private _scopes: HTMLSelectElement | null = null; constructor() { @@ -34,15 +33,19 @@ export class SettingsApp extends App<SettingsBootstrap> { protected onBind() { const onSectionHeaderClicked = this.onSectionHeaderClicked.bind(this); - DOM.listenAll('.section__header', 'click', function(this: HTMLInputElement) { return onSectionHeaderClicked(this, ...arguments); }); + DOM.listenAll('.section__header', 'click', function(this: HTMLInputElement) { + return onSectionHeaderClicked(this, ...arguments); + }); const onActionLinkClicked = this.onActionLinkClicked.bind(this); - DOM.listenAll('[data-action]', 'click', function(this: HTMLAnchorElement) { return onActionLinkClicked(this, ...arguments); }); + DOM.listenAll('[data-action]', 'click', function(this: HTMLAnchorElement) { + return onActionLinkClicked(this, ...arguments); + }); } protected getSettingsScope(): 'user' | 'workspace' { return this._scopes != null - ? this._scopes.options[this._scopes.selectedIndex].value as 'user' | 'workspace' + ? (this._scopes.options[this._scopes.selectedIndex].value as 'user' | 'workspace') : 'user'; } @@ -78,8 +81,11 @@ export class SettingsApp extends App<SettingsBootstrap> { } private onSectionHeaderClicked(element: HTMLElement, e: MouseEvent) { - if ((e.target as HTMLElement).matches('i.icon__info') || - (e.target as HTMLElement).matches('a.link__learn-more')) return; + if ( + (e.target as HTMLElement).matches('i.icon__info') || + (e.target as HTMLElement).matches('a.link__learn-more') + ) + return; element.classList.toggle('collapsed'); } diff --git a/src/ui/settings/index.ts b/src/ui/settings/index.ts index 2837931..1944b08 100644 --- a/src/ui/settings/index.ts +++ b/src/ui/settings/index.ts @@ -1,4 +1,4 @@ 'use strict'; import { SettingsApp } from './app'; -new SettingsApp(); \ No newline at end of file +new SettingsApp(); diff --git a/src/ui/shared/app-base.ts b/src/ui/shared/app-base.ts index 6ba230f..cc37053 100644 --- a/src/ui/shared/app-base.ts +++ b/src/ui/shared/app-base.ts @@ -12,15 +12,11 @@ interface VsCodeApi { declare function acquireVsCodeApi(): VsCodeApi; export abstract class App<TBootstrap extends Bootstrap> { - private readonly _api: VsCodeApi; private _changes: { [key: string]: any } = Object.create(null); private _updating: boolean = false; - constructor( - protected readonly appName: string, - protected readonly bootstrap: TBootstrap - ) { + constructor(protected readonly appName: string, protected readonly bootstrap: TBootstrap) { this.log(`${this.appName}.ctor`); this._api = acquireVsCodeApi(); @@ -40,7 +36,6 @@ export abstract class App<TBootstrap extends Bootstrap> { changes: { ...this._changes }, removes: Object.keys(this._changes).filter(k => this._changes[k] === undefined), scope: this.getSettingsScope() - } as SaveSettingsMessage); this._changes = Object.create(null); @@ -54,8 +49,8 @@ export abstract class App<TBootstrap extends Bootstrap> { console.log(message); } - protected onBind() { } - protected onInitialize() { } + protected onBind() {} + protected onInitialize() {} protected onInputBlurred(element: HTMLInputElement) { this.log(`${this.appName}.onInputBlurred: name=${element.name}, value=${element.value}`); @@ -82,7 +77,9 @@ export abstract class App<TBootstrap extends Bootstrap> { protected onInputChecked(element: HTMLInputElement) { if (this._updating) return; - this.log(`${this.appName}.onInputChecked: name=${element.name}, checked=${element.checked}, value=${element.value}`); + this.log( + `${this.appName}.onInputChecked: name=${element.name}, checked=${element.checked}, value=${element.value}` + ); switch (element.dataset.type) { case 'object': { @@ -92,8 +89,7 @@ export abstract class App<TBootstrap extends Bootstrap> { if (element.checked) { set(setting, props.join('.'), fromCheckboxValue(element.value)); - } - else { + } else { set(setting, props.join('.'), false); } @@ -108,8 +104,7 @@ export abstract class App<TBootstrap extends Bootstrap> { if (!setting.includes(element.value)) { setting.push(element.value); } - } - else { + } else { const i = setting.indexOf(element.value); if (i !== -1) { setting.splice(i, 1); @@ -123,8 +118,7 @@ export abstract class App<TBootstrap extends Bootstrap> { default: { if (element.checked) { this._changes[element.name] = fromCheckboxValue(element.value); - } - else { + } else { this._changes[element.name] = false; } @@ -227,25 +221,39 @@ export abstract class App<TBootstrap extends Bootstrap> { window.addEventListener('message', onMessageReceived); const onInputChecked = this.onInputChecked.bind(this); - DOM.listenAll('input[type=checkbox].setting', 'change', function(this: HTMLInputElement) { return onInputChecked(this, ...arguments); }); + DOM.listenAll('input[type=checkbox].setting', 'change', function(this: HTMLInputElement) { + return onInputChecked(this, ...arguments); + }); const onInputBlurred = this.onInputBlurred.bind(this); - DOM.listenAll('input[type=text].setting, input:not([type]).setting', 'blur', function(this: HTMLInputElement) { return onInputBlurred(this, ...arguments); }); + DOM.listenAll('input[type=text].setting, input:not([type]).setting', 'blur', function(this: HTMLInputElement) { + return onInputBlurred(this, ...arguments); + }); const onInputFocused = this.onInputFocused.bind(this); - DOM.listenAll('input[type=text].setting, input:not([type]).setting', 'focus', function(this: HTMLInputElement) { return onInputFocused(this, ...arguments); }); + DOM.listenAll('input[type=text].setting, input:not([type]).setting', 'focus', function(this: HTMLInputElement) { + return onInputFocused(this, ...arguments); + }); const onInputSelected = this.onInputSelected.bind(this); - DOM.listenAll('select.setting', 'change', function(this: HTMLInputElement) { return onInputSelected(this, ...arguments); }); + DOM.listenAll('select.setting', 'change', function(this: HTMLInputElement) { + return onInputSelected(this, ...arguments); + }); const onTokenMouseDown = this.onTokenMouseDown.bind(this); - DOM.listenAll('[data-token]', 'mousedown', function(this: HTMLElement) { return onTokenMouseDown(this, ...arguments); }); + DOM.listenAll('[data-token]', 'mousedown', function(this: HTMLElement) { + return onTokenMouseDown(this, ...arguments); + }); const onPopupMouseDown = this.onPopupMouseDown.bind(this); - DOM.listenAll('.popup', 'mousedown', function(this: HTMLElement) { return onPopupMouseDown(this, ...arguments); }); + DOM.listenAll('.popup', 'mousedown', function(this: HTMLElement) { + return onPopupMouseDown(this, ...arguments); + }); const onJumpToLinkClicked = this.onJumpToLinkClicked.bind(this); - DOM.listenAll('a.jump-to[href^="#"]', 'click', function(this: HTMLAnchorElement) { return onJumpToLinkClicked(this, ...arguments); }); + DOM.listenAll('a.jump-to[href^="#"]', 'click', function(this: HTMLAnchorElement) { + return onJumpToLinkClicked(this, ...arguments); + }); } private evaluateStateExpression(expression: string, changes: { [key: string]: string | boolean }): boolean { @@ -254,7 +262,8 @@ export abstract class App<TBootstrap extends Bootstrap> { const [lhs, op, rhs] = parseStateExpression(expr); switch (op) { - case '=': { // Equals + case '=': { + // Equals let value = changes[lhs]; if (value === undefined) { value = this.getSettingValue<string | boolean>(lhs) || false; @@ -262,7 +271,8 @@ export abstract class App<TBootstrap extends Bootstrap> { state = rhs !== undefined ? rhs === '' + value : !!value; break; } - case '!': { // Not equals + case '!': { + // Not equals let value = changes[lhs]; if (value === undefined) { value = this.getSettingValue<string | boolean>(lhs) || false; @@ -270,7 +280,8 @@ export abstract class App<TBootstrap extends Bootstrap> { state = rhs !== undefined ? rhs !== '' + value : !value; break; } - case '+': { // Contains + case '+': { + // Contains if (rhs !== undefined) { const setting = this.getSettingValue<string[]>(lhs); state = setting !== undefined ? setting.includes(rhs.toString()) : false; @@ -332,13 +343,16 @@ export abstract class App<TBootstrap extends Bootstrap> { try { for (const el of document.querySelectorAll<HTMLInputElement>('input[type=checkbox].setting')) { - const checked = el.dataset.type === 'array' - ? (this.getSettingValue<string[]>(el.name) || []).includes(el.value) - : this.getSettingValue<boolean>(el.name) || false; + const checked = + el.dataset.type === 'array' + ? (this.getSettingValue<string[]>(el.name) || []).includes(el.value) + : this.getSettingValue<boolean>(el.name) || false; el.checked = checked; } - for (const el of document.querySelectorAll<HTMLInputElement>('input[type=text].setting, input:not([type]).setting')) { + for (const el of document.querySelectorAll<HTMLInputElement>( + 'input[type=text].setting, input:not([type]).setting' + )) { el.value = this.getSettingValue<string>(el.name) || ''; } @@ -349,8 +363,7 @@ export abstract class App<TBootstrap extends Bootstrap> { option.selected = true; } } - } - finally { + } finally { this._updating = false; } @@ -373,15 +386,13 @@ export abstract class App<TBootstrap extends Bootstrap> { const disabled = !this.evaluateStateExpression(el.dataset.enablement!, state); if (disabled) { el.setAttribute('disabled', ''); - } - else { + } else { el.removeAttribute('disabled'); } if (el.matches('input,select')) { (el as HTMLInputElement | HTMLSelectElement).disabled = disabled; - } - else { + } else { const input = el.querySelector<HTMLInputElement | HTMLSelectElement>('input,select'); if (input == null) continue; @@ -403,11 +414,11 @@ function ensureIfBoolean(value: string | boolean): string | boolean { return value; } -function get<T>(o: { [key: string ]: any}, path: string): T | undefined { - return path.split('.').reduce((o = {}, key) => o == null ? undefined : o[key], o) as T; +function get<T>(o: { [key: string]: any }, path: string): T | undefined { + return path.split('.').reduce((o = {}, key) => (o == null ? undefined : o[key]), o) as T; } -function set(o: { [key: string ]: any}, path: string, value: any): { [key: string ]: any} { +function set(o: { [key: string]: any }, path: string, value: any): { [key: string]: any } { const props = path.split('.'); const length = props.length; const lastIndex = length - 1; @@ -421,9 +432,7 @@ function set(o: { [key: string ]: any}, path: string, value: any): { [key: strin if (index !== lastIndex) { const objValue = nested[key]; - newValue = typeof objValue === 'object' - ? objValue - : {}; + newValue = typeof objValue === 'object' ? objValue : {}; } nested[key] = newValue; @@ -455,8 +464,7 @@ function flatten(o: { [key: string]: any }, path?: string): { [key: string]: any if (typeof value === 'object') { Object.assign(results, flatten(value, path === undefined ? key : `${path}.${key}`)); - } - else { + } else { results[path === undefined ? key : `${path}.${key}`] = value; } } @@ -466,9 +474,13 @@ function flatten(o: { [key: string]: any }, path?: string): { [key: string]: any function fromCheckboxValue(elementValue: any) { switch (elementValue) { - case 'on': return true; - case 'null': return null; - case 'undefined': return undefined; - default: return elementValue; + case 'on': + return true; + case 'null': + return null; + case 'undefined': + return undefined; + default: + return elementValue; } -} \ No newline at end of file +} diff --git a/src/ui/shared/colors.ts b/src/ui/shared/colors.ts index 6c30f9d..2242412 100644 --- a/src/ui/shared/colors.ts +++ b/src/ui/shared/colors.ts @@ -1,10 +1,9 @@ +// tslint:disable-next-line:max-line-length const cssColorRegEx = /^(?:(#?)([0-9a-f]{3}|[0-9a-f]{6})|((?:rgb|hsl)a?)\((-?\d+%?)[,\s]+(-?\d+%?)[,\s]+(-?\d+%?)[,\s]*(-?[\d\.]+%?)?\))$/i; function adjustLight(color: number, amount: number) { const cc = color + amount; - const c = amount < 0 - ? cc < 0 ? 0 : cc - : cc > 255 ? 255 : cc; + const c = amount < 0 ? (cc < 0 ? 0 : cc) : cc > 255 ? 255 : cc; return Math.round(c); } @@ -40,12 +39,7 @@ export function toRgba(color: string) { const hex = result[2]; switch (hex.length) { case 3: - return [ - parseInt(hex[0] + hex[0], 16), - parseInt(hex[1] + hex[1], 16), - parseInt(hex[2] + hex[2], 16), - 1 - ]; + return [parseInt(hex[0] + hex[0], 16), parseInt(hex[1] + hex[1], 16), parseInt(hex[2] + hex[2], 16), 1]; case 6: return [ parseInt(hex.substring(0, 2), 16), @@ -60,19 +54,9 @@ export function toRgba(color: string) { switch (result[3]) { case 'rgb': - return [ - parseInt(result[4], 10), - parseInt(result[5], 10), - parseInt(result[6], 10), - 1 - ]; + return [parseInt(result[4], 10), parseInt(result[5], 10), parseInt(result[6], 10), 1]; case 'rgba': - return [ - parseInt(result[4], 10), - parseInt(result[5], 10), - parseInt(result[6], 10), - parseFloat(result[7]) - ]; + return [parseInt(result[4], 10), parseInt(result[5], 10), parseInt(result[6], 10), parseFloat(result[7])]; default: return null; } diff --git a/src/ui/shared/dom.ts b/src/ui/shared/dom.ts index fc082a3..1819baa 100644 --- a/src/ui/shared/dom.ts +++ b/src/ui/shared/dom.ts @@ -41,4 +41,4 @@ export namespace DOM { el.addEventListener(name, listener, false); } } -} \ No newline at end of file +} diff --git a/src/ui/welcome/app.ts b/src/ui/welcome/app.ts index 4ef2495..18ecc71 100644 --- a/src/ui/welcome/app.ts +++ b/src/ui/welcome/app.ts @@ -6,7 +6,6 @@ import { WelcomeBootstrap } from '../ipc'; const bootstrap: WelcomeBootstrap = (window as any).bootstrap; export class WelcomeApp extends App<WelcomeBootstrap> { - private _commandRelay: HTMLAnchorElement | null | undefined; constructor() { @@ -19,7 +18,9 @@ export class WelcomeApp extends App<WelcomeBootstrap> { protected onBind() { const onClicked = this.onClicked.bind(this); - DOM.listenAll('button[data-href]', 'click', function(this: HTMLButtonElement) { onClicked(this); }); + DOM.listenAll('button[data-href]', 'click', function(this: HTMLButtonElement) { + onClicked(this); + }); } private onClicked(element: HTMLButtonElement) { @@ -34,5 +35,4 @@ export class WelcomeApp extends App<WelcomeBootstrap> { this._commandRelay.setAttribute('href', command); this._commandRelay.click(); } - } diff --git a/src/ui/welcome/index.ts b/src/ui/welcome/index.ts index db8a537..4096bc0 100644 --- a/src/ui/welcome/index.ts +++ b/src/ui/welcome/index.ts @@ -1,4 +1,4 @@ 'use strict'; import { WelcomeApp } from './app'; -new WelcomeApp(); \ No newline at end of file +new WelcomeApp(); diff --git a/src/views/activeRepositoryNode.ts b/src/views/activeRepositoryNode.ts index 1add1bb..72f7169 100644 --- a/src/views/activeRepositoryNode.ts +++ b/src/views/activeRepositoryNode.ts @@ -9,7 +9,6 @@ import { GitUri } from '../gitService'; import { RepositoryNode } from './repositoryNode'; export class ActiveRepositoryNode extends ExplorerNode { - private _repositoryNode: RepositoryNode | undefined; constructor( @@ -84,15 +83,14 @@ export class ActiveRepositoryNode extends ExplorerNode { } async getChildren(): Promise<ExplorerNode[]> { - return this._repositoryNode !== undefined - ? this._repositoryNode.getChildren() - : []; + return this._repositoryNode !== undefined ? this._repositoryNode.getChildren() : []; } getTreeItem(): TreeItem { - const item = this._repositoryNode !== undefined - ? this._repositoryNode.getTreeItem() - : new TreeItem('No active repository', TreeItemCollapsibleState.None); + const item = + this._repositoryNode !== undefined + ? this._repositoryNode.getTreeItem() + : new TreeItem('No active repository', TreeItemCollapsibleState.None); item.id = this.id; return item; } diff --git a/src/views/branchNode.ts b/src/views/branchNode.ts index b36174e..245697b 100644 --- a/src/views/branchNode.ts +++ b/src/views/branchNode.ts @@ -10,7 +10,6 @@ import { GitExplorer } from './gitExplorer'; import { GitBranch, GitUri } from '../gitService'; export class BranchNode extends ExplorerRefNode { - readonly supportsPaging: boolean = true; constructor( @@ -47,7 +46,11 @@ export class BranchNode extends ExplorerRefNode { const branches = await Container.git.getBranches(this.uri.repoPath); // Get the sha length, since `git branch` can return variable length shas const shaLength = branches[0].sha!.length; - const branchesBySha = Arrays.groupByFilterMap(branches, b => b.sha!, b => b.name === this.branch.name ? undefined : b.name); + const branchesBySha = Arrays.groupByFilterMap( + branches, + b => b.sha!, + b => (b.name === this.branch.name ? undefined : b.name) + ); const getBranchTips = (sha: string) => { const branches = branchesBySha.get(sha.substr(0, shaLength)); @@ -55,7 +58,10 @@ export class BranchNode extends ExplorerRefNode { return branches.join(', '); }; - const children: (CommitNode | ShowAllNode)[] = [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer, this.branch, getBranchTips))]; + const children: (CommitNode | ShowAllNode)[] = [ + ...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer, this.branch, getBranchTips)) + ]; + if (log.truncated) { children.push(new ShowAllNode('Show All Commits', this, this.explorer)); } @@ -69,9 +75,12 @@ export class BranchNode extends ExplorerRefNode { if (!this.branch.remote && this.branch.tracking !== undefined) { if (this.explorer.config.showTrackingBranch) { - name += `${this.branch.getTrackingStatus({ prefix: `${GlyphChars.Space} ` })}${GlyphChars.Space} ${GlyphChars.ArrowLeftRightLong}${GlyphChars.Space} ${this.branch.tracking}`; + name += `${this.branch.getTrackingStatus({ prefix: `${GlyphChars.Space} ` })}${GlyphChars.Space} ${ + GlyphChars.ArrowLeftRightLong + }${GlyphChars.Space} ${this.branch.tracking}`; } - tooltip += `\n\nTracking ${GlyphChars.Dash} ${this.branch.tracking}\n${this.branch.getTrackingStatus({ empty: 'up-to-date', expand: true, separator: '\n' })}`; + tooltip += `\n\nTracking ${GlyphChars.Dash} ${this.branch.tracking} +${this.branch.getTrackingStatus({ empty: 'up-to-date', expand: true, separator: '\n' })}`; if (this.branch.state.ahead || this.branch.state.behind) { if (this.branch.state.behind) { @@ -83,7 +92,10 @@ export class BranchNode extends ExplorerRefNode { } } - const item = new TreeItem(`${this.markCurrent && this.current ? `${GlyphChars.Check} ${GlyphChars.Space}` : ''}${name}`, TreeItemCollapsibleState.Collapsed); + const item = new TreeItem( + `${this.markCurrent && this.current ? `${GlyphChars.Check} ${GlyphChars.Space}` : ''}${name}`, + TreeItemCollapsibleState.Collapsed + ); item.tooltip = tooltip; if (this.branch.remote) { @@ -95,9 +107,7 @@ export class BranchNode extends ExplorerRefNode { : ResourceType.CurrentBranch; } else { - item.contextValue = !!this.branch.tracking - ? ResourceType.BranchWithTracking - : ResourceType.Branch; + item.contextValue = !!this.branch.tracking ? ResourceType.BranchWithTracking : ResourceType.Branch; } item.iconPath = { diff --git a/src/views/branchOrTagFolderNode.ts b/src/views/branchOrTagFolderNode.ts index f7645dd..4c8d264 100644 --- a/src/views/branchOrTagFolderNode.ts +++ b/src/views/branchOrTagFolderNode.ts @@ -8,7 +8,6 @@ import { GitUri } from '../gitService'; import { TagNode } from './tagNode'; export class BranchOrTagFolderNode extends ExplorerNode { - constructor( public readonly repoPath: string, public readonly folderName: string, @@ -26,7 +25,9 @@ export class BranchOrTagFolderNode extends ExplorerNode { for (const folder of Objects.values(this.root.children)) { if (folder.value === undefined) { - children.push(new BranchOrTagFolderNode(this.repoPath, folder.name, folder.relativePath, folder, this.explorer)); + children.push( + new BranchOrTagFolderNode(this.repoPath, folder.name, folder.relativePath, folder, this.explorer) + ); continue; } children.push(folder.value); diff --git a/src/views/branchesNode.ts b/src/views/branchesNode.ts index 9896bf0..108365c 100644 --- a/src/views/branchesNode.ts +++ b/src/views/branchesNode.ts @@ -10,7 +10,6 @@ import { GitExplorer } from './gitExplorer'; import { GitUri, Repository } from '../gitService'; export class BranchesNode extends ExplorerNode { - constructor( uri: GitUri, private readonly repo: Repository, @@ -31,21 +30,23 @@ export class BranchesNode extends ExplorerNode { branches.sort((a, b) => (a.current ? -1 : 1) - (b.current ? -1 : 1) || a.name.localeCompare(b.name)); // filter local branches - const branchNodes = [...Iterables.filterMap(branches, b => b.remote ? undefined : new BranchNode(b, this.uri, this.explorer))]; + const branchNodes = [ + ...Iterables.filterMap(branches, b => (b.remote ? undefined : new BranchNode(b, this.uri, this.explorer))) + ]; if (this.explorer.config.branches.layout === ExplorerBranchesLayout.List) return branchNodes; // Take out the current branch, since that should always be first and un-nested - const current = (branchNodes.length > 0 && branchNodes[0].current) - ? branchNodes.splice(0, 1)[0] - : undefined; + const current = branchNodes.length > 0 && branchNodes[0].current ? branchNodes.splice(0, 1)[0] : undefined; - const hierarchy = Arrays.makeHierarchical(branchNodes, - n => n.branch.isValid() ? n.branch.getName().split('/') : [n.branch.name], + const hierarchy = Arrays.makeHierarchical( + branchNodes, + n => (n.branch.isValid() ? n.branch.getName().split('/') : [n.branch.name]), (...paths: string[]) => paths.join('/'), - this.explorer.config.files.compact); + this.explorer.config.files.compact + ); const root = new BranchOrTagFolderNode(this.repo.path, '', undefined, hierarchy, this.explorer); - const children = await root.getChildren() as (BranchOrTagFolderNode | BranchNode)[]; + const children = (await root.getChildren()) as (BranchOrTagFolderNode | BranchNode)[]; // If we found a current branch, insert it at the start if (current !== undefined) { @@ -59,9 +60,8 @@ export class BranchesNode extends ExplorerNode { const item = new TreeItem(`Branches`, TreeItemCollapsibleState.Collapsed); const remotes = await this.repo.getRemotes(); - item.contextValue = (remotes !== undefined && remotes.length > 0) - ? ResourceType.BranchesWithRemotes - : ResourceType.Branches; + item.contextValue = + remotes !== undefined && remotes.length > 0 ? ResourceType.BranchesWithRemotes : ResourceType.Branches; item.iconPath = { dark: Container.context.asAbsolutePath('images/dark/icon-branch.svg'), diff --git a/src/views/commitFileNode.ts b/src/views/commitFileNode.ts index d1abe22..e000b51 100644 --- a/src/views/commitFileNode.ts +++ b/src/views/commitFileNode.ts @@ -4,7 +4,16 @@ import { Commands, DiffWithPreviousCommandArgs } from '../commands'; import { GlyphChars } from '../constants'; import { Container } from '../container'; import { Explorer, ExplorerNode, ResourceType } from './explorerNode'; -import { CommitFormatter, getGitStatusIcon, GitLogCommit, GitUri, ICommitFormatOptions, IGitStatusFile, IStatusFormatOptions, StatusFileFormatter } from '../gitService'; +import { + CommitFormatter, + getGitStatusIcon, + GitLogCommit, + GitUri, + ICommitFormatOptions, + IGitStatusFile, + IStatusFormatOptions, + StatusFileFormatter +} from '../gitService'; import * as path from 'path'; export enum CommitFileNodeDisplayAs { @@ -19,7 +28,6 @@ export enum CommitFileNodeDisplayAs { } export class CommitFileNode extends ExplorerNode { - readonly priority: boolean = false; readonly repoPath: string; @@ -42,7 +50,10 @@ export class CommitFileNode extends ExplorerNode { // See if we can get the commit directly from the multi-file commit const commit = this.commit.toFileCommit(this.status); if (commit === undefined) { - const log = await Container.git.getLogForFile(this.repoPath, this.status.fileName, { maxCount: 2, ref: this.commit.sha }); + const log = await Container.git.getLogForFile(this.repoPath, this.status.fileName, { + maxCount: 2, + ref: this.commit.sha + }); if (log !== undefined) { this.commit = log.commits.get(this.commit.sha) || this.commit; } @@ -93,22 +104,15 @@ export class CommitFileNode extends ExplorerNode { private _label: string | undefined; get label() { if (this._label === undefined) { - this._label = (this.displayAs & CommitFileNodeDisplayAs.CommitLabel) - ? CommitFormatter.fromTemplate( - this.getCommitTemplate(), - this.commit, - { - truncateMessageAtNewLine: true, - dateFormat: Container.config.defaultDateFormat - } as ICommitFormatOptions - ) - : StatusFileFormatter.fromTemplate( - this.getCommitFileTemplate(), - this.status, - { - relativePath: this.relativePath - } as IStatusFormatOptions - ); + this._label = + this.displayAs & CommitFileNodeDisplayAs.CommitLabel + ? CommitFormatter.fromTemplate(this.getCommitTemplate(), this.commit, { + truncateMessageAtNewLine: true, + dateFormat: Container.config.defaultDateFormat + } as ICommitFormatOptions) + : StatusFileFormatter.fromTemplate(this.getCommitFileTemplate(), this.status, { + relativePath: this.relativePath + } as IStatusFormatOptions); } return this._label; } @@ -173,4 +177,4 @@ export class CommitFileNode extends ExplorerNode { ] }; } -} \ No newline at end of file +} diff --git a/src/views/commitNode.ts b/src/views/commitNode.ts index c16ccb1..3431642 100644 --- a/src/views/commitNode.ts +++ b/src/views/commitNode.ts @@ -12,7 +12,6 @@ import { CommitFormatter, GitBranch, GitLogCommit, ICommitFormatOptions } from ' import * as path from 'path'; export class CommitNode extends ExplorerRefNode { - constructor( public readonly commit: GitLogCommit, private readonly explorer: Explorer, @@ -29,15 +28,22 @@ export class CommitNode extends ExplorerRefNode { async getChildren(): Promise<ExplorerNode[]> { const commit = this.commit; let children: IFileExplorerNode[] = [ - ...Iterables.map(commit.fileStatuses, s => new CommitFileNode(s, commit.toFileCommit(s), this.explorer, CommitFileNodeDisplayAs.File)) + ...Iterables.map( + commit.fileStatuses, + s => new CommitFileNode(s, commit.toFileCommit(s), this.explorer, CommitFileNodeDisplayAs.File) + ) ]; if (this.explorer.config.files.layout !== ExplorerFilesLayout.List) { - const hierarchy = Arrays.makeHierarchical(children, n => n.uri.getRelativePath().split('/'), - (...paths: string[]) => Strings.normalizePath(path.join(...paths)), this.explorer.config.files.compact); + const hierarchy = Arrays.makeHierarchical( + children, + n => n.uri.getRelativePath().split('/'), + (...paths: string[]) => Strings.normalizePath(path.join(...paths)), + this.explorer.config.files.compact + ); const root = new FolderNode(this.repoPath, '', undefined, hierarchy, this.explorer); - children = await root.getChildren() as IFileExplorerNode[]; + children = (await root.getChildren()) as IFileExplorerNode[]; } else { children.sort((a, b) => a.label!.localeCompare(b.label!)); @@ -53,18 +59,20 @@ export class CommitNode extends ExplorerRefNode { const branchTips = this.getBranchTips && this.getBranchTips(this.commit.sha); if (branchTips !== undefined) { - label = `${GlyphChars.AngleBracketLeftHeavy}${GlyphChars.SpaceThin}${branchTips}${GlyphChars.SpaceThin}${GlyphChars.AngleBracketRightHeavy}${GlyphChars.ArrowHeadRight}${GlyphChars.Space} ${label}`; + label = `${GlyphChars.AngleBracketLeftHeavy}${GlyphChars.SpaceThin}${branchTips}${GlyphChars.SpaceThin}${ + GlyphChars.AngleBracketRightHeavy + }${GlyphChars.ArrowHeadRight}${GlyphChars.Space} ${label}`; } const item = new TreeItem(label, TreeItemCollapsibleState.Collapsed); - item.contextValue = (this.branch === undefined || this.branch.current) - ? ResourceType.CommitOnCurrentBranch - : ResourceType.Commit; + item.contextValue = + this.branch === undefined || this.branch.current ? ResourceType.CommitOnCurrentBranch : ResourceType.Commit; if (this.explorer.config.avatars) { item.iconPath = this.commit.getGravatarUri(Container.config.defaultGravatarsStyle); - } else { + } + else { item.iconPath = { dark: Container.context.asAbsolutePath('images/dark/icon-commit.svg'), light: Container.context.asAbsolutePath('images/light/icon-commit.svg') @@ -74,7 +82,9 @@ export class CommitNode extends ExplorerRefNode { item.tooltip = CommitFormatter.fromTemplate( this.commit.isUncommitted ? `\${author} ${GlyphChars.Dash} \${id}\n\${ago} (\${date})` - : `\${author} ${GlyphChars.Dash} \${id}${branchTips !== undefined ? ` (${branchTips})` : ''}\n\${ago} (\${date})\n\n\${message}`, + : `\${author} ${GlyphChars.Dash} \${id}${ + branchTips !== undefined ? ` (${branchTips})` : '' + }\n\${ago} (\${date})\n\n\${message}`, this.commit, { dateFormat: Container.config.defaultDateFormat @@ -101,4 +111,4 @@ export class CommitNode extends ExplorerRefNode { ] }; } -} \ No newline at end of file +} diff --git a/src/views/commitResultsNode.ts b/src/views/commitResultsNode.ts index aded0c4..13434af 100644 --- a/src/views/commitResultsNode.ts +++ b/src/views/commitResultsNode.ts @@ -8,7 +8,6 @@ import { Explorer, ExplorerNode, MessageNode, ResourceType } from './explorerNod import { CommitFormatter, GitLogCommit } from '../gitService'; export class CommitResultsNode extends ExplorerNode { - constructor( public readonly commit: GitLogCommit, private readonly explorer: Explorer, @@ -19,14 +18,25 @@ export class CommitResultsNode extends ExplorerNode { async getChildren(): Promise<ExplorerNode[]> { const children = await new CommitNode(this.commit, this.explorer).getChildren(); - children.splice(0, 0, new MessageNode(CommitFormatter.fromTemplate('${message}', this.commit, { truncateMessageAtNewLine: true }), CommitFormatter.fromTemplate('${message}', this.commit))); + children.splice( + 0, + 0, + new MessageNode( + CommitFormatter.fromTemplate('${message}', this.commit, { truncateMessageAtNewLine: true }), + CommitFormatter.fromTemplate('${message}', this.commit) + ) + ); return children; } async getTreeItem(): Promise<TreeItem> { - const label = CommitFormatter.fromTemplate(`Commit \${sha} ${Strings.pad(GlyphChars.Dash, 1, 1)} \${authorAgoOrDate}`, this.commit, Container.config.defaultDateFormat); + const label = CommitFormatter.fromTemplate( + `Commit \${sha} ${Strings.pad(GlyphChars.Dash, 1, 1)} \${authorAgoOrDate}`, + this.commit, + Container.config.defaultDateFormat + ); const item = new TreeItem(label, TreeItemCollapsibleState.Expanded); item.contextValue = this.contextValue; return item; } -} \ No newline at end of file +} diff --git a/src/views/commitsNode.ts b/src/views/commitsNode.ts index 110dee4..0d746a4 100644 --- a/src/views/commitsNode.ts +++ b/src/views/commitsNode.ts @@ -6,7 +6,6 @@ import { Explorer, ExplorerNode, ResourceType, ShowAllNode } from './explorerNod import { GitLog, GitUri } from '../gitService'; export class CommitsNode extends ExplorerNode { - readonly supportsPaging: boolean = true; constructor( @@ -21,7 +20,10 @@ export class CommitsNode extends ExplorerNode { const log = await this.logFn(this.maxCount); if (log === undefined) return []; - const children: (CommitNode | ShowAllNode)[] = [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer))]; + const children: (CommitNode | ShowAllNode)[] = [ + ...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer)) + ]; + if (log.truncated) { children.push(new ShowAllNode('Show All Commits', this, this.explorer)); } diff --git a/src/views/commitsResultsNode.ts b/src/views/commitsResultsNode.ts index 86f4c5f..8efd8cd 100644 --- a/src/views/commitsResultsNode.ts +++ b/src/views/commitsResultsNode.ts @@ -6,10 +6,9 @@ import { Explorer, ExplorerNode, ResourceType, ShowAllNode } from './explorerNod import { GitLog, GitUri } from '../gitService'; export class CommitsResultsNode extends ExplorerNode { - readonly supportsPaging: boolean = true; - private _cache: { label: string, log: GitLog | undefined } | undefined; + private _cache: { label: string; log: GitLog | undefined } | undefined; constructor( public readonly repoPath: string, @@ -25,7 +24,10 @@ export class CommitsResultsNode extends ExplorerNode { const log = await this.getLog(); if (log === undefined) return []; - const children: (CommitNode | ShowAllNode)[] = [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer))]; + const children: (CommitNode | ShowAllNode)[] = [ + ...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer)) + ]; + if (log.truncated) { children.push(new ShowAllNode('Show All Results', this, this.explorer)); } @@ -35,7 +37,10 @@ export class CommitsResultsNode extends ExplorerNode { async getTreeItem(): Promise<TreeItem> { const log = await this.getLog(); - const item = new TreeItem(await this.getLabel(), log && log.count > 0 ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.None); + const item = new TreeItem( + await this.getLabel(), + log && log.count > 0 ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.None + ); item.contextValue = this.contextValue; return item; } @@ -66,4 +71,4 @@ export class CommitsResultsNode extends ExplorerNode { const cache = await this.ensureCache(); return cache.log; } -} \ No newline at end of file +} diff --git a/src/views/comparisonResultsNode.ts b/src/views/comparisonResultsNode.ts index 841c5c9..9bcd215 100644 --- a/src/views/comparisonResultsNode.ts +++ b/src/views/comparisonResultsNode.ts @@ -9,7 +9,6 @@ import { GitLog, GitService, GitUri } from '../gitService'; import { StatusFilesResultsNode } from './statusFilesResultsNode'; export class ComparisonResultsNode extends ExplorerNode { - constructor( public readonly repoPath: string, public readonly ref1: NamedRef, @@ -22,7 +21,11 @@ export class ComparisonResultsNode extends ExplorerNode { async getChildren(): Promise<ExplorerNode[]> { this.resetChildren(); - const commitsQueryFn = (maxCount: number | undefined) => Container.git.getLog(this.uri.repoPath!, { maxCount: maxCount, ref: `${this.ref1.ref}...${this.ref2.ref || 'HEAD'}` }); + const commitsQueryFn = (maxCount: number | undefined) => + Container.git.getLog(this.uri.repoPath!, { + maxCount: maxCount, + ref: `${this.ref1.ref}...${this.ref2.ref || 'HEAD'}` + }); const commitsLabelFn = async (log: GitLog | undefined) => { const count = log !== undefined ? log.count : 0; const truncated = log !== undefined ? log.truncated : false; @@ -41,13 +44,17 @@ export class ComparisonResultsNode extends ExplorerNode { async getTreeItem(): Promise<TreeItem> { let repository = ''; - if (await Container.git.getRepositoryCount() > 1) { + if ((await Container.git.getRepositoryCount()) > 1) { const repo = await Container.git.getRepository(this.uri.repoPath!); repository = ` ${Strings.pad(GlyphChars.Dash, 1, 1)} ${(repo && repo.formattedName) || this.uri.repoPath}`; } - const item = new TreeItem(`Comparing ${this.ref1.label || GitService.shortenSha(this.ref1.ref, { working: 'Working Tree' })} to ${this.ref2.label || GitService.shortenSha(this.ref2.ref, { working: 'Working Tree' })}${repository}`, TreeItemCollapsibleState.Expanded); + const item = new TreeItem( + `Comparing ${this.ref1.label || GitService.shortenSha(this.ref1.ref, { working: 'Working Tree' })} to ${this + .ref2.label || GitService.shortenSha(this.ref2.ref, { working: 'Working Tree' })}${repository}`, + TreeItemCollapsibleState.Expanded + ); item.contextValue = ResourceType.ComparisonResults; return item; } -} \ No newline at end of file +} diff --git a/src/views/explorerCommands.ts b/src/views/explorerCommands.ts index aa6fc6d..183c19e 100644 --- a/src/views/explorerCommands.ts +++ b/src/views/explorerCommands.ts @@ -3,8 +3,26 @@ import { commands, Disposable, InputBoxOptions, Terminal, TextDocumentShowOption import { CommandContext, extensionTerminalName, setCommandContext } from '../constants'; import { Container } from '../container'; import { BranchNode, ExplorerNode, TagNode } from '../views/gitExplorer'; -import { CommitFileNode, CommitNode, ExplorerRefNode, RemoteNode, StashFileNode, StashNode, StatusFileCommitsNode, StatusUpstreamNode } from './explorerNodes'; -import { Commands, DiffWithCommandArgs, DiffWithCommandArgsRevision, DiffWithPreviousCommandArgs, DiffWithWorkingCommandArgs, openEditor, OpenFileInRemoteCommandArgs, OpenFileRevisionCommandArgs } from '../commands'; +import { + CommitFileNode, + CommitNode, + ExplorerRefNode, + RemoteNode, + StashFileNode, + StashNode, + StatusFileCommitsNode, + StatusUpstreamNode +} from './explorerNodes'; +import { + Commands, + DiffWithCommandArgs, + DiffWithCommandArgsRevision, + DiffWithPreviousCommandArgs, + DiffWithWorkingCommandArgs, + openEditor, + OpenFileInRemoteCommandArgs, + OpenFileRevisionCommandArgs +} from '../commands'; import { GitService, GitUri } from '../gitService'; import { RepositoryNode } from './repositoryNode'; import { StatusNode } from './statusNode'; @@ -21,7 +39,6 @@ interface ICompareSelected { } export class ExplorerCommands extends Disposable { - private _disposable: Disposable | undefined; private _terminal: Terminal | undefined; private _terminalCwd: string | undefined; @@ -36,7 +53,11 @@ export class ExplorerCommands extends Disposable { commands.registerCommand('gitlens.explorers.openFileRevisionInRemote', this.openFileRevisionInRemote, this); commands.registerCommand('gitlens.explorers.openChangedFiles', this.openChangedFiles, this); commands.registerCommand('gitlens.explorers.openChangedFileChanges', this.openChangedFileChanges, this); - commands.registerCommand('gitlens.explorers.openChangedFileChangesWithWorking', this.openChangedFileChangesWithWorking, this); + commands.registerCommand( + 'gitlens.explorers.openChangedFileChangesWithWorking', + this.openChangedFileChangesWithWorking, + this + ); commands.registerCommand('gitlens.explorers.openChangedFileRevisions', this.openChangedFileRevisions, this); commands.registerCommand('gitlens.explorers.applyChanges', this.applyChanges, this); commands.registerCommand('gitlens.explorers.closeRepository', this.closeRepository, this); @@ -51,8 +72,16 @@ export class ExplorerCommands extends Disposable { commands.registerCommand('gitlens.explorers.terminalDeleteBranch', this.terminalDeleteBranch, this); commands.registerCommand('gitlens.explorers.terminalMergeBranch', this.terminalMergeBranch, this); commands.registerCommand('gitlens.explorers.terminalRebaseBranch', this.terminalRebaseBranch, this); - commands.registerCommand('gitlens.explorers.terminalRebaseBranchToRemote', this.terminalRebaseBranchToRemote, this); - commands.registerCommand('gitlens.explorers.terminalSquashBranchIntoCommit', this.terminalSquashBranchIntoCommit, this); + commands.registerCommand( + 'gitlens.explorers.terminalRebaseBranchToRemote', + this.terminalRebaseBranchToRemote, + this + ); + commands.registerCommand( + 'gitlens.explorers.terminalSquashBranchIntoCommit', + this.terminalSquashBranchIntoCommit, + this + ); commands.registerCommand('gitlens.explorers.terminalCherryPickCommit', this.terminalCherryPickCommit, this); commands.registerCommand('gitlens.explorers.terminalPushCommit', this.terminalPushCommit, this); commands.registerCommand('gitlens.explorers.terminalRebaseCommit', this.terminalRebaseCommit, this); @@ -103,7 +132,11 @@ export class ExplorerCommands extends Disposable { const commonAncestor = await Container.git.getMergeBase(node.repoPath, branch.name, node.ref); if (commonAncestor === undefined) return; - Container.resultsExplorer.showComparisonInResults(node.repoPath, { ref: commonAncestor, label: `ancestry with ${node.ref} (${GitService.shortenSha(commonAncestor)})` }, ''); + Container.resultsExplorer.showComparisonInResults( + node.repoPath, + { ref: commonAncestor, label: `ancestry with ${node.ref} (${GitService.shortenSha(commonAncestor)})` }, + '' + ); } private compareWithSelected(node: ExplorerNode) { @@ -143,7 +176,6 @@ export class ExplorerCommands extends Disposable { showOptions: { preserveFocus: true, preview: false - } }; return commands.executeCommand(Commands.DiffWithWorking, node.commit.toGitUri(), args); @@ -153,54 +185,87 @@ export class ExplorerCommands extends Disposable { return openEditor(node.uri, { preserveFocus: true, preview: false }); } - private openFileRevision(node: CommitFileNode | StashFileNode | StatusFileCommitsNode, options: OpenFileRevisionCommandArgs = { showOptions: { preserveFocus: true, preview: false } }) { - const uri = options.uri || (node.commit.status === 'D' - ? GitUri.toRevisionUri(node.commit.previousSha!, node.commit.previousUri.fsPath, node.commit.repoPath) - : GitUri.toRevisionUri(node.uri)); + private openFileRevision( + node: CommitFileNode | StashFileNode | StatusFileCommitsNode, + options: OpenFileRevisionCommandArgs = { showOptions: { preserveFocus: true, preview: false } } + ) { + const uri = + options.uri || + (node.commit.status === 'D' + ? GitUri.toRevisionUri(node.commit.previousSha!, node.commit.previousUri.fsPath, node.commit.repoPath) + : GitUri.toRevisionUri(node.uri)); return openEditor(uri, options.showOptions || { preserveFocus: true, preview: false }); } - private async openChangedFileChanges(node: CommitFileNode | StashFileNode | StatusFileCommitsNode, options: TextDocumentShowOptions = { preserveFocus: false, preview: false }) { + private async openChangedFileChanges( + node: CommitFileNode | StashFileNode | StatusFileCommitsNode, + options: TextDocumentShowOptions = { preserveFocus: false, preview: false } + ) { const repoPath = node.commit.repoPath; - const uris = node.commit.fileStatuses - .map(s => GitUri.fromFileStatus(s, repoPath)); + const uris = node.commit.fileStatuses.map(s => GitUri.fromFileStatus(s, repoPath)); for (const uri of uris) { - await this.openDiffWith(repoPath, - { uri: uri, sha: node.commit.previousSha !== undefined ? node.commit.previousSha : GitService.deletedSha }, - { uri: uri, sha: node.commit.sha }, options); + await this.openDiffWith( + repoPath, + { + uri: uri, + sha: node.commit.previousSha !== undefined ? node.commit.previousSha : GitService.deletedSha + }, + { uri: uri, sha: node.commit.sha }, + options + ); } } - private async openChangedFileChangesWithWorking(node: CommitFileNode | StashFileNode | StatusFileCommitsNode, options: TextDocumentShowOptions = { preserveFocus: false, preview: false }) { + private async openChangedFileChangesWithWorking( + node: CommitFileNode | StashFileNode | StatusFileCommitsNode, + options: TextDocumentShowOptions = { preserveFocus: false, preview: false } + ) { const repoPath = node.commit.repoPath; - const uris = Arrays.filterMap(node.commit.fileStatuses, - f => f.status !== 'D' ? GitUri.fromFileStatus(f, repoPath) : undefined); + const uris = Arrays.filterMap( + node.commit.fileStatuses, + f => (f.status !== 'D' ? GitUri.fromFileStatus(f, repoPath) : undefined) + ); for (const uri of uris) { await this.openDiffWith(repoPath, { uri: uri, sha: node.commit.sha }, { uri: uri, sha: '' }, options); } } - private async openChangedFiles(node: CommitNode | StashNode, options: TextDocumentShowOptions = { preserveFocus: false, preview: false }) { + private async openChangedFiles( + node: CommitNode | StashNode, + options: TextDocumentShowOptions = { preserveFocus: false, preview: false } + ) { const repoPath = node.commit.repoPath; - const uris = Arrays.filterMap(node.commit.fileStatuses, - f => GitUri.fromFileStatus(f, repoPath)); + const uris = Arrays.filterMap(node.commit.fileStatuses, f => GitUri.fromFileStatus(f, repoPath)); for (const uri of uris) { await openEditor(uri, options); } } - private async openChangedFileRevisions(node: CommitNode | StashNode, options: TextDocumentShowOptions = { preserveFocus: false, preview: false }) { - const uris = Arrays.filterMap(node.commit.fileStatuses, - f => GitUri.toRevisionUri(f.status === 'D' ? node.commit.previousFileSha : node.commit.sha, f, node.commit.repoPath)); + private async openChangedFileRevisions( + node: CommitNode | StashNode, + options: TextDocumentShowOptions = { preserveFocus: false, preview: false } + ) { + const uris = Arrays.filterMap(node.commit.fileStatuses, f => + GitUri.toRevisionUri( + f.status === 'D' ? node.commit.previousFileSha : node.commit.sha, + f, + node.commit.repoPath + ) + ); for (const uri of uris) { await openEditor(uri, options); } } - private async openDiffWith(repoPath: string, lhs: DiffWithCommandArgsRevision, rhs: DiffWithCommandArgsRevision, options: TextDocumentShowOptions = { preserveFocus: false, preview: false }) { + private async openDiffWith( + repoPath: string, + lhs: DiffWithCommandArgsRevision, + rhs: DiffWithCommandArgsRevision, + options: TextDocumentShowOptions = { preserveFocus: false, preview: false } + ) { const diffArgs: DiffWithCommandArgs = { repoPath: repoPath, lhs: lhs, @@ -211,7 +276,9 @@ export class ExplorerCommands extends Disposable { } private async openFileRevisionInRemote(node: CommitFileNode | StashFileNode | StatusFileCommitsNode) { - return commands.executeCommand(Commands.OpenFileInRemote, node.commit.toGitUri(node.commit.status === 'D'), { range: false } as OpenFileInRemoteCommandArgs); + return commands.executeCommand(Commands.OpenFileInRemote, node.commit.toGitUri(node.commit.status === 'D'), { + range: false + } as OpenFileInRemoteCommandArgs); } async terminalCheckoutBranch(node: ExplorerNode) { @@ -289,7 +356,7 @@ export class ExplorerCommands extends Disposable { async terminalPushCommit(node: ExplorerNode) { if (!(node instanceof CommitNode)) return; - const branch = node.branch || await Container.git.getBranch(node.repoPath); + const branch = node.branch || (await Container.git.getBranch(node.repoPath)); if (branch === undefined) return; this.sendTerminalCommand('push', `${branch.getRemote()} ${node.ref}:${branch.getName()}`, node.repoPath); diff --git a/src/views/explorerNode.ts b/src/views/explorerNode.ts index 939e448..8211864 100644 --- a/src/views/explorerNode.ts +++ b/src/views/explorerNode.ts @@ -67,7 +67,6 @@ export type Explorer = GitExplorer | HistoryExplorer | ResultsExplorer; // let id = 0; export abstract class ExplorerNode extends Disposable { - readonly supportsPaging: boolean = false; maxCount: number | undefined; @@ -98,7 +97,7 @@ export abstract class ExplorerNode extends Disposable { return undefined; } - refresh(): void { } + refresh(): void {} resetChildren(): void { if (this.children !== undefined) { @@ -116,7 +115,6 @@ export abstract class ExplorerRefNode extends ExplorerNode { } export class MessageNode extends ExplorerNode { - constructor( private readonly message: string, private readonly tooltip?: string @@ -137,7 +135,6 @@ export class MessageNode extends ExplorerNode { } export class PagerNode extends ExplorerNode { - args: RefreshNodeCommandArgs = {}; constructor( @@ -173,14 +170,13 @@ export class PagerNode extends ExplorerNode { } export class ShowAllNode extends PagerNode { - args: RefreshNodeCommandArgs = { maxCount: 0 }; - constructor( - message: string, - node: ExplorerNode, - explorer: Explorer - ) { - super(`${message} ${GlyphChars.Space}${GlyphChars.Dash}${GlyphChars.Space} this may take a while`, node, explorer); + constructor(message: string, node: ExplorerNode, explorer: Explorer) { + super( + `${message} ${GlyphChars.Space}${GlyphChars.Dash}${GlyphChars.Space} this may take a while`, + node, + explorer + ); } -} \ No newline at end of file +} diff --git a/src/views/explorerNodes.ts b/src/views/explorerNodes.ts index 11579cd..ba08c68 100644 --- a/src/views/explorerNodes.ts +++ b/src/views/explorerNodes.ts @@ -26,4 +26,4 @@ export * from './statusFilesResultsNode'; export * from './statusNode'; export * from './statusUpstreamNode'; export * from './tagsNode'; -export * from './tagNode'; \ No newline at end of file +export * from './tagNode'; diff --git a/src/views/fileHistoryNode.ts b/src/views/fileHistoryNode.ts index 6c1325c..5d80803 100644 --- a/src/views/fileHistoryNode.ts +++ b/src/views/fileHistoryNode.ts @@ -4,11 +4,18 @@ import { TreeItem, TreeItemCollapsibleState } from 'vscode'; import { CommitFileNode, CommitFileNodeDisplayAs } from './commitFileNode'; import { Container } from '../container'; import { Explorer, ExplorerNode, MessageNode, ResourceType } from './explorerNode'; -import { GitCommitType, GitLogCommit, GitService, GitUri, Repository, RepositoryChange, RepositoryChangeEvent } from '../gitService'; +import { + GitCommitType, + GitLogCommit, + GitService, + GitUri, + Repository, + RepositoryChange, + RepositoryChangeEvent +} from '../gitService'; import { Logger } from '../logger'; export class FileHistoryNode extends ExplorerNode { - constructor( uri: GitUri, private readonly repo: Repository, @@ -22,7 +29,9 @@ export class FileHistoryNode extends ExplorerNode { const children: ExplorerNode[] = []; - const displayAs = CommitFileNodeDisplayAs.CommitLabel | (this.explorer.config.avatars ? CommitFileNodeDisplayAs.Gravatar : CommitFileNodeDisplayAs.StatusIcon); + const displayAs = + CommitFileNodeDisplayAs.CommitLabel | + (this.explorer.config.avatars ? CommitFileNodeDisplayAs.Gravatar : CommitFileNodeDisplayAs.StatusIcon); const status = await Container.git.getStatusForFile(this.uri.repoPath!, this.uri.fsPath); if (status !== undefined && (status.indexStatus !== undefined || status.workTreeStatus !== undefined)) { @@ -55,13 +64,19 @@ export class FileHistoryNode extends ExplorerNode { status.status, status.originalFileName, previousSha, - status.originalFileName || status.fileName); + status.originalFileName || status.fileName + ); children.push(new CommitFileNode(status, commit, this.explorer, displayAs)); } const log = await Container.git.getLogForFile(this.uri.repoPath, this.uri.fsPath, { ref: this.uri.sha }); if (log !== undefined) { - children.push(...Iterables.map(log.commits.values(), c => new CommitFileNode(c.fileStatuses[0], c, this.explorer, displayAs))); + children.push( + ...Iterables.map( + log.commits.values(), + c => new CommitFileNode(c.fileStatuses[0], c, this.explorer, displayAs) + ) + ); } if (children.length === 0) return [new MessageNode('No file history')]; @@ -94,4 +109,4 @@ export class FileHistoryNode extends ExplorerNode { this.explorer.refreshNode(this); } -} \ No newline at end of file +} diff --git a/src/views/folderNode.ts b/src/views/folderNode.ts index bd9d700..4f3e70a 100644 --- a/src/views/folderNode.ts +++ b/src/views/folderNode.ts @@ -14,7 +14,6 @@ export interface IFileExplorerNode extends ExplorerNode { } export class FolderNode extends ExplorerNode { - readonly priority: boolean = true; constructor( @@ -32,12 +31,18 @@ export class FolderNode extends ExplorerNode { let children: (FolderNode | IFileExplorerNode)[]; - const nesting = FolderNode.getFileNesting(this.explorer.config.files, this.root.descendants, this.relativePath === undefined); + const nesting = FolderNode.getFileNesting( + this.explorer.config.files, + this.root.descendants, + this.relativePath === undefined + ); if (nesting !== ExplorerFilesLayout.List) { children = []; for (const folder of Objects.values(this.root.children)) { if (folder.value === undefined) { - children.push(new FolderNode(this.repoPath, folder.name, folder.relativePath, folder, this.explorer)); + children.push( + new FolderNode(this.repoPath, folder.name, folder.relativePath, folder, this.explorer) + ); continue; } @@ -46,14 +51,16 @@ export class FolderNode extends ExplorerNode { } } else { - this.root.descendants.forEach(n => n.relativePath = this.root.relativePath); + this.root.descendants.forEach(n => (n.relativePath = this.root.relativePath)); children = this.root.descendants; } children.sort((a, b) => { - return ((a instanceof FolderNode) ? -1 : 1) - ((b instanceof FolderNode) ? -1 : 1) || + return ( + (a instanceof FolderNode ? -1 : 1) - (b instanceof FolderNode ? -1 : 1) || (a.priority ? -1 : 1) - (b.priority ? -1 : 1) || - a.label!.localeCompare(b.label!); + a.label!.localeCompare(b.label!) + ); }); return children; @@ -72,7 +79,11 @@ export class FolderNode extends ExplorerNode { return this.folderName; } - static getFileNesting<T extends IFileExplorerNode>(config: IExplorersFilesConfig, children: T[], isRoot: boolean): ExplorerFilesLayout { + static getFileNesting<T extends IFileExplorerNode>( + config: IExplorersFilesConfig, + children: T[], + isRoot: boolean + ): ExplorerFilesLayout { const nesting = config.layout || ExplorerFilesLayout.Auto; if (nesting === ExplorerFilesLayout.Auto) { if (isRoot || config.compact) { @@ -83,4 +94,4 @@ export class FolderNode extends ExplorerNode { } return nesting; } -} \ No newline at end of file +} diff --git a/src/views/gitExplorer.ts b/src/views/gitExplorer.ts index a7edc8a..89edcdb 100644 --- a/src/views/gitExplorer.ts +++ b/src/views/gitExplorer.ts @@ -1,12 +1,40 @@ 'use strict'; import { Functions } from '../system'; -import { commands, ConfigurationChangeEvent, ConfigurationTarget, Disposable, Event, EventEmitter, TextDocumentShowOptions, TextEditor, TreeDataProvider, TreeItem, TreeView, Uri, window } from 'vscode'; +import { + commands, + ConfigurationChangeEvent, + ConfigurationTarget, + Disposable, + Event, + EventEmitter, + TextDocumentShowOptions, + TextEditor, + TreeDataProvider, + TreeItem, + TreeView, + Uri, + window +} from 'vscode'; import { UriComparer } from '../comparers'; -import { configuration, ExplorerFilesLayout, GitExplorerView, IExplorersConfig, IGitExplorerConfig } from '../configuration'; +import { + configuration, + ExplorerFilesLayout, + GitExplorerView, + IExplorersConfig, + IGitExplorerConfig +} from '../configuration'; import { CommandContext, GlyphChars, setCommandContext, WorkspaceState } from '../constants'; import { Container } from '../container'; import { RefreshNodeCommandArgs } from './explorerCommands'; -import { Explorer, ExplorerNode, HistoryNode, MessageNode, RefreshReason, RepositoriesNode, RepositoryNode } from './explorerNodes'; +import { + Explorer, + ExplorerNode, + HistoryNode, + MessageNode, + RefreshReason, + RepositoriesNode, + RepositoryNode +} from './explorerNodes'; import { GitUri } from '../gitService'; import { Logger } from '../logger'; @@ -18,7 +46,6 @@ export interface OpenFileRevisionCommandArgs { } export class GitExplorer extends Disposable implements TreeDataProvider<ExplorerNode> { - private _disposable: Disposable | undefined; private _root?: ExplorerNode; private _tree: TreeView<ExplorerNode> | undefined; @@ -39,16 +66,52 @@ export class GitExplorer extends Disposable implements TreeDataProvider<Explorer Container.explorerCommands; commands.registerCommand('gitlens.gitExplorer.refresh', this.refresh, this); commands.registerCommand('gitlens.gitExplorer.refreshNode', this.refreshNode, this); - commands.registerCommand('gitlens.gitExplorer.setFilesLayoutToAuto', () => this.setFilesLayout(ExplorerFilesLayout.Auto), this); - commands.registerCommand('gitlens.gitExplorer.setFilesLayoutToList', () => this.setFilesLayout(ExplorerFilesLayout.List), this); - commands.registerCommand('gitlens.gitExplorer.setFilesLayoutToTree', () => this.setFilesLayout(ExplorerFilesLayout.Tree), this); + commands.registerCommand( + 'gitlens.gitExplorer.setFilesLayoutToAuto', + () => this.setFilesLayout(ExplorerFilesLayout.Auto), + this + ); + commands.registerCommand( + 'gitlens.gitExplorer.setFilesLayoutToList', + () => this.setFilesLayout(ExplorerFilesLayout.List), + this + ); + commands.registerCommand( + 'gitlens.gitExplorer.setFilesLayoutToTree', + () => this.setFilesLayout(ExplorerFilesLayout.Tree), + this + ); - commands.registerCommand('gitlens.gitExplorer.setAutoRefreshToOn', () => this.setAutoRefresh(Container.config.gitExplorer.autoRefresh, true), this); - commands.registerCommand('gitlens.gitExplorer.setAutoRefreshToOff', () => this.setAutoRefresh(Container.config.gitExplorer.autoRefresh, false), this); - commands.registerCommand('gitlens.gitExplorer.setRenameFollowingOn', () => GitExplorer.setRenameFollowing(true), this); - commands.registerCommand('gitlens.gitExplorer.setRenameFollowingOff', () => GitExplorer.setRenameFollowing(false), this); - commands.registerCommand('gitlens.gitExplorer.switchToHistoryView', () => this.switchTo(GitExplorerView.History), this); - commands.registerCommand('gitlens.gitExplorer.switchToRepositoryView', () => this.switchTo(GitExplorerView.Repository), this); + commands.registerCommand( + 'gitlens.gitExplorer.setAutoRefreshToOn', + () => this.setAutoRefresh(Container.config.gitExplorer.autoRefresh, true), + this + ); + commands.registerCommand( + 'gitlens.gitExplorer.setAutoRefreshToOff', + () => this.setAutoRefresh(Container.config.gitExplorer.autoRefresh, false), + this + ); + commands.registerCommand( + 'gitlens.gitExplorer.setRenameFollowingOn', + () => GitExplorer.setRenameFollowing(true), + this + ); + commands.registerCommand( + 'gitlens.gitExplorer.setRenameFollowingOff', + () => GitExplorer.setRenameFollowing(false), + this + ); + commands.registerCommand( + 'gitlens.gitExplorer.switchToHistoryView', + () => this.switchTo(GitExplorerView.History), + this + ); + commands.registerCommand( + 'gitlens.gitExplorer.switchToRepositoryView', + () => this.switchTo(GitExplorerView.Repository), + this + ); commands.registerCommand('gitlens.gitExplorer.undockHistory', this.undockHistory, this); @@ -67,15 +130,21 @@ export class GitExplorer extends Disposable implements TreeDataProvider<Explorer private async onConfigurationChanged(e: ConfigurationChangeEvent) { const initializing = configuration.initializing(e); - if (!initializing && + if ( + !initializing && !configuration.changed(e, configuration.name('gitExplorer').value) && !configuration.changed(e, configuration.name('explorers').value) && !configuration.changed(e, configuration.name('defaultGravatarsStyle').value) && - !configuration.changed(e, configuration.name('advanced')('fileHistoryFollowsRenames').value)) return; + !configuration.changed(e, configuration.name('advanced')('fileHistoryFollowsRenames').value) + ) { + return; + } - if (initializing || + if ( + initializing || configuration.changed(e, configuration.name('gitExplorer')('enabled').value) || - configuration.changed(e, configuration.name('gitExplorer')('location').value)) { + configuration.changed(e, configuration.name('gitExplorer')('location').value) + ) { setCommandContext(CommandContext.GitExplorer, this.config.enabled ? this.config.location : false); } @@ -97,7 +166,10 @@ export class GitExplorer extends Disposable implements TreeDataProvider<Explorer if (initializing || configuration.changed(e, configuration.name('gitExplorer')('view').value)) { view = this.config.view; if (view === GitExplorerView.Auto) { - view = Container.context.workspaceState.get<GitExplorerView>(WorkspaceState.GitExplorerView, GitExplorerView.Repository); + view = Container.context.workspaceState.get<GitExplorerView>( + WorkspaceState.GitExplorerView, + GitExplorerView.Repository + ); } } @@ -114,7 +186,9 @@ export class GitExplorer extends Disposable implements TreeDataProvider<Explorer this._onDidChangeTreeData = new EventEmitter<ExplorerNode>(); } - this._tree = window.createTreeView(`gitlens.gitExplorer:${this.config.location}`, { treeDataProvider: this }); + this._tree = window.createTreeView(`gitlens.gitExplorer:${this.config.location}`, { + treeDataProvider: this + }); this._disposable = this._tree; return; @@ -154,8 +228,10 @@ export class GitExplorer extends Disposable implements TreeDataProvider<Explorer } get autoRefresh() { - return this.config.autoRefresh && - Container.context.workspaceState.get<boolean>(WorkspaceState.GitExplorerAutoRefresh, true); + return ( + this.config.autoRefresh && + Container.context.workspaceState.get<boolean>(WorkspaceState.GitExplorerAutoRefresh, true) + ); } get config(): IExplorersConfig & IGitExplorerConfig { @@ -183,8 +259,13 @@ export class GitExplorer extends Disposable implements TreeDataProvider<Explorer } if (this._root === undefined) { - if (this.view === GitExplorerView.History) return [new MessageNode(`No active file ${GlyphChars.Dash} no history to show`)]; - return [new MessageNode('No repositories found')]; + return [ + new MessageNode( + this.view === GitExplorerView.History + ? `No active file ${GlyphChars.Dash} no history to show` + : 'No repositories found' + ) + ]; } if (node === undefined) return this._root.getChildren(); @@ -219,7 +300,7 @@ export class GitExplorer extends Disposable implements TreeDataProvider<Explorer } refreshNode(node: ExplorerNode, args?: RefreshNodeCommandArgs) { - Logger.log(`GitExplorer[view=${this.view}].refreshNode(${(node as { id?: string}).id || ''})`); + Logger.log(`GitExplorer[view=${this.view}].refreshNode(${(node as { id?: string }).id || ''})`); if (args !== undefined && node.supportsPaging) { node.maxCount = args.maxCount; @@ -256,7 +337,10 @@ export class GitExplorer extends Disposable implements TreeDataProvider<Explorer let toggled = false; if (enabled) { if (workspaceEnabled === undefined) { - workspaceEnabled = Container.context.workspaceState.get<boolean>(WorkspaceState.GitExplorerAutoRefresh, true); + workspaceEnabled = Container.context.workspaceState.get<boolean>( + WorkspaceState.GitExplorerAutoRefresh, + true + ); } else { toggled = workspaceEnabled; @@ -336,7 +420,7 @@ export class GitExplorer extends Disposable implements TreeDataProvider<Explorer const promise = Container.git.getRepositories(); this._loading = promise.then(_ => Functions.wait(0)); - const repositories = [...await promise]; + const repositories = [...(await promise)]; if (repositories.length === 0) return undefined; const openedRepos = repositories.filter(r => !r.closed); @@ -357,7 +441,11 @@ export class GitExplorer extends Disposable implements TreeDataProvider<Explorer } private async setFilesLayout(layout: ExplorerFilesLayout) { - return configuration.update(configuration.name('gitExplorer')('files')('layout').value, layout, ConfigurationTarget.Global); + return configuration.update( + configuration.name('gitExplorer')('files')('layout').value, + layout, + ConfigurationTarget.Global + ); } private setRoot(root: ExplorerNode | undefined): boolean { @@ -375,9 +463,20 @@ export class GitExplorer extends Disposable implements TreeDataProvider<Explorer Container.historyExplorer.undock(switchView); } - static async getHistoryNode(explorer: Explorer, editor: TextEditor | undefined, root: ExplorerNode | undefined): Promise<ExplorerNode | undefined> { + static async getHistoryNode( + explorer: Explorer, + editor: TextEditor | undefined, + root: ExplorerNode | undefined + ): Promise<ExplorerNode | undefined> { // If we have no active editor, or no visible editors, or no trackable visible editors reset the view - if (editor == null || window.visibleTextEditors.length === 0 || !window.visibleTextEditors.some(e => e.document && Container.git.isTrackable(e.document.uri))) return undefined; + if ( + editor == null || + window.visibleTextEditors.length === 0 || + !window.visibleTextEditors.some(e => e.document && Container.git.isTrackable(e.document.uri)) + ) { + return undefined; + } + // If we do have a visible trackable editor, don't change from the last state (avoids issues when focus switches to the problems/output/debug console panes) if (editor.document === undefined || !Container.git.isTrackable(editor.document.uri)) return root; @@ -394,4 +493,4 @@ export class GitExplorer extends Disposable implements TreeDataProvider<Explorer static setRenameFollowing(enabled: boolean) { configuration.updateEffective(configuration.name('advanced')('fileHistoryFollowsRenames').value, enabled); } -} \ No newline at end of file +} diff --git a/src/views/historyExplorer.ts b/src/views/historyExplorer.ts index 0c46d56..ac3739c 100644 --- a/src/views/historyExplorer.ts +++ b/src/views/historyExplorer.ts @@ -1,6 +1,17 @@ 'use strict'; import { Functions } from '../system'; -import { commands, ConfigurationChangeEvent, Disposable, Event, EventEmitter, TextEditor, TreeDataProvider, TreeItem, TreeView, window } from 'vscode'; +import { + commands, + ConfigurationChangeEvent, + Disposable, + Event, + EventEmitter, + TextEditor, + TreeDataProvider, + TreeItem, + TreeView, + window +} from 'vscode'; import { configuration, GitExplorerView, IExplorersConfig, IHistoryExplorerConfig } from '../configuration'; import { CommandContext, GlyphChars, setCommandContext } from '../constants'; import { Container } from '../container'; @@ -12,7 +23,6 @@ import { Logger } from '../logger'; export * from './explorerNodes'; export class HistoryExplorer extends Disposable implements TreeDataProvider<ExplorerNode> { - private _disposable: Disposable | undefined; private _root?: ExplorerNode; private _tree: TreeView<ExplorerNode> | undefined; @@ -31,8 +41,16 @@ export class HistoryExplorer extends Disposable implements TreeDataProvider<Expl commands.registerCommand('gitlens.historyExplorer.close', () => this.dock(false), this); commands.registerCommand('gitlens.historyExplorer.dock', this.dock, this); - commands.registerCommand('gitlens.historyExplorer.setRenameFollowingOn', () => GitExplorer.setRenameFollowing(true), this); - commands.registerCommand('gitlens.historyExplorer.setRenameFollowingOff', () => GitExplorer.setRenameFollowing(false), this); + commands.registerCommand( + 'gitlens.historyExplorer.setRenameFollowingOn', + () => GitExplorer.setRenameFollowing(true), + this + ); + commands.registerCommand( + 'gitlens.historyExplorer.setRenameFollowingOff', + () => GitExplorer.setRenameFollowing(false), + this + ); Container.context.subscriptions.push( window.onDidChangeActiveTextEditor(Functions.debounce(this.onActiveEditorChanged, 500), this), @@ -49,15 +67,21 @@ export class HistoryExplorer extends Disposable implements TreeDataProvider<Expl private async onConfigurationChanged(e: ConfigurationChangeEvent) { const initializing = configuration.initializing(e); - if (!initializing && + if ( + !initializing && !configuration.changed(e, configuration.name('historyExplorer').value) && !configuration.changed(e, configuration.name('explorers').value) && !configuration.changed(e, configuration.name('defaultGravatarsStyle').value) && - !configuration.changed(e, configuration.name('advanced')('fileHistoryFollowsRenames').value)) return; + !configuration.changed(e, configuration.name('advanced')('fileHistoryFollowsRenames').value) + ) { + return; + } - if (initializing || + if ( + initializing || configuration.changed(e, configuration.name('historyExplorer')('enabled').value) || - configuration.changed(e, configuration.name('historyExplorer')('location').value)) { + configuration.changed(e, configuration.name('historyExplorer')('location').value) + ) { setCommandContext(CommandContext.HistoryExplorer, this.config.enabled ? this.config.location : false); } @@ -80,7 +104,9 @@ export class HistoryExplorer extends Disposable implements TreeDataProvider<Expl this._onDidChangeTreeData = new EventEmitter<ExplorerNode>(); } - this._tree = window.createTreeView(`gitlens.historyExplorer:${this.config.location}`, { treeDataProvider: this }); + this._tree = window.createTreeView(`gitlens.historyExplorer:${this.config.location}`, { + treeDataProvider: this + }); this._disposable = this._tree; } @@ -157,7 +183,7 @@ export class HistoryExplorer extends Disposable implements TreeDataProvider<Expl } refreshNode(node: ExplorerNode, args?: RefreshNodeCommandArgs) { - Logger.log(`HistoryExplorer.refreshNode(${(node as { id?: string}).id || ''})`); + Logger.log(`HistoryExplorer.refreshNode(${(node as { id?: string }).id || ''})`); if (args !== undefined && node.supportsPaging) { node.maxCount = args.maxCount; @@ -211,4 +237,4 @@ export class HistoryExplorer extends Disposable implements TreeDataProvider<Expl this._root = root; return true; } -} \ No newline at end of file +} diff --git a/src/views/historyNode.ts b/src/views/historyNode.ts index b351973..110a916 100644 --- a/src/views/historyNode.ts +++ b/src/views/historyNode.ts @@ -6,7 +6,6 @@ import { FileHistoryNode } from './fileHistoryNode'; import { GitUri, Repository } from '../gitService'; export class HistoryNode extends ExplorerNode { - constructor( uri: GitUri, private readonly repo: Repository, @@ -18,9 +17,7 @@ export class HistoryNode extends ExplorerNode { async getChildren(): Promise<ExplorerNode[]> { this.resetChildren(); - this.children = [ - new FileHistoryNode(this.uri, this.repo, this.explorer) - ]; + this.children = [new FileHistoryNode(this.uri, this.repo, this.explorer)]; return this.children; } @@ -35,4 +32,4 @@ export class HistoryNode extends ExplorerNode { return item; } -} \ No newline at end of file +} diff --git a/src/views/remoteNode.ts b/src/views/remoteNode.ts index 0cb0ed8..18b5dcd 100644 --- a/src/views/remoteNode.ts +++ b/src/views/remoteNode.ts @@ -11,76 +11,86 @@ import { GitRemote, GitRemoteType, GitUri, Repository } from '../gitService'; import { Container } from '../container'; export class RemoteNode extends ExplorerNode { + constructor( + public readonly remote: GitRemote, + uri: GitUri, + private readonly repo: Repository, + private readonly explorer: GitExplorer + ) { + super(uri); + } - constructor( - public readonly remote: GitRemote, - uri: GitUri, - private readonly repo: Repository, - private readonly explorer: GitExplorer - ) { - super(uri); - } - - async getChildren(): Promise<ExplorerNode[]> { - const branches = await this.repo.getBranches(); - if (branches === undefined) return []; - - branches.sort((a, b) => a.name.localeCompare(b.name)); + async getChildren(): Promise<ExplorerNode[]> { + const branches = await this.repo.getBranches(); + if (branches === undefined) return []; - // filter remote branches - const branchNodes = [...Iterables.filterMap(branches, b => !b.remote || !b.name.startsWith(this.remote.name) ? undefined : new BranchNode(b, this.uri, this.explorer))]; - if (this.explorer.config.branches.layout === ExplorerBranchesLayout.List) return branchNodes; + branches.sort((a, b) => a.name.localeCompare(b.name)); - const hierarchy = Arrays.makeHierarchical( - branchNodes, - n => n.branch.isValid() ? n.branch.getName().split('/') : [n.branch.name], - (...paths: string[]) => paths.join('/'), - this.explorer.config.files.compact - ); + // filter remote branches + const branchNodes = [ + ...Iterables.filterMap( + branches, + b => + !b.remote || !b.name.startsWith(this.remote.name) + ? undefined + : new BranchNode(b, this.uri, this.explorer) + ) + ]; + if (this.explorer.config.branches.layout === ExplorerBranchesLayout.List) return branchNodes; - const root = new BranchOrTagFolderNode(this.repo.path, '', undefined, hierarchy, this.explorer); - const children = await root.getChildren() as (BranchOrTagFolderNode | BranchNode)[]; + const hierarchy = Arrays.makeHierarchical( + branchNodes, + n => (n.branch.isValid() ? n.branch.getName().split('/') : [n.branch.name]), + (...paths: string[]) => paths.join('/'), + this.explorer.config.files.compact + ); - return children; - } + const root = new BranchOrTagFolderNode(this.repo.path, '', undefined, hierarchy, this.explorer); + const children = (await root.getChildren()) as (BranchOrTagFolderNode | BranchNode)[]; - getTreeItem(): TreeItem { - const fetch = this.remote.types.find(rt => rt.type === GitRemoteType.Fetch); - const push = this.remote.types.find(rt => rt.type === GitRemoteType.Push); + return children; + } - let separator; - if (fetch && push) { - separator = GlyphChars.ArrowLeftRightLong; - } - else if (fetch) { - separator = GlyphChars.ArrowLeft; - } - else if (push) { - separator = GlyphChars.ArrowRight; - } - else { - separator = GlyphChars.Dash; - } + getTreeItem(): TreeItem { + const fetch = this.remote.types.find(rt => rt.type === GitRemoteType.Fetch); + const push = this.remote.types.find(rt => rt.type === GitRemoteType.Push); - const label = `${this.remote.name} ${GlyphChars.Space}${separator}${GlyphChars.Space} ${(this.remote.provider !== undefined) ? this.remote.provider.name : this.remote.domain} ${GlyphChars.Space}${GlyphChars.Dot}${GlyphChars.Space} ${this.remote.path}`; + let separator; + if (fetch && push) { + separator = GlyphChars.ArrowLeftRightLong; + } + else if (fetch) { + separator = GlyphChars.ArrowLeft; + } + else if (push) { + separator = GlyphChars.ArrowRight; + } + else { + separator = GlyphChars.Dash; + } - const item = new TreeItem(label, TreeItemCollapsibleState.Collapsed); - item.contextValue = ResourceType.Remote; - item.tooltip = `${this.remote.name}\n${this.remote.path} (${(this.remote.provider !== undefined) ? this.remote.provider.name : this.remote.domain})`; + const label = `${this.remote.name} ${GlyphChars.Space}${separator}${GlyphChars.Space} ${ + this.remote.provider !== undefined ? this.remote.provider.name : this.remote.domain + } ${GlyphChars.Space}${GlyphChars.Dot}${GlyphChars.Space} ${this.remote.path}`; - if (this.remote.provider !== undefined) { - item.iconPath = { - dark: Container.context.asAbsolutePath(`images/dark/icon-${this.remote.provider.icon}.svg`), - light: Container.context.asAbsolutePath(`images/light/icon-${this.remote.provider.icon}.svg`) - }; - } - else { - item.iconPath = { - dark: Container.context.asAbsolutePath('images/dark/icon-remote.svg'), - light: Container.context.asAbsolutePath('images/light/icon-remote.svg') - }; - } + const item = new TreeItem(label, TreeItemCollapsibleState.Collapsed); + item.contextValue = ResourceType.Remote; + item.tooltip = `${this.remote.name} +${this.remote.path} (${this.remote.provider !== undefined ? this.remote.provider.name : this.remote.domain})`; - return item; + if (this.remote.provider !== undefined) { + item.iconPath = { + dark: Container.context.asAbsolutePath(`images/dark/icon-${this.remote.provider.icon}.svg`), + light: Container.context.asAbsolutePath(`images/light/icon-${this.remote.provider.icon}.svg`) + }; + } + else { + item.iconPath = { + dark: Container.context.asAbsolutePath('images/dark/icon-remote.svg'), + light: Container.context.asAbsolutePath('images/light/icon-remote.svg') + }; } + + return item; } +} diff --git a/src/views/remotesNode.ts b/src/views/remotesNode.ts index 53e7129..bbb1566 100644 --- a/src/views/remotesNode.ts +++ b/src/views/remotesNode.ts @@ -8,37 +8,36 @@ import { GitUri, Repository } from '../gitService'; import { RemoteNode } from './remoteNode'; export class RemotesNode extends ExplorerNode { + constructor( + uri: GitUri, + private readonly repo: Repository, + private readonly explorer: GitExplorer, + private readonly active: boolean = false + ) { + super(uri); + } - constructor( - uri: GitUri, - private readonly repo: Repository, - private readonly explorer: GitExplorer, - private readonly active: boolean = false - ) { - super(uri); - } - - get id(): string { - return `gitlens:repository(${this.repo.path})${this.active ? ':active' : ''}:remotes`; - } + get id(): string { + return `gitlens:repository(${this.repo.path})${this.active ? ':active' : ''}:remotes`; + } - async getChildren(): Promise<ExplorerNode[]> { - const remotes = await this.repo.getRemotes(); - if (remotes === undefined || remotes.length === 0) return [new MessageNode('No remotes configured')]; + async getChildren(): Promise<ExplorerNode[]> { + const remotes = await this.repo.getRemotes(); + if (remotes === undefined || remotes.length === 0) return [new MessageNode('No remotes configured')]; - remotes.sort((a, b) => a.name.localeCompare(b.name)); - return [...Iterables.map(remotes, r => new RemoteNode(r, this.uri, this.repo, this.explorer))]; - } + remotes.sort((a, b) => a.name.localeCompare(b.name)); + return [...Iterables.map(remotes, r => new RemoteNode(r, this.uri, this.repo, this.explorer))]; + } - getTreeItem(): TreeItem { - const item = new TreeItem(`Remotes`, TreeItemCollapsibleState.Collapsed); - item.contextValue = ResourceType.Remotes; + getTreeItem(): TreeItem { + const item = new TreeItem(`Remotes`, TreeItemCollapsibleState.Collapsed); + item.contextValue = ResourceType.Remotes; - item.iconPath = { - dark: Container.context.asAbsolutePath('images/dark/icon-remote.svg'), - light: Container.context.asAbsolutePath('images/light/icon-remote.svg') - }; + item.iconPath = { + dark: Container.context.asAbsolutePath('images/dark/icon-remote.svg'), + light: Container.context.asAbsolutePath('images/light/icon-remote.svg') + }; - return item; - } + return item; } +} diff --git a/src/views/repositoriesNode.ts b/src/views/repositoriesNode.ts index 2a81a10..9649c2c 100644 --- a/src/views/repositoriesNode.ts +++ b/src/views/repositoriesNode.ts @@ -7,7 +7,6 @@ import { GitUri, Repository } from '../gitService'; import { RepositoryNode } from './repositoryNode'; export class RepositoriesNode extends ExplorerNode { - constructor( private readonly repositories: Repository[], private readonly explorer: GitExplorer @@ -39,4 +38,4 @@ export class RepositoriesNode extends ExplorerNode { item.contextValue = ResourceType.Repositories; return item; } -} \ No newline at end of file +} diff --git a/src/views/repositoryNode.ts b/src/views/repositoryNode.ts index 975093a..a5863ac 100644 --- a/src/views/repositoryNode.ts +++ b/src/views/repositoryNode.ts @@ -13,7 +13,6 @@ import { StashesNode } from './stashesNode'; import { TagsNode } from './tagsNode'; export class RepositoryNode extends ExplorerNode { - constructor( uri: GitUri, public readonly repo: Repository, @@ -50,7 +49,10 @@ export class RepositoryNode extends ExplorerNode { ? `Active Repository ${Strings.pad(GlyphChars.Dash, 1, 1)} ${this.repo.formattedName || this.uri.repoPath}` : `${this.repo.formattedName || this.uri.repoPath}`; - const item = new TreeItem(label, this.active ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.Collapsed); + const item = new TreeItem( + label, + this.active ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.Collapsed + ); item.id = this.id; item.contextValue = ResourceType.Repository; return item; @@ -64,10 +66,12 @@ export class RepositoryNode extends ExplorerNode { private updateSubscription() { // We only need to subscribe if auto-refresh is enabled, because if it becomes enabled we will be refreshed if (this.explorer.autoRefresh) { - this.disposable = this.disposable || Disposable.from( - this.explorer.onDidChangeAutoRefresh(this.onAutoRefreshChanged, this), - this.repo.onDidChange(this.onRepoChanged, this) - ); + this.disposable = + this.disposable || + Disposable.from( + this.explorer.onDidChangeAutoRefresh(this.onAutoRefreshChanged, this), + this.repo.onDidChange(this.onRepoChanged, this) + ); } else if (this.disposable !== undefined) { this.disposable.dispose(); @@ -82,7 +86,11 @@ export class RepositoryNode extends ExplorerNode { private onRepoChanged(e: RepositoryChangeEvent) { Logger.log(`RepositoryNode.onRepoChanged(${e.changes.join()}); triggering node refresh`); - if (this.children === undefined || e.changed(RepositoryChange.Repository) || e.changed(RepositoryChange.Config)) { + if ( + this.children === undefined || + e.changed(RepositoryChange.Repository) || + e.changed(RepositoryChange.Config) + ) { this.explorer.refreshNode(this.active && this.activeParent !== undefined ? this.activeParent : this); return; @@ -109,4 +117,4 @@ export class RepositoryNode extends ExplorerNode { } } } -} \ No newline at end of file +} diff --git a/src/views/resultsExplorer.ts b/src/views/resultsExplorer.ts index 8652119..dabe788 100644 --- a/src/views/resultsExplorer.ts +++ b/src/views/resultsExplorer.ts @@ -1,11 +1,31 @@ 'use strict'; import { Functions, Strings } from '../system'; -import { commands, ConfigurationChangeEvent, ConfigurationTarget, Disposable, Event, EventEmitter, TreeDataProvider, TreeItem, TreeView, window } from 'vscode'; +import { + commands, + ConfigurationChangeEvent, + ConfigurationTarget, + Disposable, + Event, + EventEmitter, + TreeDataProvider, + TreeItem, + TreeView, + window +} from 'vscode'; import { configuration, ExplorerFilesLayout, IExplorersConfig, IResultsExplorerConfig } from '../configuration'; import { CommandContext, GlyphChars, setCommandContext, WorkspaceState } from '../constants'; import { Container } from '../container'; import { RefreshNodeCommandArgs } from './explorerCommands'; -import { CommitResultsNode, CommitsResultsNode, ComparisonResultsNode, ExplorerNode, MessageNode, NamedRef, RefreshReason, ResourceType } from './explorerNodes'; +import { + CommitResultsNode, + CommitsResultsNode, + ComparisonResultsNode, + ExplorerNode, + MessageNode, + NamedRef, + RefreshReason, + ResourceType +} from './explorerNodes'; import { GitLog, GitLogCommit } from '../gitService'; import { Logger } from '../logger'; // import { Messages } from '../messages'; @@ -13,7 +33,6 @@ import { Logger } from '../logger'; export * from './explorerNodes'; export class ResultsExplorer extends Disposable implements TreeDataProvider<ExplorerNode> { - private _disposable: Disposable | undefined; private _roots: ExplorerNode[] = []; private _tree: TreeView<ExplorerNode> | undefined; @@ -29,9 +48,21 @@ export class ResultsExplorer extends Disposable implements TreeDataProvider<Expl Container.explorerCommands; commands.registerCommand('gitlens.resultsExplorer.refresh', this.refreshNodes, this); commands.registerCommand('gitlens.resultsExplorer.refreshNode', this.refreshNode, this); - commands.registerCommand('gitlens.resultsExplorer.setFilesLayoutToAuto', () => this.setFilesLayout(ExplorerFilesLayout.Auto), this); - commands.registerCommand('gitlens.resultsExplorer.setFilesLayoutToList', () => this.setFilesLayout(ExplorerFilesLayout.List), this); - commands.registerCommand('gitlens.resultsExplorer.setFilesLayoutToTree', () => this.setFilesLayout(ExplorerFilesLayout.Tree), this); + commands.registerCommand( + 'gitlens.resultsExplorer.setFilesLayoutToAuto', + () => this.setFilesLayout(ExplorerFilesLayout.Auto), + this + ); + commands.registerCommand( + 'gitlens.resultsExplorer.setFilesLayoutToList', + () => this.setFilesLayout(ExplorerFilesLayout.List), + this + ); + commands.registerCommand( + 'gitlens.resultsExplorer.setFilesLayoutToTree', + () => this.setFilesLayout(ExplorerFilesLayout.Tree), + this + ); commands.registerCommand('gitlens.resultsExplorer.clearResultsNode', this.clearResultsNode, this); commands.registerCommand('gitlens.resultsExplorer.close', this.close, this); @@ -41,9 +72,7 @@ export class ResultsExplorer extends Disposable implements TreeDataProvider<Expl setCommandContext(CommandContext.ResultsExplorerKeepResults, this.keepResults); - Container.context.subscriptions.push( - configuration.onDidChange(this.onConfigurationChanged, this) - ); + Container.context.subscriptions.push(configuration.onDidChange(this.onConfigurationChanged, this)); this.onConfigurationChanged(configuration.initializingChangeEvent); } @@ -54,10 +83,14 @@ export class ResultsExplorer extends Disposable implements TreeDataProvider<Expl private async onConfigurationChanged(e: ConfigurationChangeEvent) { const initializing = configuration.initializing(e); - if (!initializing && + if ( + !initializing && !configuration.changed(e, configuration.name('resultsExplorer').value) && !configuration.changed(e, configuration.name('explorers').value) && - !configuration.changed(e, configuration.name('defaultGravatarsStyle').value)) return; + !configuration.changed(e, configuration.name('defaultGravatarsStyle').value) + ) { + return; + } if (initializing || configuration.changed(e, configuration.name('resultsExplorer')('location').value)) { setCommandContext(CommandContext.ResultsExplorer, this.enabled ? this.config.location : false); @@ -69,7 +102,9 @@ export class ResultsExplorer extends Disposable implements TreeDataProvider<Expl this._onDidChangeTreeData = new EventEmitter<ExplorerNode>(); } - this._tree = window.createTreeView(`gitlens.resultsExplorer:${this.config.location}`, { treeDataProvider: this }); + this._tree = window.createTreeView(`gitlens.resultsExplorer:${this.config.location}`, { + treeDataProvider: this + }); this._disposable = this._tree; } @@ -128,7 +163,7 @@ export class ResultsExplorer extends Disposable implements TreeDataProvider<Expl } refreshNode(node: ExplorerNode, args?: RefreshNodeCommandArgs) { - Logger.log(`ResultsExplorer.refreshNode(${(node as { id?: string}).id || ''})`); + Logger.log(`ResultsExplorer.refreshNode(${(node as { id?: string }).id || ''})`); if (args !== undefined && node.supportsPaging) { node.maxCount = args.maxCount; @@ -159,17 +194,33 @@ export class ResultsExplorer extends Disposable implements TreeDataProvider<Expl } showComparisonInResults(repoPath: string, ref1: string | NamedRef, ref2: string | NamedRef) { - this.showResults(this.addResults(new ComparisonResultsNode(repoPath, typeof ref1 === 'string' ? { ref: ref1 } : ref1, typeof ref2 === 'string' ? { ref: ref2 } : ref2, this))); + this.showResults( + this.addResults( + new ComparisonResultsNode( + repoPath, + typeof ref1 === 'string' ? { ref: ref1 } : ref1, + typeof ref2 === 'string' ? { ref: ref2 } : ref2, + this + ) + ) + ); } showCommitInResults(commit: GitLogCommit) { this.showResults(this.addResults(new CommitResultsNode(commit, this))); } - showCommitsInResults(results: GitLog, resultsLabel: string | { label: string, resultsType?: { singular: string, plural: string } }) { - const query = results.query === undefined - ? (maxCount: number | undefined) => Promise.resolve(results) - : results.query; + showCommitsInResults( + results: GitLog, + resultsLabel: + | string + | { + label: string; + resultsType?: { singular: string; plural: string }; + } + ) { + const query = + results.query === undefined ? (maxCount: number | undefined) => Promise.resolve(results) : results.query; const labelFn = async (log: GitLog | undefined) => { if (typeof resultsLabel === 'string') return resultsLabel; @@ -177,21 +228,35 @@ export class ResultsExplorer extends Disposable implements TreeDataProvider<Expl const count = log !== undefined ? log.count : 0; const truncated = log !== undefined ? log.truncated : false; - const resultsType = resultsLabel.resultsType === undefined - ? { singular: 'result', plural: 'results' } - : resultsLabel.resultsType; + const resultsType = + resultsLabel.resultsType === undefined + ? { singular: 'result', plural: 'results' } + : resultsLabel.resultsType; let repository = ''; - if (await Container.git.getRepositoryCount() > 1) { + if ((await Container.git.getRepositoryCount()) > 1) { const repo = await Container.git.getRepository(results.repoPath); - repository = ` ${Strings.pad(GlyphChars.Dash, 1, 1)} ${(repo && repo.formattedName) || results.repoPath}`; + repository = ` ${Strings.pad(GlyphChars.Dash, 1, 1)} ${(repo && repo.formattedName) || + results.repoPath}`; } if (count === 1) return `1 ${resultsType.singular} for ${resultsLabel.label}${repository}`; - return `${count === 0 ? 'No' : `${count}${truncated ? '+' : ''}`} ${resultsType.plural} for ${resultsLabel.label}${repository}`; + return `${count === 0 ? 'No' : `${count}${truncated ? '+' : ''}`} ${resultsType.plural} for ${ + resultsLabel.label + }${repository}`; }; - this.showResults(this.addResults(new CommitsResultsNode(results.repoPath, labelFn, Functions.seeded(query, results), this, ResourceType.SearchResults))); + this.showResults( + this.addResults( + new CommitsResultsNode( + results.repoPath, + labelFn, + Functions.seeded(query, results), + this, + ResourceType.SearchResults + ) + ) + ); } private async showResults(results: ExplorerNode) { @@ -234,7 +299,11 @@ export class ResultsExplorer extends Disposable implements TreeDataProvider<Expl } private async setFilesLayout(layout: ExplorerFilesLayout) { - return configuration.update(configuration.name('resultsExplorer')('files')('layout').value, layout, ConfigurationTarget.Global); + return configuration.update( + configuration.name('resultsExplorer')('files')('layout').value, + layout, + ConfigurationTarget.Global + ); } private setKeepResults(enabled: boolean) { @@ -247,4 +316,4 @@ export class ResultsExplorer extends Disposable implements TreeDataProvider<Expl this.showComparisonInResults(node.repoPath, node.ref2, node.ref1); } -} \ No newline at end of file +} diff --git a/src/views/stashFileNode.ts b/src/views/stashFileNode.ts index c8dae32..fffb105 100644 --- a/src/views/stashFileNode.ts +++ b/src/views/stashFileNode.ts @@ -4,12 +4,7 @@ import { Explorer, ResourceType } from './explorerNode'; import { GitLogCommit, IGitStatusFile } from '../gitService'; export class StashFileNode extends CommitFileNode { - - constructor( - status: IGitStatusFile, - commit: GitLogCommit, - explorer: Explorer - ) { + constructor(status: IGitStatusFile, commit: GitLogCommit, explorer: Explorer) { super(status, commit, explorer, CommitFileNodeDisplayAs.File); } @@ -24,4 +19,4 @@ export class StashFileNode extends CommitFileNode { protected getCommitFileTemplate() { return this.explorer.config.stashFileFormat; } -} \ No newline at end of file +} diff --git a/src/views/stashNode.ts b/src/views/stashNode.ts index 79f930d..088bf7b 100644 --- a/src/views/stashNode.ts +++ b/src/views/stashNode.ts @@ -7,7 +7,6 @@ import { CommitFormatter, GitStashCommit, ICommitFormatOptions } from '../gitSer import { StashFileNode } from './stashFileNode'; export class StashNode extends ExplorerRefNode { - constructor( public readonly commit: GitStashCommit, private readonly explorer: Explorer @@ -23,12 +22,15 @@ export class StashNode extends ExplorerRefNode { const statuses = (this.commit as GitStashCommit).fileStatuses; // Check for any untracked files -- since git doesn't return them via `git stash list` :( - const log = await Container.git.getLog(this.commit.repoPath, { maxCount: 1, ref: `${(this.commit as GitStashCommit).stashName}^3` }); + const log = await Container.git.getLog(this.commit.repoPath, { + maxCount: 1, + ref: `${(this.commit as GitStashCommit).stashName}^3` + }); if (log !== undefined) { const commit = Iterables.first(log.commits.values()); if (commit !== undefined && commit.fileStatuses.length !== 0) { // Since these files are untracked -- make them look that way - commit.fileStatuses.forEach(s => s.status = '?'); + commit.fileStatuses.forEach(s => (s.status = '?')); statuses.splice(statuses.length, 0, ...commit.fileStatuses); } } @@ -39,19 +41,18 @@ export class StashNode extends ExplorerRefNode { } getTreeItem(): TreeItem { - const item = new TreeItem(CommitFormatter.fromTemplate(this.explorer.config.stashFormat, this.commit, { - truncateMessageAtNewLine: true, - dateFormat: Container.config.defaultDateFormat - } as ICommitFormatOptions), TreeItemCollapsibleState.Collapsed); - item.contextValue = ResourceType.Stash; - item.tooltip = CommitFormatter.fromTemplate( - '${ago} (${date})\n\n${message}', - this.commit, - { + const item = new TreeItem( + CommitFormatter.fromTemplate(this.explorer.config.stashFormat, this.commit, { + truncateMessageAtNewLine: true, dateFormat: Container.config.defaultDateFormat - } as ICommitFormatOptions + } as ICommitFormatOptions), + TreeItemCollapsibleState.Collapsed ); + item.contextValue = ResourceType.Stash; + item.tooltip = CommitFormatter.fromTemplate('${ago} (${date})\n\n${message}', this.commit, { + dateFormat: Container.config.defaultDateFormat + } as ICommitFormatOptions); return item; } -} \ No newline at end of file +} diff --git a/src/views/stashesNode.ts b/src/views/stashesNode.ts index 3117114..d057d59 100644 --- a/src/views/stashesNode.ts +++ b/src/views/stashesNode.ts @@ -7,7 +7,6 @@ import { GitUri, Repository } from '../gitService'; import { StashNode } from './stashNode'; export class StashesNode extends ExplorerNode { - constructor( uri: GitUri, private readonly repo: Repository, @@ -39,4 +38,4 @@ export class StashesNode extends ExplorerNode { return item; } -} \ No newline at end of file +} diff --git a/src/views/statusFileCommitsNode.ts b/src/views/statusFileCommitsNode.ts index 7fb3549..c5882bd 100644 --- a/src/views/statusFileCommitsNode.ts +++ b/src/views/statusFileCommitsNode.ts @@ -4,11 +4,18 @@ import { Commands, DiffWithPreviousCommandArgs } from '../commands'; import { CommitFileNode, CommitFileNodeDisplayAs } from './commitFileNode'; import { Container } from '../container'; import { Explorer, ExplorerNode, ResourceType } from './explorerNode'; -import { getGitStatusIcon, GitLogCommit, GitUri, IGitStatusFile, IGitStatusFileWithCommit, IStatusFormatOptions, StatusFileFormatter } from '../gitService'; +import { + getGitStatusIcon, + GitLogCommit, + GitUri, + IGitStatusFile, + IGitStatusFileWithCommit, + IStatusFormatOptions, + StatusFileFormatter +} from '../gitService'; import * as path from 'path'; export class StatusFileCommitsNode extends ExplorerNode { - constructor( public readonly repoPath: string, public readonly status: IGitStatusFile, @@ -19,7 +26,18 @@ export class StatusFileCommitsNode extends ExplorerNode { } async getChildren(): Promise<ExplorerNode[]> { - return this.commits.map(c => new CommitFileNode(this.status, c, this.explorer, CommitFileNodeDisplayAs.CommitLabel | (this.explorer.config.avatars ? CommitFileNodeDisplayAs.Gravatar : CommitFileNodeDisplayAs.CommitIcon))); + return this.commits.map( + c => + new CommitFileNode( + this.status, + c, + this.explorer, + CommitFileNodeDisplayAs.CommitLabel | + (this.explorer.config.avatars + ? CommitFileNodeDisplayAs.Gravatar + : CommitFileNodeDisplayAs.CommitIcon) + ) + ); } async getTreeItem(): Promise<TreeItem> { @@ -30,16 +48,25 @@ export class StatusFileCommitsNode extends ExplorerNode { item.contextValue = ResourceType.StatusFile; if (this.commit.isStagedUncommitted) { - item.tooltip = StatusFileFormatter.fromTemplate('${status} in index\n\n${file}\n${directory}/', this.status); + item.tooltip = StatusFileFormatter.fromTemplate( + '${status} in index\n\n${file}\n${directory}/', + this.status + ); } else { - item.tooltip = StatusFileFormatter.fromTemplate('${status} in working tree\n\n${file}\n${directory}/', this.status); + item.tooltip = StatusFileFormatter.fromTemplate( + '${status} in working tree\n\n${file}\n${directory}/', + this.status + ); } item.command = this.getCommand(); } else { item.contextValue = ResourceType.StatusFileCommits; - item.tooltip = StatusFileFormatter.fromTemplate(`\${status} in ${this.getChangedIn()}\n\n\${file}\n\${directory}/`, this.status); + item.tooltip = StatusFileFormatter.fromTemplate( + `\${status} in ${this.getChangedIn()}\n\n\${file}\n\${directory}/`, + this.status + ); } const icon = getGitStatusIcon(this.status.status); @@ -144,4 +171,4 @@ export class StatusFileCommitsNode extends ExplorerNode { ] }; } -} \ No newline at end of file +} diff --git a/src/views/statusFileNode.ts b/src/views/statusFileNode.ts index b388886..ae339bc 100644 --- a/src/views/statusFileNode.ts +++ b/src/views/statusFileNode.ts @@ -7,7 +7,6 @@ import { getGitStatusIcon, GitStatusFile, GitUri, IStatusFormatOptions, StatusFi import * as path from 'path'; export class StatusFileNode extends ExplorerNode { - constructor( public readonly repoPath: string, private readonly status: GitStatusFile, @@ -15,13 +14,7 @@ export class StatusFileNode extends ExplorerNode { private readonly ref2: string, private readonly explorer: Explorer ) { - super(GitUri.fromFileStatus( - status, - repoPath, - ref1 - ? ref1 - : ref2 ? ref2 : undefined - )); + super(GitUri.fromFileStatus(status, repoPath, ref1 ? ref1 : ref2 ? ref2 : undefined)); } getChildren(): ExplorerNode[] { @@ -87,9 +80,10 @@ export class StatusFileNode extends ExplorerNode { }, rhs: { sha: this.ref2, - uri: this.status.status === 'R' - ? GitUri.fromFileStatus(this.status, this.uri.repoPath!, this.ref2, true) - : this.uri + uri: + this.status.status === 'R' + ? GitUri.fromFileStatus(this.status, this.uri.repoPath!, this.ref2, true) + : this.uri }, repoPath: this.uri.repoPath!, diff --git a/src/views/statusFilesNode.ts b/src/views/statusFilesNode.ts index 3d49bd0..8db4c17 100644 --- a/src/views/statusFilesNode.ts +++ b/src/views/statusFilesNode.ts @@ -6,12 +6,19 @@ import { Container } from '../container'; import { ExplorerNode, ResourceType, ShowAllNode } from './explorerNode'; import { FolderNode, IFileExplorerNode } from './folderNode'; import { GitExplorer } from './gitExplorer'; -import { GitCommitType, GitLog, GitLogCommit, GitService, GitStatus, GitUri, IGitStatusFileWithCommit } from '../gitService'; +import { + GitCommitType, + GitLog, + GitLogCommit, + GitService, + GitStatus, + GitUri, + IGitStatusFileWithCommit +} from '../gitService'; import { StatusFileCommitsNode } from './statusFileCommitsNode'; import * as path from 'path'; export class StatusFilesNode extends ExplorerNode { - readonly repoPath: string; readonly supportsPaging: boolean = true; @@ -38,53 +45,115 @@ export class StatusFilesNode extends ExplorerNode { if (this.range !== undefined) { log = await Container.git.getLog(repoPath, { maxCount: this.maxCount, ref: this.range }); if (log !== undefined) { - statuses = Array.from(Iterables.flatMap(log.commits.values(), c => { - return c.fileStatuses.map(s => { - return { ...s, commit: c } as IGitStatusFileWithCommit; - }); - })); + statuses = Array.from( + Iterables.flatMap(log.commits.values(), c => { + return c.fileStatuses.map(s => { + return { ...s, commit: c } as IGitStatusFileWithCommit; + }); + }) + ); } } if (this.status.files.length !== 0 && this.includeWorkingTree) { - statuses.splice(0, 0, ...Iterables.flatMap(this.status.files, s => { - if (s.workTreeStatus !== undefined && s.indexStatus !== undefined) { - // Decrements the date to guarantee this entry will be sorted after the previous entry (most recent first) - const older = new Date(); - older.setMilliseconds(older.getMilliseconds() - 1); - - return [ - { - ...s, - status: s.status, - commit: new GitLogCommit(GitCommitType.File, repoPath, GitService.uncommittedSha, 'You', undefined, new Date(), '', s.fileName, [s], s.status, s.originalFileName, GitService.stagedUncommittedSha, s.fileName) - } as IGitStatusFileWithCommit, - { - ...s, - status: s.status, - commit: new GitLogCommit(GitCommitType.File, repoPath, GitService.stagedUncommittedSha, 'You', undefined, older, '', s.fileName, [s], s.status, s.originalFileName, 'HEAD', s.fileName) - } as IGitStatusFileWithCommit - ]; - } - else if (s.indexStatus !== undefined) { - return [ - { - ...s, - status: s.status, - commit: new GitLogCommit(GitCommitType.File, repoPath, GitService.stagedUncommittedSha, 'You', undefined, new Date(), '', s.fileName, [s], s.status, s.originalFileName, 'HEAD', s.fileName) - } as IGitStatusFileWithCommit - ]; - } - else { - return [ - { - ...s, - status: s.status, - commit: new GitLogCommit(GitCommitType.File, repoPath, GitService.uncommittedSha, 'You', undefined, new Date(), '', s.fileName, [s], s.status, s.originalFileName, 'HEAD', s.fileName) - } as IGitStatusFileWithCommit - ]; - } - })); + statuses.splice( + 0, + 0, + ...Iterables.flatMap(this.status.files, s => { + if (s.workTreeStatus !== undefined && s.indexStatus !== undefined) { + // Decrements the date to guarantee this entry will be sorted after the previous entry (most recent first) + const older = new Date(); + older.setMilliseconds(older.getMilliseconds() - 1); + + return [ + { + ...s, + status: s.status, + commit: new GitLogCommit( + GitCommitType.File, + repoPath, + GitService.uncommittedSha, + 'You', + undefined, + new Date(), + '', + s.fileName, + [s], + s.status, + s.originalFileName, + GitService.stagedUncommittedSha, + s.fileName + ) + } as IGitStatusFileWithCommit, + { + ...s, + status: s.status, + commit: new GitLogCommit( + GitCommitType.File, + repoPath, + GitService.stagedUncommittedSha, + 'You', + undefined, + older, + '', + s.fileName, + [s], + s.status, + s.originalFileName, + 'HEAD', + s.fileName + ) + } as IGitStatusFileWithCommit + ]; + } + else if (s.indexStatus !== undefined) { + return [ + { + ...s, + status: s.status, + commit: new GitLogCommit( + GitCommitType.File, + repoPath, + GitService.stagedUncommittedSha, + 'You', + undefined, + new Date(), + '', + s.fileName, + [s], + s.status, + s.originalFileName, + 'HEAD', + s.fileName + ) + } as IGitStatusFileWithCommit + ]; + } + else { + return [ + { + ...s, + status: s.status, + commit: new GitLogCommit( + GitCommitType.File, + repoPath, + GitService.uncommittedSha, + 'You', + undefined, + new Date(), + '', + s.fileName, + [s], + s.status, + s.originalFileName, + 'HEAD', + s.fileName + ) + } as IGitStatusFileWithCommit + ]; + } + }) + ); } statuses.sort((a, b) => b.commit.date.getTime() - a.commit.date.getTime()); @@ -92,28 +161,43 @@ export class StatusFilesNode extends ExplorerNode { const groups = Arrays.groupBy(statuses, s => s.fileName); let children: IFileExplorerNode[] = [ - ...Iterables.map(Objects.values(groups), statuses => new StatusFileCommitsNode(repoPath, statuses[statuses.length - 1], statuses.map(s => s.commit), this.explorer)) + ...Iterables.map( + Objects.values(groups), + statuses => + new StatusFileCommitsNode( + repoPath, + statuses[statuses.length - 1], + statuses.map(s => s.commit), + this.explorer + ) + ) ]; if (this.explorer.config.files.layout !== ExplorerFilesLayout.List) { - const hierarchy = Arrays.makeHierarchical(children, n => n.uri.getRelativePath().split('/'), - (...paths: string[]) => Strings.normalizePath(path.join(...paths)), this.explorer.config.files.compact); + const hierarchy = Arrays.makeHierarchical( + children, + n => n.uri.getRelativePath().split('/'), + (...paths: string[]) => Strings.normalizePath(path.join(...paths)), + this.explorer.config.files.compact + ); const root = new FolderNode(repoPath, '', undefined, hierarchy, this.explorer); - children = await root.getChildren() as IFileExplorerNode[]; + children = (await root.getChildren()) as IFileExplorerNode[]; } else { children.sort((a, b) => (a.priority ? -1 : 1) - (b.priority ? -1 : 1) || a.label!.localeCompare(b.label!)); } if (log !== undefined && log.truncated) { - (children as (IFileExplorerNode | ShowAllNode)[]).push(new ShowAllNode('Show All Changes', this, this.explorer)); + (children as (IFileExplorerNode | ShowAllNode)[]).push( + new ShowAllNode('Show All Changes', this, this.explorer) + ); } return children; } async getTreeItem(): Promise<TreeItem> { - let files = (this.status.files !== undefined && this.includeWorkingTree) ? this.status.files.length : 0; + let files = this.status.files !== undefined && this.includeWorkingTree ? this.status.files.length : 0; if (this.status.upstream !== undefined) { const stats = await Container.git.getChangedFilesCount(this.repoPath, this.status.upstream); @@ -137,4 +221,4 @@ export class StatusFilesNode extends ExplorerNode { private get includeWorkingTree(): boolean { return this.explorer.config.includeWorkingTree; } -} \ No newline at end of file +} diff --git a/src/views/statusFilesResultsNode.ts b/src/views/statusFilesResultsNode.ts index d0e861e..98f006e 100644 --- a/src/views/statusFilesResultsNode.ts +++ b/src/views/statusFilesResultsNode.ts @@ -10,10 +10,9 @@ import { StatusFileNode } from './statusFileNode'; import * as path from 'path'; export class StatusFilesResultsNode extends ExplorerNode { - readonly supportsPaging: boolean = true; - private _cache: { label: string, diff: GitStatusFile[] | undefined } | undefined; + private _cache: { label: string; diff: GitStatusFile[] | undefined } | undefined; constructor( public readonly repoPath: string, @@ -28,14 +27,20 @@ export class StatusFilesResultsNode extends ExplorerNode { const diff = await this.getDiff(); if (diff === undefined) return []; - let children: IFileExplorerNode[] = [...Iterables.map(diff, s => new StatusFileNode(this.repoPath, s, this.ref1, this.ref2, this.explorer))]; + let children: IFileExplorerNode[] = [ + ...Iterables.map(diff, s => new StatusFileNode(this.repoPath, s, this.ref1, this.ref2, this.explorer)) + ]; if (this.explorer.config.files.layout !== ExplorerFilesLayout.List) { - const hierarchy = Arrays.makeHierarchical(children, n => n.uri.getRelativePath().split('/'), - (...paths: string[]) => Strings.normalizePath(path.join(...paths)), this.explorer.config.files.compact); + const hierarchy = Arrays.makeHierarchical( + children, + n => n.uri.getRelativePath().split('/'), + (...paths: string[]) => Strings.normalizePath(path.join(...paths)), + this.explorer.config.files.compact + ); const root = new FolderNode(this.repoPath, '', undefined, hierarchy, this.explorer); - children = await root.getChildren() as IFileExplorerNode[]; + children = (await root.getChildren()) as IFileExplorerNode[]; } else { children.sort((a, b) => (a.priority ? -1 : 1) - (b.priority ? -1 : 1) || a.label!.localeCompare(b.label!)); @@ -47,7 +52,10 @@ export class StatusFilesResultsNode extends ExplorerNode { async getTreeItem(): Promise<TreeItem> { const diff = await this.getDiff(); - const item = new TreeItem(await this.getLabel(), diff && diff.length > 0 ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.None); + const item = new TreeItem( + await this.getLabel(), + diff && diff.length > 0 ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.None + ); item.contextValue = ResourceType.ResultsFiles; return item; } @@ -81,4 +89,4 @@ export class StatusFilesResultsNode extends ExplorerNode { const cache = await this.ensureCache(); return cache.label; } -} \ No newline at end of file +} diff --git a/src/views/statusNode.ts b/src/views/statusNode.ts index 7e8b9ad..9bec8ef 100644 --- a/src/views/statusNode.ts +++ b/src/views/statusNode.ts @@ -9,7 +9,6 @@ import { StatusFilesNode } from './statusFilesNode'; import { StatusUpstreamNode } from './statusUpstreamNode'; export class StatusNode extends ExplorerNode { - constructor( uri: GitUri, public readonly repo: Repository, @@ -39,9 +38,7 @@ export class StatusNode extends ExplorerNode { } if (status.state.ahead || (status.files.length !== 0 && this.includeWorkingTree)) { - const range = status.upstream - ? `${status.upstream}..${status.branch}` - : undefined; + const range = status.upstream ? `${status.upstream}..${status.branch}` : undefined; this.children.push(new StatusFilesNode(status, range, this.explorer, this.active)); } } @@ -49,7 +46,15 @@ export class StatusNode extends ExplorerNode { let branch = await this.repo.getBranch(); if (branch !== undefined) { if (status !== undefined) { - branch = new GitBranch(branch.repoPath, branch.name, branch.current, branch.sha, branch.tracking, status.state.ahead, status.state.behind); + branch = new GitBranch( + branch.repoPath, + branch.name, + branch.current, + branch.sha, + branch.tracking, + status.state.ahead, + status.state.behind + ); } this.children.push(new StatusBranchNode(branch, this.uri, this.explorer)); @@ -79,7 +84,9 @@ export class StatusNode extends ExplorerNode { let hasChildren = false; const hasWorkingChanges = status.files.length !== 0 && this.includeWorkingTree; - let label = `${status.getUpstreamStatus({ prefix: `${GlyphChars.Space} ` })}${hasWorkingChanges ? status.getDiffStatus({ prefix: `${GlyphChars.Space} ` }) : ''}`; + let label = `${status.getUpstreamStatus({ prefix: `${GlyphChars.Space} ` })}${ + hasWorkingChanges ? status.getDiffStatus({ prefix: `${GlyphChars.Space} ` }) : '' + }`; let tooltip = `${status.branch} (current)`; let iconSuffix = ''; @@ -87,7 +94,8 @@ export class StatusNode extends ExplorerNode { if (this.explorer.config.showTrackingBranch) { label += `${GlyphChars.Space} ${GlyphChars.ArrowLeftRightLong}${GlyphChars.Space} ${status.upstream}`; } - tooltip += `\n\nTracking ${GlyphChars.Dash} ${status.upstream}\n${status.getUpstreamStatus({ empty: 'up-to-date', expand: true, separator: '\n' })}`; + tooltip += `\n\nTracking ${GlyphChars.Dash} ${status.upstream} +${status.getUpstreamStatus({ empty: 'up-to-date', expand: true, separator: '\n' })}`; if (status.state.ahead || status.state.behind) { hasChildren = true; @@ -102,7 +110,11 @@ export class StatusNode extends ExplorerNode { } if (hasWorkingChanges) { - tooltip += `\n\nHas uncommitted changes${status.getDiffStatus({ expand: true, prefix: `\n`, separator: '\n' })}`; + tooltip += `\n\nHas uncommitted changes${status.getDiffStatus({ + expand: true, + prefix: `\n`, + separator: '\n' + })}`; } let state: TreeItemCollapsibleState; @@ -145,12 +157,7 @@ export class StatusNode extends ExplorerNode { } export class StatusBranchNode extends BranchNode { - - constructor( - branch: GitBranch, - uri: GitUri, - explorer: GitExplorer - ) { + constructor(branch: GitBranch, uri: GitUri, explorer: GitExplorer) { super(branch, uri, explorer); } diff --git a/src/views/statusUpstreamNode.ts b/src/views/statusUpstreamNode.ts index 380220b..c8d8b4f 100644 --- a/src/views/statusUpstreamNode.ts +++ b/src/views/statusUpstreamNode.ts @@ -7,7 +7,6 @@ import { Explorer, ExplorerNode, ResourceType } from './explorerNode'; import { GitStatus, GitUri } from '../gitService'; export class StatusUpstreamNode extends ExplorerNode { - constructor( public readonly status: GitStatus, public readonly direction: 'ahead' | 'behind', @@ -18,18 +17,23 @@ export class StatusUpstreamNode extends ExplorerNode { } get id(): string { - return `gitlens:repository(${this.status.repoPath})${this.active ? ':active' : ''}:status:upstream:${this.direction}`; + return `gitlens:repository(${this.status.repoPath})${this.active ? ':active' : ''}:status:upstream:${ + this.direction + }`; } async getChildren(): Promise<ExplorerNode[]> { - const range = this.direction === 'ahead' - ? `${this.status.upstream}..${this.status.branch}` - : `${this.status.branch}..${this.status.upstream}`; + const range = + this.direction === 'ahead' + ? `${this.status.upstream}..${this.status.branch}` + : `${this.status.branch}..${this.status.upstream}`; let log = await Container.git.getLog(this.uri.repoPath!, { maxCount: 0, ref: range }); if (log === undefined) return []; - if (this.direction !== 'ahead') return [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer))]; + if (this.direction !== 'ahead') { + return [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer))]; + } // Since the last commit when we are looking 'ahead' can have no previous (because of the range given) -- look it up const commits = Array.from(log.commits.values()); @@ -45,19 +49,25 @@ export class StatusUpstreamNode extends ExplorerNode { } async getTreeItem(): Promise<TreeItem> { - const label = this.direction === 'ahead' - ? `${this.status.state.ahead} ${this.status.state.ahead === 1 ? 'commit' : 'commits'} (ahead of ${this.status.upstream})` - : `${this.status.state.behind} ${this.status.state.behind === 1 ? 'commit' : 'commits'} (behind ${this.status.upstream})`; + const label = + this.direction === 'ahead' + ? `${this.status.state.ahead} ${this.status.state.ahead === 1 ? 'commit' : 'commits'} (ahead of ${ + this.status.upstream + })` + : `${this.status.state.behind} ${this.status.state.behind === 1 ? 'commit' : 'commits'} (behind ${ + this.status.upstream + })`; const item = new TreeItem(label, TreeItemCollapsibleState.Collapsed); item.id = this.id; item.contextValue = ResourceType.StatusUpstream; + const iconSuffix = this.direction === 'ahead' ? 'upload' : 'download'; item.iconPath = { - dark: Container.context.asAbsolutePath(`images/dark/icon-${this.direction === 'ahead' ? 'upload' : 'download'}.svg`), - light: Container.context.asAbsolutePath(`images/light/icon-${this.direction === 'ahead' ? 'upload' : 'download'}.svg`) + dark: Container.context.asAbsolutePath(`images/dark/icon-${iconSuffix}.svg`), + light: Container.context.asAbsolutePath(`images/light/icon-${iconSuffix}.svg`) }; return item; } -} \ No newline at end of file +} diff --git a/src/views/tagNode.ts b/src/views/tagNode.ts index 332ec82..cbb8df7 100644 --- a/src/views/tagNode.ts +++ b/src/views/tagNode.ts @@ -9,7 +9,6 @@ import { GitExplorer } from './gitExplorer'; import { GitTag, GitUri } from '../gitService'; export class TagNode extends ExplorerRefNode { - readonly supportsPaging: boolean = true; constructor( @@ -34,7 +33,10 @@ export class TagNode extends ExplorerRefNode { const log = await Container.git.getLog(this.uri.repoPath!, { maxCount: this.maxCount, ref: this.tag.name }); if (log === undefined) return [new MessageNode('No commits yet')]; - const children: (CommitNode | ShowAllNode)[] = [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer))]; + const children: (CommitNode | ShowAllNode)[] = [ + ...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer)) + ]; + if (log.truncated) { children.push(new ShowAllNode('Show All Commits', this, this.explorer)); } diff --git a/src/views/tagsNode.ts b/src/views/tagsNode.ts index 71454a4..a050715 100644 --- a/src/views/tagsNode.ts +++ b/src/views/tagsNode.ts @@ -10,47 +10,48 @@ import { GitUri, Repository } from '../gitService'; import { TagNode } from './tagNode'; export class TagsNode extends ExplorerNode { + constructor( + uri: GitUri, + private readonly repo: Repository, + private readonly explorer: GitExplorer, + private readonly active: boolean = false + ) { + super(uri); + } + + get id(): string { + return `gitlens:repository(${this.repo.path})${this.active ? ':active' : ''}:tags`; + } + + async getChildren(): Promise<ExplorerNode[]> { + const tags = await this.repo.getTags(); + if (tags.length === 0) return [new MessageNode('No tags yet')]; + + tags.sort((a, b) => a.name.localeCompare(b.name)); + const tagNodes = [...tags.map(t => new TagNode(t, this.uri, this.explorer))]; + if (this.explorer.config.branches.layout === ExplorerBranchesLayout.List) return tagNodes; + + const hierarchy = Arrays.makeHierarchical( + tagNodes, + n => n.tag.name.split('/'), + (...paths: string[]) => paths.join('/'), + this.explorer.config.files.compact + ); + + const root = new BranchOrTagFolderNode(this.repo.path, '', undefined, hierarchy, this.explorer); + const children = (await root.getChildren()) as (BranchOrTagFolderNode | TagNode)[]; + return children; + } + + async getTreeItem(): Promise<TreeItem> { + const item = new TreeItem(`Tags`, TreeItemCollapsibleState.Collapsed); + item.contextValue = ResourceType.Tags; + + item.iconPath = { + dark: Container.context.asAbsolutePath('images/dark/icon-tag.svg'), + light: Container.context.asAbsolutePath('images/light/icon-tag.svg') + }; - constructor( - uri: GitUri, - private readonly repo: Repository, - private readonly explorer: GitExplorer, - private readonly active: boolean = false - ) { - super(uri); - } - - get id(): string { - return `gitlens:repository(${this.repo.path})${this.active ? ':active' : ''}:tags`; - } - - async getChildren(): Promise<ExplorerNode[]> { - const tags = await this.repo.getTags(); - if (tags.length === 0) return [new MessageNode('No tags yet')]; - - tags.sort((a, b) => a.name.localeCompare(b.name)); - const tagNodes = [...tags.map(t => new TagNode(t, this.uri, this.explorer))]; - if (this.explorer.config.branches.layout === ExplorerBranchesLayout.List) return tagNodes; - - const hierarchy = Arrays.makeHierarchical(tagNodes, - n => n.tag.name.split('/'), - (...paths: string[]) => paths.join('/'), - this.explorer.config.files.compact); - - const root = new BranchOrTagFolderNode(this.repo.path, '', undefined, hierarchy, this.explorer); - const children = await root.getChildren() as (BranchOrTagFolderNode | TagNode)[]; - return children; - } - - async getTreeItem(): Promise<TreeItem> { - const item = new TreeItem(`Tags`, TreeItemCollapsibleState.Collapsed); - item.contextValue = ResourceType.Tags; - - item.iconPath = { - dark: Container.context.asAbsolutePath('images/dark/icon-tag.svg'), - light: Container.context.asAbsolutePath('images/light/icon-tag.svg') - }; - - return item; - } + return item; } +} diff --git a/src/webviews/settingsEditor.ts b/src/webviews/settingsEditor.ts index b913664..c0edfbb 100644 --- a/src/webviews/settingsEditor.ts +++ b/src/webviews/settingsEditor.ts @@ -5,7 +5,6 @@ import { SettingsBootstrap } from '../ui/ipc'; import { WebviewEditor } from './webviewEditor'; export class SettingsEditor extends WebviewEditor<SettingsBootstrap> { - constructor() { super(); } @@ -32,9 +31,7 @@ export class SettingsEditor extends WebviewEditor<SettingsBootstrap> { } registerCommands() { - return [ - commands.registerCommand('gitlens.showSettingsPage', this.show, this) - ]; + return [commands.registerCommand('gitlens.showSettingsPage', this.show, this)]; } private getAvailableScopes(): ['user' | 'workspace', string][] { diff --git a/src/webviews/webviewEditor.ts b/src/webviews/webviewEditor.ts index f295fb2..c375cee 100644 --- a/src/webviews/webviewEditor.ts +++ b/src/webviews/webviewEditor.ts @@ -1,5 +1,15 @@ 'use strict'; -import { ConfigurationChangeEvent, ConfigurationTarget, Disposable, Uri, ViewColumn, WebviewPanel, WebviewPanelOnDidChangeViewStateEvent, window, workspace } from 'vscode'; +import { + ConfigurationChangeEvent, + ConfigurationTarget, + Disposable, + Uri, + ViewColumn, + WebviewPanel, + WebviewPanelOnDidChangeViewStateEvent, + window, + workspace +} from 'vscode'; import { configuration, IConfig } from '../configuration'; import { Container } from '../container'; import { Message, SettingsChangedMessage } from '../ui/ipc'; @@ -7,7 +17,6 @@ import { Logger } from '../logger'; import * as fs from 'fs'; export abstract class WebviewEditor<TBootstrap> extends Disposable { - private _disposable: Disposable | undefined; private _disposablePanel: Disposable | undefined; private _panel: WebviewPanel | undefined; @@ -70,9 +79,7 @@ export abstract class WebviewEditor<TBootstrap> extends Disposable { switch (e.type) { case 'saveSettings': - const target = e.scope === 'workspace' - ? ConfigurationTarget.Workspace - : ConfigurationTarget.Global; + const target = e.scope === 'workspace' ? ConfigurationTarget.Workspace : ConfigurationTarget.Global; for (const key in e.changes) { const inspect = await configuration.inspect(key)!; @@ -99,10 +106,14 @@ export abstract class WebviewEditor<TBootstrap> extends Disposable { } async show(): Promise<void> { - let html = (await this.getHtml()) - .replace(/{{root}}/g, Uri.file(Container.context.asAbsolutePath('.')).with({ scheme: 'vscode-resource' }).toString()); - if (html.includes('\'{{bootstrap}}\'')) { - html = html.replace('\'{{bootstrap}}\'', JSON.stringify(this.getBootstrap())); + let html = (await this.getHtml()).replace( + /{{root}}/g, + Uri.file(Container.context.asAbsolutePath('.')) + .with({ scheme: 'vscode-resource' }) + .toString() + ); + if (html.includes("'{{bootstrap}}'")) { + html = html.replace("'{{bootstrap}}'", JSON.stringify(this.getBootstrap())); } if (this._panel === undefined) { @@ -163,6 +174,12 @@ export abstract class WebviewEditor<TBootstrap> extends Disposable { private postUpdatedConfiguration() { // Make sure to get the raw config, not from the container which has the modes mixed in - return this.postMessage({ type: 'settingsChanged', config: configuration.get<IConfig>() } as SettingsChangedMessage, 'config'); + return this.postMessage( + { + type: 'settingsChanged', + config: configuration.get<IConfig>() + } as SettingsChangedMessage, + 'config' + ); } } diff --git a/src/webviews/welcomeEditor.ts b/src/webviews/welcomeEditor.ts index a090418..b8779ed 100644 --- a/src/webviews/welcomeEditor.ts +++ b/src/webviews/welcomeEditor.ts @@ -28,8 +28,6 @@ export class WelcomeEditor extends WebviewEditor<WelcomeBootstrap> { } registerCommands() { - return [ - commands.registerCommand('gitlens.showWelcomePage', this.show, this) - ]; + return [commands.registerCommand('gitlens.showWelcomePage', this.show, this)]; } } diff --git a/test/extension.test.ts b/test/extension.test.ts index 563d626..4fc159e 100644 --- a/test/extension.test.ts +++ b/test/extension.test.ts @@ -13,10 +13,9 @@ import * as assert from 'assert'; // Defines a Mocha test suite to group tests of similar kind together suite('Extension Tests', () => { - // Defines a Mocha unit test test('Something 1', () => { assert.equal(-1, [1, 2, 3].indexOf(5)); assert.equal(-1, [1, 2, 3].indexOf(0)); }); -}); \ No newline at end of file +}); diff --git a/test/index.ts b/test/index.ts index 31de27a..41cfdda 100644 --- a/test/index.ts +++ b/test/index.ts @@ -15,8 +15,8 @@ let testRunner = require('vscode/lib/testrunner'); // You can directly control Mocha options by uncommenting the following lines // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info testRunner.configure({ - ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) + ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) useColors: true // colored output from test results }); -module.exports = testRunner; \ No newline at end of file +module.exports = testRunner; diff --git a/tsconfig.json b/tsconfig.json index 88f32f7..3ed729b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "forceConsistentCasingInFileNames": true, "importHelpers": true, - "lib": [ "es2015", "es2016", "es2017" ], + "lib": ["es2015", "es2016", "es2017"], "module": "esnext", "moduleResolution": "node", "noFallthroughCasesInSwitch": true, @@ -16,10 +16,5 @@ "strict": true, "target": "es2017" }, - "exclude": [ - "node_modules", - "test", - ".vscode-test", - "src/ui", - ] -} \ No newline at end of file + "exclude": ["node_modules", "rules", "test", ".vscode-test", "src/ui"] +} diff --git a/tslint.json b/tslint.json index 6cfd392..541f08f 100644 --- a/tslint.json +++ b/tslint.json @@ -1,44 +1,23 @@ { + "extends": ["tslint-prettiest"], "rules": { "adjacent-overload-signatures": true, - "array-type": [ - true, - "array" - ], - "arrow-parens": [ - true, - "ban-single-arg-parens" - ], + "array-type": [true, "array"], + "arrow-parens": [true, "ban-single-arg-parens"], "arrow-return-shorthand": true, "class-name": true, - "comment-format": [ - true, - "check-space" - ], - "curly": [ - true, - "ignore-same-line" - ], - "indent": [ - true, - "spaces", - 4 - ], + "comment-format": [true, "check-space"], + "curly": [true, "ignore-same-line"], + "eofline": true, "interface-over-type-literal": true, + "linebreak-style": [true, "LF"], "new-parens": true, "no-angle-bracket-type-assertion": true, - "no-consecutive-blank-lines": [ - true, - 1 - ], + "no-consecutive-blank-lines": [true, 1], "no-default-export": true, "no-duplicate-variable": true, "no-eval": true, - "no-inferrable-types": [ - true, - "ignore-params", - "ignore-properties" - ], + "no-inferrable-types": [true, "ignore-params", "ignore-properties"], "no-internal-module": true, "no-irregular-whitespace": true, "no-reference": true, @@ -49,19 +28,9 @@ "no-unused-expression": false, "no-var-keyword": true, "no-var-requires": false, - "object-literal-key-quotes": [ - true, - "as-needed" - ], - "one-line": [ - true, - "check-open-brace", - "check-whitespace" - ], - "one-variable-per-declaration": [ - true, - "ignore-for-loop" - ], + "object-literal-key-quotes": [true, "as-needed"], + "one-line": [true, "check-open-brace", "check-whitespace"], + "one-variable-per-declaration": [true, "ignore-for-loop"], "ordered-imports": [ true, { @@ -71,20 +40,12 @@ ], "prefer-const": true, "prefer-for-of": true, - "prefer-template": [ - true, - "allow-single-concat" - ], - "quotemark": [ - true, - "single", - "avoid-escape" - ], + "prefer-method-signature": true, + "prefer-template": [true, "allow-single-concat"], + "prettiest": [true, "spaces", 4], + "quotemark": [true, "single", "avoid-escape"], "radix": true, - "semicolon": [ - true, - "always" - ], + "semicolon": [true, "always"], "space-before-function-paren": [ true, { @@ -100,10 +61,7 @@ "singleline": "never" } ], - "triple-equals": [ - true, - "allow-null-check" - ], + "triple-equals": [true, "allow-null-check"], "typedef-whitespace": [ true, { @@ -115,13 +73,7 @@ } ], "use-isnan": true, - "variable-name": [ - true, - "allow-leading-underscore", - "allow-pascal-case", - "ban-keywords", - "check-format" - ], + "variable-name": [true, "allow-leading-underscore", "allow-pascal-case", "ban-keywords", "check-format"], "whitespace": [ true, "check-branch", @@ -133,4 +85,4 @@ ] }, "defaultSeverity": "warning" -} \ No newline at end of file +} diff --git a/webpack.config.js b/webpack.config.js index b7f438f..16c0af0 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,7 +2,7 @@ const webpack = require('webpack'); const path = require('path'); const nodeExternals = require('webpack-node-externals'); -const UglifyJsPlugin = require('uglifyjs-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); module.exports = function(env, argv) { if (env === undefined) { @@ -43,9 +43,7 @@ module.exports = function(env, argv) { resolve: { extensions: ['.ts'] }, - externals: [ - nodeExternals() - ], + externals: [nodeExternals()], devtool: sourceMaps ? 'eval-source-map' : undefined, module: { rules: [