mirror of
https://github.com/ckaczor/vscode-gitlens.git
synced 2026-02-12 11:08:34 -05:00
Compare commits
11 Commits
v4.4.0-bet
...
v4.5.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ed0778a02 | ||
|
|
68c17206e5 | ||
|
|
d6c84061f9 | ||
|
|
208d549c1c | ||
|
|
6518279937 | ||
|
|
c03634fafc | ||
|
|
3ba1fe18ee | ||
|
|
4db2b116c2 | ||
|
|
b40579f4b2 | ||
|
|
15c981ba06 | ||
|
|
c2f78a7242 |
24
CHANGELOG.md
24
CHANGELOG.md
@@ -4,7 +4,23 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [4.4.0-beta] - 2017-08-17
|
||||
## [4.5.0-beta] - 2017-08-27
|
||||
### Added
|
||||
- Adds an all-new `Git File History` explorer to the Explorer activity -- enabled via `"gitlens.insiders": true`
|
||||
- Shows the commit history of the active file -- automatically tracks the active editor
|
||||
- Provides toolbar buttons to `Refresh`
|
||||
- Provides a context menu with `Open Changes`, `Compare File with Working Tree`, `Open File`, `Open File Revision`, `Open File in Remote`, `Open File Revision in Remote`, and `Show Commit Details` commands
|
||||
- Adds a `No stashed changes` message to the `Git Stashes` explorer when there are no stashes
|
||||
- Adds `${filePath}` token to file formatting
|
||||
|
||||
### Changed
|
||||
- Changes `gitlens.stashExplorer.stashFileFormat` setting to defaults to `${filePath}` for better separator handling
|
||||
|
||||
## [4.4.1] - 2017-08-23
|
||||
## Fixed
|
||||
- Fixes [#114](https://github.com/eamodio/vscode-gitlens/issues/114) - Stylus files makes code lens freak out
|
||||
|
||||
## [4.4.0] - 2017-08-18
|
||||
## Added
|
||||
- Adds a progress indicator to the `Toggle File Blame Annotations` command (`gitlens.toggleFileBlame`) icon -- pulses while annotations are computed
|
||||
- Adds an active state to the `Toggle File Blame Annotations` command (`gitlens.toggleFileBlame`) icon -- turns orange while the annotations are visible
|
||||
@@ -13,11 +29,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
|
||||
## Changed
|
||||
- Changes chat links from Gitter to [Slack](https://join.slack.com/t/vscode-gitlens/shared_invite/MjIxOTgxNDE3NzM0LTE1MDE2Nzk1MTgtMjkwMmZjMzcxNQ)
|
||||
- Changes the look of the line separators on the gutter blame annotations
|
||||
- Changes the `gitlens.advanced.toggleWhitespace.enabled` configuration setting to default to `false` -- as this should no longer be required
|
||||
- Changes the `gitlens.advanced.toggleWhitespace.enabled` configuration setting to default to `false` -- thanks to the awesome work in vscode by Alexandru Dima ([@alexandrudima](https://github.com/alexandrudima)) this is no longer required!
|
||||
|
||||
## Removed
|
||||
- Removes unneeded `gitlens.stashExplorer.enabled` configuration setting since users can add or remove custom views natively now
|
||||
- Removes unneeded `Toggle Git Stashed Explorer` command (`gitlens.stashExplorer.toggle`) since users can add or remove custom views natively now
|
||||
- Removes unneeded `Toggle Git Stashes Explorer` command (`gitlens.stashExplorer.toggle`) since users can add or remove custom views natively now
|
||||
- Removes the `gitlens.theme.annotations.file.hover.separateLines` configuration setting
|
||||
|
||||
## Fixed
|
||||
@@ -40,7 +56,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
|
||||
## [4.3.1] - 2017-07-03
|
||||
## Added
|
||||
- Adds `gitlens.stashExplorer.enabled` setting to specify whether or not to show the `Git Stashes` explorer
|
||||
- Adds `Toggle Git Stashed Explorer` command (`gitlens.stashExplorer.toggle`) - toggles the `Git Stashes` explorer on and off
|
||||
- Adds `Toggle Git Stashes Explorer` command (`gitlens.stashExplorer.toggle`) - toggles the `Git Stashes` explorer on and off
|
||||
|
||||
## Changed
|
||||
- Hides the `Git Stashes` explorer by default
|
||||
|
||||
18
README.md
18
README.md
@@ -111,7 +111,13 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
|
||||
|
||||
### Navigate and Explore
|
||||
|
||||
- Adds a `Git Stashes` explorer to the Explorer activity ([optional](#git-stashes-explorer-settings), off by default)
|
||||
- Adds a [customizable](#git-file-history-explorer-settings) `Git File History` explorer to the Explorer activity -- currently [insiders](#insiders) only
|
||||
|
||||
- Shows the commit history of the active file -- automatically tracks the active editor
|
||||
- Provides toolbar buttons to `Refresh`
|
||||
- Provides a context menu with `Open Changes`, `Compare File with Working Tree`, `Open File`, `Open File Revision`, `Open File in Remote`, `Open File Revision in Remote`, and `Show Commit Details` commands
|
||||
|
||||
- Adds a [customizable](#git-stashes-explorer-settings) `Git Stashes` explorer to the Explorer activity
|
||||
|
||||

|
||||
|
||||
@@ -289,12 +295,18 @@ GitLens is highly customizable and provides many configuration settings to allow
|
||||
|`gitlens.codeLens.customLocationSymbols`|Specifies the set of document symbols where Git code lens will be shown in the document
|
||||
|`gitlens.codeLens.perLanguageLocations`|Specifies where Git code lens will be shown in the document for the specified languages
|
||||
|
||||
### Git File History Explorer Settings
|
||||
|
||||
|Name | Description
|
||||
|-----|------------
|
||||
|`gitlens.fileHistoryExplorer.commitFormat`|Specifies the format of committed changes in the `Git File History` explorer <br />Available tokens<br /> ${id} - commit id<br /> ${author} - commit author<br /> ${message} - commit message<br /> ${ago} - relative commit date (e.g. 1 day ago)<br /> ${date} - formatted commit date (format specified by `gitlens.statusBar.dateFormat`)<br /> ${authorAgo} - commit author, relative commit date<br />See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting
|
||||
|
||||
### Git Stashes Explorer Settings
|
||||
|
||||
|Name | Description
|
||||
|-----|------------
|
||||
|`gitlens.stashExplorer.stashFormat`|Specifies the format of stashed changes in the `Git Stashes` explorer <br />Available tokens<br /> ${id} - commit id<br /> ${author} - commit author<br /> ${message} - commit message<br /> ${ago} - relative commit date (e.g. 1 day ago)<br /> ${date} - formatted commit date (format specified by `gitlens.statusBar.dateFormat`)<br /> ${authorAgo} - commit author, relative commit date<br />See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting
|
||||
|`gitlens.stashExplorer.stashFileFormat`|Specifies the format of a stashed file in the `Git Stashes` explorer <br />Available tokens<br /> ${file} - file name<br /> ${path} - file path
|
||||
|`gitlens.stashExplorer.stashFileFormat`|Specifies the format of a stashed file in the `Git Stashes` explorer <br />Available tokens<br /> ${file} - file name<br /> ${filePath} - file name and path<br /> ${path} - file path
|
||||
|
||||
### Status Bar Settings
|
||||
|
||||
@@ -338,7 +350,6 @@ GitLens is highly customizable and provides many configuration settings to allow
|
||||
|
||||
|Name | Description
|
||||
|-----|------------
|
||||
|`gitlens.advanced.toggleWhitespace.enabled`|Specifies whether or not to toggle whitespace off then showing blame annotations (*may* be required by certain fonts/themes)
|
||||
|`gitlens.advanced.telemetry.enabled`|Specifies whether or not to enable GitLens telemetry (even if enabled still abides by the overall `telemetry.enableTelemetry` setting
|
||||
|`gitlens.advanced.menus`|Specifies which commands will be added to which menus
|
||||
|`gitlens.advanced.caching.enabled`|Specifies whether git output will be cached
|
||||
@@ -351,7 +362,6 @@ GitLens is highly customizable and provides many configuration settings to allow
|
||||
## Known Issues
|
||||
|
||||
- If the `Copy to * clipboard` commands don't work on Linux -- `xclip` needs to be installed. You can install it via `sudo apt-get install xclip`
|
||||
- Visible whitespace causes issues ([vscode issue #11485](https://github.com/Microsoft/vscode/issues/11485)) with the `expanded` and `compact` blame annotation styles when using a non-monospace font -- set `"gitlens.advanced.toggleWhitespace.enabled": true` if you are using a non-monospace font
|
||||
|
||||
## Contributors
|
||||
|
||||
|
||||
84
package-lock.json
generated
84
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gitlens",
|
||||
"version": "4.3.3",
|
||||
"version": "4.4.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -16,19 +16,19 @@
|
||||
"integrity": "sha1-qjuL2ivlErGuCgV7lC6GnDcKVWk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "8.0.22"
|
||||
"@types/node": "8.0.25"
|
||||
}
|
||||
},
|
||||
"@types/mocha": {
|
||||
"version": "2.2.41",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.41.tgz",
|
||||
"integrity": "sha1-4nzwgXFT658nE7LT9saPHhw8pgg=",
|
||||
"version": "2.2.42",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.42.tgz",
|
||||
"integrity": "sha512-b6gVDoxEbAQGwbV7gSzeFw/hy3/eEAokztktdzl4bHvGgb9K5zW4mVQDlVYch2w31m8t/J7L2iqhQvz3r5edCQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "8.0.22",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.22.tgz",
|
||||
"integrity": "sha512-+YQ5JLlvLP24teVUdUDep83mAWIFoAnOMosrH/2+xDeU9YMUpmMJtYOqVtbivs37h2PL9svz0R3r/MfVuEvEIA==",
|
||||
"version": "8.0.25",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.25.tgz",
|
||||
"integrity": "sha512-zT+t9841g1HsjLtPMCYxmb1U4pcZ2TOegAKiomlmj6bIziuaEYHUavxLE9NRwdntY0vOCrgHho6OXjDX7fm/Kw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/tmp": {
|
||||
@@ -147,9 +147,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"babel-code-frame": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz",
|
||||
"integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=",
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
||||
"integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "1.1.3",
|
||||
@@ -1019,7 +1019,7 @@
|
||||
"clone-stats": "1.0.0",
|
||||
"cloneable-readable": "1.0.0",
|
||||
"is-stream": "1.1.0",
|
||||
"remove-trailing-separator": "1.0.2",
|
||||
"remove-trailing-separator": "1.1.0",
|
||||
"replace-ext": "1.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1200,7 +1200,7 @@
|
||||
"requires": {
|
||||
"chalk": "1.1.3",
|
||||
"commander": "2.9.0",
|
||||
"is-my-json-valid": "2.16.0",
|
||||
"is-my-json-valid": "2.16.1",
|
||||
"pinkie-promise": "2.0.1"
|
||||
}
|
||||
},
|
||||
@@ -1271,9 +1271,9 @@
|
||||
"integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA=="
|
||||
},
|
||||
"ignore": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.3.tgz",
|
||||
"integrity": "sha1-QyNS5XrM2HqzEQ6C0/6g5HgSFW0="
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.4.tgz",
|
||||
"integrity": "sha512-KjHyHxUgicfgFiTJaIA9DoeY3TIQz5thaKqm35re7RTVVB7zjF1fTMIDMXM4GUUBipR4FW8BvGnA115pZ/AxQQ=="
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
@@ -1345,9 +1345,9 @@
|
||||
}
|
||||
},
|
||||
"is-my-json-valid": {
|
||||
"version": "2.16.0",
|
||||
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz",
|
||||
"integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=",
|
||||
"version": "2.16.1",
|
||||
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz",
|
||||
"integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"generate-function": "2.0.0",
|
||||
@@ -1852,7 +1852,7 @@
|
||||
"integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"remove-trailing-separator": "1.0.2"
|
||||
"remove-trailing-separator": "1.1.0"
|
||||
}
|
||||
},
|
||||
"oauth-sign": {
|
||||
@@ -2090,9 +2090,9 @@
|
||||
}
|
||||
},
|
||||
"remove-trailing-separator": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz",
|
||||
"integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
|
||||
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
|
||||
"dev": true
|
||||
},
|
||||
"repeat-element": {
|
||||
@@ -2229,18 +2229,18 @@
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.5.6",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
|
||||
"integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=",
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
|
||||
"dev": true
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.4.15",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz",
|
||||
"integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=",
|
||||
"version": "0.4.16",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.16.tgz",
|
||||
"integrity": "sha512-A6vlydY7H/ljr4L2UOhDSajQdZQ6dMD7cLH0pzwcmwLyc9u8PNI4WGtnfDDzX7uzGL6c/T+ORL97Zlh+S4iOrg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"source-map": "0.5.6"
|
||||
"source-map": "0.5.7"
|
||||
}
|
||||
},
|
||||
"sparkles": {
|
||||
@@ -2475,12 +2475,12 @@
|
||||
"dev": true
|
||||
},
|
||||
"tslint": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.6.0.tgz",
|
||||
"integrity": "sha1-CIqmxgJmIzOGULKQCCirPt9Z9s8=",
|
||||
"version": "5.7.0",
|
||||
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.7.0.tgz",
|
||||
"integrity": "sha1-wl4NDJL6EgHCvDDoROCOaCtPNVI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-code-frame": "6.22.0",
|
||||
"babel-code-frame": "6.26.0",
|
||||
"colors": "1.1.2",
|
||||
"commander": "2.9.0",
|
||||
"diff": "3.2.0",
|
||||
@@ -2489,13 +2489,13 @@
|
||||
"resolve": "1.4.0",
|
||||
"semver": "5.4.1",
|
||||
"tslib": "1.7.1",
|
||||
"tsutils": "2.8.0"
|
||||
"tsutils": "2.8.1"
|
||||
}
|
||||
},
|
||||
"tsutils": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.8.0.tgz",
|
||||
"integrity": "sha1-AWAXNymzvxOGKN0UoVN+AIUdgUo=",
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.8.1.tgz",
|
||||
"integrity": "sha1-N3FATnyp8L7fXZGaR6SxiQpo7/8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tslib": "1.7.1"
|
||||
@@ -2695,9 +2695,9 @@
|
||||
}
|
||||
},
|
||||
"vscode": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.4.tgz",
|
||||
"integrity": "sha1-Hx1NZi1VyaKLxGeqy2MikfcKaG0=",
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.5.tgz",
|
||||
"integrity": "sha1-EOsQQAGEDD3QgTgV/UoF+PyILRQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "7.1.1",
|
||||
@@ -2711,7 +2711,7 @@
|
||||
"mocha": "3.5.0",
|
||||
"request": "2.81.0",
|
||||
"semver": "5.4.1",
|
||||
"source-map-support": "0.4.15",
|
||||
"source-map-support": "0.4.16",
|
||||
"url-parse": "1.1.9",
|
||||
"vinyl-source-stream": "1.1.0"
|
||||
}
|
||||
|
||||
3274
package.json
3274
package.json
File diff suppressed because it is too large
Load Diff
81
src/codeLensController.ts
Normal file
81
src/codeLensController.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
'use strict';
|
||||
import { Objects } from './system';
|
||||
import { Disposable, ExtensionContext, languages, TextEditor, workspace } from 'vscode';
|
||||
import { IConfig } from './configuration';
|
||||
import { CommandContext, ExtensionKey, setCommandContext } from './constants';
|
||||
import { GitCodeLensProvider } from './gitCodeLensProvider';
|
||||
import { GitService } from './gitService';
|
||||
import { Logger } from './logger';
|
||||
|
||||
export class CodeLensController extends Disposable {
|
||||
|
||||
private _codeLensProvider: GitCodeLensProvider | undefined;
|
||||
private _codeLensProviderDisposable: Disposable | undefined;
|
||||
private _config: IConfig;
|
||||
private _disposable: Disposable | undefined;
|
||||
|
||||
constructor(private context: ExtensionContext, private git: GitService) {
|
||||
super(() => this.dispose());
|
||||
|
||||
this._onConfigurationChanged();
|
||||
|
||||
const subscriptions: Disposable[] = [];
|
||||
|
||||
subscriptions.push(workspace.onDidChangeConfiguration(this._onConfigurationChanged, this));
|
||||
subscriptions.push(git.onDidChangeGitCache(this._onGitCacheChanged, this));
|
||||
|
||||
this._disposable = Disposable.from(...subscriptions);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._disposable && this._disposable.dispose();
|
||||
|
||||
this._codeLensProviderDisposable && this._codeLensProviderDisposable.dispose();
|
||||
this._codeLensProviderDisposable = undefined;
|
||||
this._codeLensProvider = undefined;
|
||||
}
|
||||
|
||||
private _onConfigurationChanged() {
|
||||
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
|
||||
|
||||
if (!Objects.areEquivalent(cfg.codeLens, this._config && this._config.codeLens)) {
|
||||
Logger.log('CodeLens config changed; resetting CodeLens provider');
|
||||
if (cfg.codeLens.enabled && (cfg.codeLens.recentChange.enabled || cfg.codeLens.authors.enabled)) {
|
||||
if (this._codeLensProvider) {
|
||||
this._codeLensProvider.reset();
|
||||
}
|
||||
else {
|
||||
this._codeLensProvider = new GitCodeLensProvider(this.context, this.git);
|
||||
this._codeLensProviderDisposable = languages.registerCodeLensProvider(GitCodeLensProvider.selector, this._codeLensProvider);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this._codeLensProviderDisposable && this._codeLensProviderDisposable.dispose();
|
||||
this._codeLensProviderDisposable = undefined;
|
||||
this._codeLensProvider = undefined;
|
||||
}
|
||||
|
||||
setCommandContext(CommandContext.CanToggleCodeLens, cfg.codeLens.recentChange.enabled || cfg.codeLens.authors.enabled);
|
||||
}
|
||||
|
||||
this._config = cfg;
|
||||
}
|
||||
|
||||
private _onGitCacheChanged() {
|
||||
Logger.log('Git cache changed; resetting CodeLens provider');
|
||||
this._codeLensProvider && this._codeLensProvider.reset();
|
||||
}
|
||||
|
||||
toggleCodeLens(editor: TextEditor) {
|
||||
if (!this._config.codeLens.recentChange.enabled && !this._config.codeLens.authors.enabled) return;
|
||||
|
||||
Logger.log(`toggleCodeLens()`);
|
||||
if (this._codeLensProviderDisposable) {
|
||||
this._codeLensProviderDisposable.dispose();
|
||||
this._codeLensProviderDisposable = undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
this._codeLensProviderDisposable = languages.registerCodeLensProvider(GitCodeLensProvider.selector, new GitCodeLensProvider(this.context, this.git));
|
||||
}
|
||||
}
|
||||
@@ -6,13 +6,17 @@ import { GitService, GitUri } from '../gitService';
|
||||
import { Logger } from '../logger';
|
||||
import { OpenInRemoteCommandArgs } from './openInRemote';
|
||||
|
||||
export interface OpenFileInRemoteCommandArgs {
|
||||
range?: boolean;
|
||||
}
|
||||
|
||||
export class OpenFileInRemoteCommand extends ActiveEditorCommand {
|
||||
|
||||
constructor(private git: GitService) {
|
||||
super(Commands.OpenFileInRemote);
|
||||
}
|
||||
|
||||
async execute(editor?: TextEditor, uri?: Uri) {
|
||||
async execute(editor?: TextEditor, uri?: Uri, args: OpenFileInRemoteCommandArgs = { range: true }) {
|
||||
uri = getCommandUri(uri, editor);
|
||||
if (uri === undefined) return undefined;
|
||||
|
||||
@@ -23,7 +27,9 @@ export class OpenFileInRemoteCommand extends ActiveEditorCommand {
|
||||
|
||||
try {
|
||||
const remotes = Arrays.uniqueBy(await this.git.getRemotes(gitUri.repoPath), _ => _.url, _ => !!_.provider);
|
||||
const range = editor === undefined ? undefined : new Range(editor.selection.start.with({ line: editor.selection.start.line + 1 }), editor.selection.end.with({ line: editor.selection.end.line + 1 }));
|
||||
const range = (args.range && editor !== undefined)
|
||||
? 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: {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
'use strict';
|
||||
import { Strings } from '../system';
|
||||
import { commands, TextEditor, Uri, window } from 'vscode';
|
||||
import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common';
|
||||
import { ActiveEditorCachedCommand, CommandContext, Commands, getCommandUri } from './common';
|
||||
import { GlyphChars } from '../constants';
|
||||
import { CommitNode } from '../views/explorerNodes';
|
||||
import { GitCommit, GitLog, GitLogCommit, GitService, GitUri } from '../gitService';
|
||||
import { Logger } from '../logger';
|
||||
import { CommandQuickPickItem, CommitDetailsQuickPick, CommitWithFileStatusQuickPickItem } from '../quickPicks';
|
||||
@@ -24,6 +25,18 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand {
|
||||
super(Commands.ShowQuickCommitDetails);
|
||||
}
|
||||
|
||||
protected async preExecute(context: CommandContext, ...args: any[]): Promise<any> {
|
||||
if (context.type === 'view') {
|
||||
if (context.node instanceof CommitNode) {
|
||||
args = [{ sha: context.node.uri.sha, commit: context.node.commit }];
|
||||
}
|
||||
else {
|
||||
args = [{ sha: context.node.uri.sha }];
|
||||
}
|
||||
}
|
||||
return this.execute(context.editor, context.uri, ...args);
|
||||
}
|
||||
|
||||
async execute(editor?: TextEditor, uri?: Uri, args: ShowQuickCommitDetailsCommandArgs = {}) {
|
||||
uri = getCommandUri(uri, editor);
|
||||
if (uri === undefined) return undefined;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
'use strict';
|
||||
import { TextEditor, TextEditorEdit } from 'vscode';
|
||||
import { CodeLensController } from '../codeLensController';
|
||||
import { Commands, EditorCommand } from './common';
|
||||
import { GitService } from '../gitService';
|
||||
|
||||
export class ToggleCodeLensCommand extends EditorCommand {
|
||||
|
||||
constructor(private git: GitService) {
|
||||
constructor(private codeLensController: CodeLensController) {
|
||||
super(Commands.ToggleCodeLens);
|
||||
}
|
||||
|
||||
execute(editor: TextEditor, edit: TextEditorEdit) {
|
||||
return this.git.toggleCodeLens(editor);
|
||||
return this.codeLensController.toggleCodeLens(editor);
|
||||
}
|
||||
}
|
||||
@@ -296,15 +296,19 @@ export interface IConfig {
|
||||
|
||||
defaultDateFormat: string | null;
|
||||
|
||||
fileHistoryExplorer: {
|
||||
commitFormat: string;
|
||||
// commitFileFormat: string;
|
||||
// dateFormat: string | null;
|
||||
};
|
||||
|
||||
gitExplorer: {
|
||||
enabled: boolean;
|
||||
commitFormat: string;
|
||||
commitFileFormat: string;
|
||||
// dateFormat: string | null;
|
||||
};
|
||||
|
||||
stashExplorer: {
|
||||
enabled: boolean;
|
||||
stashFormat: string;
|
||||
stashFileFormat: string;
|
||||
// dateFormat: string | null;
|
||||
|
||||
@@ -17,9 +17,11 @@ import { StashApplyCommand, StashDeleteCommand, StashSaveCommand } from './comma
|
||||
import { ToggleCodeLensCommand } from './commands';
|
||||
import { CodeLensLocations, IConfig, LineHighlightLocations } from './configuration';
|
||||
import { ApplicationInsightsKey, CommandContext, ExtensionKey, QualifiedExtensionId, setCommandContext, WorkspaceState } from './constants';
|
||||
import { CodeLensController } from './codeLensController';
|
||||
import { CurrentLineController, LineAnnotationType } from './currentLineController';
|
||||
import { GitContentProvider } from './gitContentProvider';
|
||||
// import { GitExplorer } from './views/gitExplorer';
|
||||
import { FileHistoryExplorer } from './views/fileHistoryExplorer';
|
||||
import { StashExplorer } from './views/stashExplorer';
|
||||
import { GitRevisionCodeLensProvider } from './gitRevisionCodeLensProvider';
|
||||
import { GitContextTracker, GitService } from './gitService';
|
||||
@@ -71,7 +73,7 @@ export async function activate(context: ExtensionContext) {
|
||||
|
||||
await context.globalState.update(WorkspaceState.GitLensVersion, gitlensVersion);
|
||||
|
||||
const git = new GitService(context, repoPath);
|
||||
const git = new GitService(repoPath);
|
||||
context.subscriptions.push(git);
|
||||
|
||||
const gitContextTracker = new GitContextTracker(git);
|
||||
@@ -84,6 +86,9 @@ export async function activate(context: ExtensionContext) {
|
||||
const annotationController = new AnnotationController(context, git, gitContextTracker);
|
||||
context.subscriptions.push(annotationController);
|
||||
|
||||
const codeLensController = new CodeLensController(context, git);
|
||||
context.subscriptions.push(codeLensController);
|
||||
|
||||
const currentLineController = new CurrentLineController(context, git, gitContextTracker, annotationController);
|
||||
context.subscriptions.push(currentLineController);
|
||||
|
||||
@@ -92,6 +97,7 @@ export async function activate(context: ExtensionContext) {
|
||||
// const explorer = new GitExplorer(context, git);
|
||||
// context.subscriptions.push(window.registerTreeDataProvider('gitlens.gitExplorer', explorer));
|
||||
|
||||
context.subscriptions.push(window.registerTreeDataProvider('gitlens.fileHistoryExplorer', new FileHistoryExplorer(context, git)));
|
||||
context.subscriptions.push(window.registerTreeDataProvider('gitlens.stashExplorer', new StashExplorer(context, git)));
|
||||
|
||||
context.subscriptions.push(commands.registerTextEditorCommand('gitlens.computingFileAnnotations', () => { }));
|
||||
@@ -134,7 +140,7 @@ export async function activate(context: ExtensionContext) {
|
||||
context.subscriptions.push(new StashApplyCommand(git));
|
||||
context.subscriptions.push(new StashDeleteCommand(git));
|
||||
context.subscriptions.push(new StashSaveCommand(git));
|
||||
context.subscriptions.push(new ToggleCodeLensCommand(git));
|
||||
context.subscriptions.push(new ToggleCodeLensCommand(codeLensController));
|
||||
|
||||
// Constantly over my data cap so stop collecting initialized event
|
||||
// Telemetry.trackEvent('initialized', Objects.flatten(cfg, 'config', true));
|
||||
|
||||
@@ -7,6 +7,7 @@ import * as path from 'path';
|
||||
export interface IStatusFormatOptions extends IFormatOptions {
|
||||
tokenOptions?: {
|
||||
file?: Strings.ITokenOptions;
|
||||
filePath?: Strings.ITokenOptions;
|
||||
path?: Strings.ITokenOptions;
|
||||
};
|
||||
}
|
||||
@@ -18,6 +19,11 @@ export class StatusFileFormatter extends Formatter<IGitStatusFile, IStatusFormat
|
||||
return this._padOrTruncate(file, this._options.tokenOptions!.file);
|
||||
}
|
||||
|
||||
get filePath() {
|
||||
const filePath = GitStatusFile.getFormattedPath(this._item);
|
||||
return this._padOrTruncate(filePath, this._options.tokenOptions!.filePath);
|
||||
}
|
||||
|
||||
get path() {
|
||||
const directory = GitStatusFile.getFormattedDirectory(this._item, false);
|
||||
return this._padOrTruncate(directory, this._options.tokenOptions!.file);
|
||||
|
||||
@@ -40,7 +40,7 @@ export class GitStatusFile implements IGitStatusFile {
|
||||
}
|
||||
|
||||
getFormattedPath(separator: string = Strings.pad(GlyphChars.Dot, 2, 2)): string {
|
||||
return GitUri.getFormattedPath(this.fileName, separator);
|
||||
return GitStatusFile.getFormattedPath(this, separator);
|
||||
}
|
||||
|
||||
getOcticon() {
|
||||
@@ -57,6 +57,10 @@ export class GitStatusFile implements IGitStatusFile {
|
||||
? `${directory} ${Strings.pad(GlyphChars.ArrowLeft, 1, 1)} ${status.originalFileName}`
|
||||
: directory;
|
||||
}
|
||||
|
||||
static getFormattedPath(status: IGitStatusFile, separator: string = Strings.pad(GlyphChars.Dot, 2, 2)): string {
|
||||
return GitUri.getFormattedPath(status.fileName, separator);
|
||||
}
|
||||
}
|
||||
|
||||
const statusOcticonsMap = {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
'use strict';
|
||||
import { Functions, Iterables, Objects } from './system';
|
||||
import { Disposable, Event, EventEmitter, ExtensionContext, FileSystemWatcher, languages, Location, Position, Range, TextDocument, TextDocumentChangeEvent, TextEditor, Uri, workspace } from 'vscode';
|
||||
import { Disposable, Event, EventEmitter, FileSystemWatcher, Location, Position, Range, TextDocument, TextDocumentChangeEvent, TextEditor, Uri, workspace } from 'vscode';
|
||||
import { IConfig } from './configuration';
|
||||
import { CommandContext, DocumentSchemes, ExtensionKey, GlyphChars, setCommandContext } from './constants';
|
||||
import { DocumentSchemes, ExtensionKey, GlyphChars } from './constants';
|
||||
import { Git, GitAuthor, GitBlame, GitBlameCommit, GitBlameLine, GitBlameLines, GitBlameParser, GitBranch, GitCommit, GitDiff, GitDiffChunkLine, GitDiffParser, GitLog, GitLogCommit, GitLogParser, GitRemote, GitStash, GitStashParser, GitStatus, GitStatusFile, GitStatusParser, IGit, setDefaultEncoding } from './git/git';
|
||||
import { GitUri, IGitCommitInfo, IGitUriData } from './git/gitUri';
|
||||
import { GitCodeLensProvider } from './gitCodeLensProvider';
|
||||
import { Logger } from './logger';
|
||||
import * as fs from 'fs';
|
||||
import * as ignore from 'ignore';
|
||||
@@ -90,8 +89,6 @@ export class GitService extends Disposable {
|
||||
private _uriCache: Map<string, UriCacheEntry>;
|
||||
|
||||
config: IConfig;
|
||||
private _codeLensProvider: GitCodeLensProvider | undefined;
|
||||
private _codeLensProviderDisposable: Disposable | undefined;
|
||||
private _disposable: Disposable | undefined;
|
||||
private _gitignore: Promise<ignore.Ignore | undefined>;
|
||||
private _repoWatcher: FileSystemWatcher | undefined;
|
||||
@@ -99,7 +96,7 @@ export class GitService extends Disposable {
|
||||
|
||||
static EmptyPromise: Promise<GitBlame | GitDiff | GitLog | undefined> = Promise.resolve(undefined);
|
||||
|
||||
constructor(private context: ExtensionContext, public repoPath: string) {
|
||||
constructor(public repoPath: string) {
|
||||
super(() => this.dispose());
|
||||
|
||||
this._gitCache = new Map();
|
||||
@@ -118,10 +115,6 @@ export class GitService extends Disposable {
|
||||
dispose() {
|
||||
this._disposable && this._disposable.dispose();
|
||||
|
||||
this._codeLensProviderDisposable && this._codeLensProviderDisposable.dispose();
|
||||
this._codeLensProviderDisposable = undefined;
|
||||
this._codeLensProvider = undefined;
|
||||
|
||||
this._cacheDisposable && this._cacheDisposable.dispose();
|
||||
this._cacheDisposable = undefined;
|
||||
|
||||
@@ -146,30 +139,7 @@ export class GitService extends Disposable {
|
||||
|
||||
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
|
||||
|
||||
const codeLensChanged = !Objects.areEquivalent(cfg.codeLens, this.config && this.config.codeLens);
|
||||
const advancedChanged = !Objects.areEquivalent(cfg.advanced, this.config && this.config.advanced);
|
||||
|
||||
if (codeLensChanged) {
|
||||
Logger.log('CodeLens config changed; resetting CodeLens provider');
|
||||
if (cfg.codeLens.enabled && (cfg.codeLens.recentChange.enabled || cfg.codeLens.authors.enabled)) {
|
||||
if (this._codeLensProvider) {
|
||||
this._codeLensProvider.reset();
|
||||
}
|
||||
else {
|
||||
this._codeLensProvider = new GitCodeLensProvider(this.context, this);
|
||||
this._codeLensProviderDisposable = languages.registerCodeLensProvider(GitCodeLensProvider.selector, this._codeLensProvider);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this._codeLensProviderDisposable && this._codeLensProviderDisposable.dispose();
|
||||
this._codeLensProviderDisposable = undefined;
|
||||
this._codeLensProvider = undefined;
|
||||
}
|
||||
|
||||
setCommandContext(CommandContext.CanToggleCodeLens, cfg.codeLens.recentChange.enabled || cfg.codeLens.authors.enabled);
|
||||
}
|
||||
|
||||
if (advancedChanged) {
|
||||
if (!Objects.areEquivalent(cfg.advanced, this.config && this.config.advanced)) {
|
||||
if (cfg.advanced.caching.enabled) {
|
||||
this._cacheDisposable && this._cacheDisposable.dispose();
|
||||
|
||||
@@ -264,9 +234,6 @@ export class GitService extends Disposable {
|
||||
}
|
||||
|
||||
private _fireGitCacheChangeCore() {
|
||||
// Refresh the code lenses
|
||||
this._codeLensProvider && this._codeLensProvider.reset();
|
||||
|
||||
this._onDidChangeGitCache.fire();
|
||||
}
|
||||
|
||||
@@ -1053,19 +1020,6 @@ export class GitService extends Disposable {
|
||||
return Git.stash_save(repoPath, message, unstagedOnly);
|
||||
}
|
||||
|
||||
toggleCodeLens(editor: TextEditor) {
|
||||
if (!this.config.codeLens.recentChange.enabled && !this.config.codeLens.authors.enabled) return;
|
||||
|
||||
Logger.log(`toggleCodeLens()`);
|
||||
if (this._codeLensProviderDisposable) {
|
||||
this._codeLensProviderDisposable.dispose();
|
||||
this._codeLensProviderDisposable = undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
this._codeLensProviderDisposable = languages.registerCodeLensProvider(GitCodeLensProvider.selector, new GitCodeLensProvider(this.context, this));
|
||||
}
|
||||
|
||||
static getGitPath(gitPath?: string): Promise<IGit> {
|
||||
return Git.getGitPath(gitPath);
|
||||
}
|
||||
|
||||
@@ -10,15 +10,15 @@ export class BranchHistoryNode extends ExplorerNode {
|
||||
|
||||
readonly resourceType: ResourceType = 'branch-history';
|
||||
|
||||
constructor(public readonly branch: GitBranch, uri: GitUri, context: ExtensionContext, git: GitService) {
|
||||
super(uri, context, git);
|
||||
}
|
||||
constructor(public readonly branch: GitBranch, uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||
super(uri);
|
||||
}
|
||||
|
||||
async getChildren(): Promise<CommitNode[]> {
|
||||
const log = await this.git.getLogForRepo(this.uri.repoPath!, this.branch.name);
|
||||
if (log === undefined) return [];
|
||||
|
||||
return [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.context, this.git))];
|
||||
return [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.git.config.gitExplorer.commitFormat, this.context, this.git))];
|
||||
}
|
||||
|
||||
getTreeItem(): TreeItem {
|
||||
|
||||
@@ -9,9 +9,9 @@ export class BranchesNode extends ExplorerNode {
|
||||
|
||||
readonly resourceType: ResourceType = 'branches';
|
||||
|
||||
constructor(uri: GitUri, context: ExtensionContext, git: GitService) {
|
||||
super(uri, context, git);
|
||||
}
|
||||
constructor(uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||
super(uri);
|
||||
}
|
||||
|
||||
async getChildren(): Promise<BranchHistoryNode[]> {
|
||||
const branches = await this.git.getBranches(this.uri.repoPath!);
|
||||
|
||||
@@ -9,8 +9,8 @@ export class CommitFileNode extends ExplorerNode {
|
||||
|
||||
readonly resourceType: ResourceType = 'commit-file';
|
||||
|
||||
constructor(public readonly status: IGitStatusFile, public commit: GitCommit, private template: string, context: ExtensionContext, git: GitService) {
|
||||
super(new GitUri(Uri.file(path.resolve(commit.repoPath, status.fileName)), { repoPath: commit.repoPath, fileName: status.fileName, sha: commit.sha }), context, git);
|
||||
constructor(public readonly status: IGitStatusFile, public commit: GitCommit, private template: string, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||
super(new GitUri(Uri.file(path.resolve(commit.repoPath, status.fileName)), { repoPath: commit.repoPath, fileName: status.fileName, sha: commit.sha }));
|
||||
}
|
||||
|
||||
getChildren(): Promise<ExplorerNode[]> {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
import { Iterables } from '../system';
|
||||
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
|
||||
import { Command, ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
|
||||
import { Commands, DiffWithPreviousCommandArgs } from '../commands';
|
||||
import { CommitFileNode } from './commitFileNode';
|
||||
import { ExplorerNode, ResourceType } from './explorerNode';
|
||||
import { CommitFormatter, GitCommit, GitService, GitUri } from '../gitService';
|
||||
@@ -9,12 +10,13 @@ export class CommitNode extends ExplorerNode {
|
||||
|
||||
readonly resourceType: ResourceType = 'commit';
|
||||
|
||||
constructor(public readonly commit: GitCommit, context: ExtensionContext, git: GitService) {
|
||||
super(new GitUri(commit.uri, commit), context, git);
|
||||
this.commit = commit;
|
||||
constructor(public readonly commit: GitCommit, private template: string, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||
super(new GitUri(commit.uri, commit));
|
||||
}
|
||||
|
||||
async getChildren(): Promise<ExplorerNode[]> {
|
||||
if (this.commit.type === 'file') Promise.resolve([]);
|
||||
|
||||
const log = await this.git.getLogForRepo(this.commit.repoPath, this.commit.sha, 1);
|
||||
if (log === undefined) return [];
|
||||
|
||||
@@ -25,14 +27,40 @@ export class CommitNode extends ExplorerNode {
|
||||
}
|
||||
|
||||
getTreeItem(): TreeItem {
|
||||
const label = CommitFormatter.fromTemplate(this.git.config.gitExplorer.commitFormat, this.commit, this.git.config.defaultDateFormat);
|
||||
const item = new TreeItem(CommitFormatter.fromTemplate(this.template, this.commit, this.git.config.defaultDateFormat));
|
||||
if (this.commit.type === 'file') {
|
||||
item.collapsibleState = TreeItemCollapsibleState.None;
|
||||
item.command = this.getCommand();
|
||||
item.contextValue = 'commit-file';
|
||||
}
|
||||
else {
|
||||
item.collapsibleState = TreeItemCollapsibleState.Collapsed;
|
||||
item.contextValue = this.resourceType;
|
||||
}
|
||||
|
||||
const item = new TreeItem(label, TreeItemCollapsibleState.Collapsed);
|
||||
item.contextValue = this.resourceType;
|
||||
item.iconPath = {
|
||||
dark: this.context.asAbsolutePath('images/dark/icon-commit.svg'),
|
||||
light: this.context.asAbsolutePath('images/light/icon-commit.svg')
|
||||
};
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
getCommand(): Command | undefined {
|
||||
return {
|
||||
title: 'Compare File with Previous',
|
||||
command: Commands.DiffWithPrevious,
|
||||
arguments: [
|
||||
new GitUri(this.uri, this.commit),
|
||||
{
|
||||
commit: this.commit,
|
||||
line: 0,
|
||||
showOptions: {
|
||||
preserveFocus: true,
|
||||
preview: true
|
||||
}
|
||||
} as DiffWithPreviousCommandArgs
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
'use strict';
|
||||
import { Command, Event, ExtensionContext, TreeItem } from 'vscode';
|
||||
import { GitService, GitUri } from '../gitService';
|
||||
import { Command, Event, TreeItem, TreeItemCollapsibleState } from 'vscode';
|
||||
import { GitUri } from '../gitService';
|
||||
|
||||
export declare type ResourceType = 'status' | 'branches' | 'repository' | 'branch-history' | 'file-history' | 'stash-history' | 'commit' | 'stash-commit' | 'commit-file';
|
||||
export declare type ResourceType = 'text' | 'status' | 'branches' | 'repository' | 'branch-history' | 'file-history' | 'stash-history' | 'commit' | 'stash-commit' | 'commit-file';
|
||||
|
||||
export abstract class ExplorerNode {
|
||||
|
||||
abstract readonly resourceType: ResourceType;
|
||||
|
||||
constructor(public readonly uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) { }
|
||||
constructor(public readonly uri: GitUri) { }
|
||||
|
||||
abstract getChildren(): ExplorerNode[] | Promise<ExplorerNode[]>;
|
||||
abstract getTreeItem(): TreeItem | Promise<TreeItem>;
|
||||
@@ -20,4 +20,23 @@ export abstract class ExplorerNode {
|
||||
onDidChangeTreeData?: Event<ExplorerNode>;
|
||||
|
||||
refresh?(): void;
|
||||
}
|
||||
|
||||
export class TextExplorerNode extends ExplorerNode {
|
||||
|
||||
readonly resourceType: ResourceType = 'text';
|
||||
|
||||
constructor(private text: string) {
|
||||
super(new GitUri());
|
||||
}
|
||||
|
||||
getChildren(): ExplorerNode[] | Promise<ExplorerNode[]> {
|
||||
return [];
|
||||
}
|
||||
|
||||
getTreeItem(): TreeItem | Promise<TreeItem> {
|
||||
const item = new TreeItem(this.text, TreeItemCollapsibleState.None);
|
||||
item.contextValue = this.resourceType;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
89
src/views/fileHistoryExplorer.ts
Normal file
89
src/views/fileHistoryExplorer.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
'use strict';
|
||||
// import { Arrays } from '../system';
|
||||
import { commands, Event, EventEmitter, ExtensionContext, TextEditor, TreeDataProvider, TreeItem, Uri, window } from 'vscode';
|
||||
import { Commands, DiffWithPreviousCommandArgs, openEditor, OpenFileInRemoteCommandArgs } from '../commands';
|
||||
import { UriComparer } from '../comparers';
|
||||
import { CommitNode, ExplorerNode, FileHistoryNode, TextExplorerNode } from './explorerNodes';
|
||||
import { GitService, GitUri } from '../gitService';
|
||||
|
||||
export * from './explorerNodes';
|
||||
|
||||
export class FileHistoryExplorer implements TreeDataProvider<ExplorerNode> {
|
||||
|
||||
private _node?: ExplorerNode;
|
||||
|
||||
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>();
|
||||
public get onDidChangeTreeData(): Event<ExplorerNode> {
|
||||
return this._onDidChangeTreeData.event;
|
||||
}
|
||||
|
||||
constructor(private context: ExtensionContext, private git: GitService) {
|
||||
commands.registerCommand('gitlens.fileHistoryExplorer.refresh', this.refresh, this);
|
||||
commands.registerCommand('gitlens.fileHistoryExplorer.openChanges', this.openChanges, this);
|
||||
commands.registerCommand('gitlens.fileHistoryExplorer.openFile', this.openFile, this);
|
||||
commands.registerCommand('gitlens.fileHistoryExplorer.openFileRevision', this.openFileRevision, this);
|
||||
commands.registerCommand('gitlens.fileHistoryExplorer.openFileInRemote', this.openFileInRemote, this);
|
||||
commands.registerCommand('gitlens.fileHistoryExplorer.openFileRevisionInRemote', this.openFileRevisionInRemote, this);
|
||||
|
||||
context.subscriptions.push(window.onDidChangeActiveTextEditor(this.onActiveEditorChanged, this));
|
||||
|
||||
this._node = this.getRootNode(window.activeTextEditor);
|
||||
}
|
||||
|
||||
async getTreeItem(node: ExplorerNode): Promise<TreeItem> {
|
||||
return node.getTreeItem();
|
||||
}
|
||||
|
||||
async getChildren(node?: ExplorerNode): Promise<ExplorerNode[]> {
|
||||
if (this._node === undefined) return [new TextExplorerNode('No active file')];
|
||||
if (node === undefined) return this._node.getChildren();
|
||||
return node.getChildren();
|
||||
}
|
||||
|
||||
private getRootNode(editor: TextEditor | undefined): ExplorerNode | undefined {
|
||||
if (window.visibleTextEditors.length === 0) return undefined;
|
||||
if (editor === undefined) return this._node;
|
||||
|
||||
const uri = this.git.getGitUriForFile(editor.document.uri) || new GitUri(editor.document.uri, { repoPath: this.git.repoPath, fileName: editor.document.uri.fsPath });
|
||||
if (UriComparer.equals(uri, this._node && this._node.uri)) return this._node;
|
||||
|
||||
return new FileHistoryNode(uri, this.context, this.git);
|
||||
}
|
||||
|
||||
private onActiveEditorChanged(editor: TextEditor | undefined) {
|
||||
const node = this.getRootNode(editor);
|
||||
if (node === this._node) return;
|
||||
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
refresh(node?: ExplorerNode) {
|
||||
this._node = node || this.getRootNode(window.activeTextEditor);
|
||||
this._onDidChangeTreeData.fire();
|
||||
}
|
||||
|
||||
private openChanges(node: CommitNode) {
|
||||
const command = node.getCommand();
|
||||
if (command === undefined || command.arguments === undefined) return;
|
||||
|
||||
const [uri, args] = command.arguments as [Uri, DiffWithPreviousCommandArgs];
|
||||
args.showOptions!.preview = false;
|
||||
return commands.executeCommand(command.command, uri, args);
|
||||
}
|
||||
|
||||
private openFile(node: CommitNode) {
|
||||
return openEditor(node.uri, { preserveFocus: true, preview: false });
|
||||
}
|
||||
|
||||
private openFileRevision(node: CommitNode) {
|
||||
return openEditor(GitService.toGitContentUri(node.uri), { preserveFocus: true, preview: false });
|
||||
}
|
||||
|
||||
private async openFileInRemote(node: CommitNode) {
|
||||
return commands.executeCommand(Commands.OpenFileInRemote, node.commit.uri, { range: false } as OpenFileInRemoteCommandArgs);
|
||||
}
|
||||
|
||||
private async openFileRevisionInRemote(node: CommitNode) {
|
||||
return commands.executeCommand(Commands.OpenFileInRemote, new GitUri(node.commit.uri, node.commit), { range: false } as OpenFileInRemoteCommandArgs);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
import { Iterables } from '../system';
|
||||
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
|
||||
import { CommitNode } from './commitNode';
|
||||
import { ExplorerNode, ResourceType } from './explorerNode';
|
||||
import { ExplorerNode, ResourceType, TextExplorerNode } from './explorerNode';
|
||||
import { GitService, GitUri } from '../gitService';
|
||||
|
||||
export class FileHistoryNode extends ExplorerNode {
|
||||
@@ -10,15 +10,15 @@ export class FileHistoryNode extends ExplorerNode {
|
||||
static readonly rootType: ResourceType = 'file-history';
|
||||
readonly resourceType: ResourceType = 'file-history';
|
||||
|
||||
constructor(uri: GitUri, context: ExtensionContext, git: GitService) {
|
||||
super(uri, context, git);
|
||||
constructor(uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||
super(uri);
|
||||
}
|
||||
|
||||
async getChildren(): Promise<CommitNode[]> {
|
||||
async getChildren(): Promise<ExplorerNode[]> {
|
||||
const log = await this.git.getLogForFile(this.uri.repoPath, this.uri.fsPath, this.uri.sha);
|
||||
if (log === undefined) return [];
|
||||
if (log === undefined) return [new TextExplorerNode('No file history')];
|
||||
|
||||
return [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.context, this.git))];
|
||||
return [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.git.config.fileHistoryExplorer.commitFormat, this.context, this.git))];
|
||||
}
|
||||
|
||||
getTreeItem(): TreeItem {
|
||||
|
||||
@@ -11,8 +11,8 @@ export class RepositoryNode extends ExplorerNode {
|
||||
static readonly rootType: ResourceType = 'repository';
|
||||
readonly resourceType: ResourceType = 'repository';
|
||||
|
||||
constructor(uri: GitUri, context: ExtensionContext, git: GitService) {
|
||||
super(uri, context, git);
|
||||
constructor(uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||
super(uri);
|
||||
}
|
||||
|
||||
async getChildren(): Promise<ExplorerNode[]> {
|
||||
|
||||
@@ -13,8 +13,8 @@ export class StashCommitNode extends ExplorerNode {
|
||||
return this._onDidChangeTreeData.event;
|
||||
}
|
||||
|
||||
constructor(public readonly commit: GitStashCommit, context: ExtensionContext, git: GitService) {
|
||||
super(new GitUri(commit.uri, commit), context, git);
|
||||
constructor(public readonly commit: GitStashCommit, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||
super(new GitUri(commit.uri, commit));
|
||||
}
|
||||
|
||||
async getChildren(): Promise<CommitFileNode[]> {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
// import { Functions } from '../system';
|
||||
import { commands, Event, EventEmitter, ExtensionContext, TreeDataProvider, TreeItem, Uri } from 'vscode';
|
||||
import { Commands, DiffWithPreviousCommandArgs, openEditor } from '../commands';
|
||||
import { Commands, DiffWithPreviousCommandArgs, openEditor, OpenFileInRemoteCommandArgs } from '../commands';
|
||||
import { ExplorerNode, StashCommitNode, StashNode } from './explorerNodes';
|
||||
import { GitService, GitUri } from '../gitService';
|
||||
|
||||
@@ -10,7 +10,6 @@ export * from './explorerNodes';
|
||||
export class StashExplorer implements TreeDataProvider<ExplorerNode> {
|
||||
|
||||
private _node: ExplorerNode;
|
||||
// private _refreshDebounced: () => void;
|
||||
|
||||
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>();
|
||||
public get onDidChangeTreeData(): Event<ExplorerNode> {
|
||||
@@ -24,28 +23,12 @@ export class StashExplorer implements TreeDataProvider<ExplorerNode> {
|
||||
commands.registerCommand('gitlens.stashExplorer.openStashedFile', this.openStashedFile, this);
|
||||
commands.registerCommand('gitlens.stashExplorer.openFileInRemote', this.openFileInRemote, this);
|
||||
|
||||
context.subscriptions.push(this.git.onDidChangeRepo(reasons => {
|
||||
if (!reasons.includes('stash')) return;
|
||||
context.subscriptions.push(this.git.onDidChangeRepo(this.onRepoChanged, this));
|
||||
|
||||
this.refresh();
|
||||
}, this));
|
||||
|
||||
// this._refreshDebounced = Functions.debounce(this.refresh.bind(this), 250);
|
||||
|
||||
// const editor = window.activeTextEditor;
|
||||
|
||||
// const uri = (editor !== undefined && editor.document !== undefined)
|
||||
// ? new GitUri(editor.document.uri, { repoPath: git.repoPath, fileName: editor.document.uri.fsPath })
|
||||
// : new GitUri(Uri.file(git.repoPath), { repoPath: git.repoPath, fileName: git.repoPath });
|
||||
|
||||
const uri = new GitUri(Uri.file(git.repoPath), { repoPath: git.repoPath, fileName: git.repoPath });
|
||||
this._node = new StashNode(uri, this.context, this.git);
|
||||
this._node = this.getRootNode();
|
||||
}
|
||||
|
||||
async getTreeItem(node: ExplorerNode): Promise<TreeItem> {
|
||||
// if (node.onDidChangeTreeData !== undefined) {
|
||||
// node.onDidChangeTreeData(() => setTimeout(this._refreshDebounced, 1));
|
||||
// }
|
||||
return node.getTreeItem();
|
||||
}
|
||||
|
||||
@@ -54,10 +37,16 @@ export class StashExplorer implements TreeDataProvider<ExplorerNode> {
|
||||
return node.getChildren();
|
||||
}
|
||||
|
||||
// update(uri: GitUri) {
|
||||
// this._node = new StashNode(uri, this.context, this.git);
|
||||
// this.refresh();
|
||||
// }
|
||||
private getRootNode(): ExplorerNode {
|
||||
const uri = new GitUri(Uri.file(this.git.repoPath), { repoPath: this.git.repoPath, fileName: this.git.repoPath });
|
||||
return new StashNode(uri, this.context, this.git);
|
||||
}
|
||||
|
||||
private onRepoChanged(reasons: ('stash' | 'unknown')[]) {
|
||||
if (!reasons.includes('stash')) return;
|
||||
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this._onDidChangeTreeData.fire();
|
||||
@@ -81,6 +70,6 @@ export class StashExplorer implements TreeDataProvider<ExplorerNode> {
|
||||
}
|
||||
|
||||
private openFileInRemote(node: StashCommitNode) {
|
||||
return commands.executeCommand(Commands.OpenFileInRemote, node.commit.previousUri);
|
||||
return commands.executeCommand(Commands.OpenFileInRemote, node.commit.uri, { range: false } as OpenFileInRemoteCommandArgs);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
import { Iterables } from '../system';
|
||||
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
|
||||
import { ExplorerNode, ResourceType } from './explorerNode';
|
||||
import { ExplorerNode, ResourceType, TextExplorerNode } from './explorerNode';
|
||||
import { GitService, GitUri } from '../gitService';
|
||||
import { StashCommitNode } from './stashCommitNode';
|
||||
|
||||
@@ -10,13 +10,13 @@ export class StashNode extends ExplorerNode {
|
||||
static readonly rootType: ResourceType = 'stash-history';
|
||||
readonly resourceType: ResourceType = 'stash-history';
|
||||
|
||||
constructor(uri: GitUri, context: ExtensionContext, git: GitService) {
|
||||
super(uri, context, git);
|
||||
constructor(uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||
super(uri);
|
||||
}
|
||||
|
||||
async getChildren(): Promise<StashCommitNode[]> {
|
||||
async getChildren(): Promise<ExplorerNode[]> {
|
||||
const stash = await this.git.getStashList(this.uri.repoPath!);
|
||||
if (stash === undefined) return [];
|
||||
if (stash === undefined) return [new TextExplorerNode('No stashed changes')];
|
||||
|
||||
return [...Iterables.map(stash.commits.values(), c => new StashCommitNode(c, this.context, this.git))];
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ export class StatusNode extends ExplorerNode {
|
||||
|
||||
readonly resourceType: ResourceType = 'status';
|
||||
|
||||
constructor(uri: GitUri, context: ExtensionContext, git: GitService) {
|
||||
super(uri, context, git);
|
||||
}
|
||||
constructor(uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||
super(uri);
|
||||
}
|
||||
|
||||
async getChildren(): Promise<ExplorerNode[]> {
|
||||
return [];
|
||||
|
||||
Reference in New Issue
Block a user