3 Commits

Author SHA1 Message Date
Eric Amodio
6b9fc3f9d2 Preps v4.0.0-alpha.2 2017-06-05 19:05:20 -04:00
Eric Amodio
5af70fd2bf Adds welcome message for first-time users 2017-06-05 19:04:29 -04:00
Eric Amodio
cecd3524b8 Major refactor/rework -- many new features and breaking changes
Adds all-new, beautiful, highly customizable and themeable, file blame annotations
Adds all-new configurability and themeability to the current line blame annotations
Adds all-new configurability to the status bar blame information
Adds all-new configurability over which commands are added to which menus via the `gitlens.advanced.menus` setting
Adds better configurability over where Git code lens will be shown -- both by default and per language
Adds an all-new `changes` (diff) hover annotation to the current line - provides instant access to the line's previous version
Adds `Toggle Line Blame Annotations` command (`gitlens.toggleLineBlame`) - toggles the current line blame annotations on and off
Adds `Show Line Blame Annotations` command (`gitlens.showLineBlame`) - shows the current line blame annotations
Adds `Toggle File Blame Annotations` command (`gitlens.toggleFileBlame`) - toggles the file blame annotations on and off
Adds `Show File Blame Annotations` command (`gitlens.showFileBlame`) - shows the file blame annotations
Adds `Open File in Remote` command (`gitlens.openFileInRemote`) to the `editor/title` context menu
Adds `Open Repo in Remote` command (`gitlens.openRepoInRemote`) to the `editor/title` context menu
Changes the position of the `Open File in Remote` command (`gitlens.openFileInRemote`) in the context menus - now in the `navigation` group
Changes the `Toggle Git Code Lens` command (`gitlens.toggleCodeLens`) to always toggle the Git code lens on and off
Removes the on-demand `trailing` file blame annotations -- didn't work out and just ended up with a ton of visual noise
Removes `Toggle Blame Annotations` command (`gitlens.toggleBlame`) - replaced by the `Toggle File Blame Annotations` command (`gitlens.toggleFileBlame`)
Removes `Show Blame Annotations` command (`gitlens.showBlame`) - replaced by the `Show File Blame Annotations` command (`gitlens.showFileBlame`)
2017-06-05 19:04:18 -04:00
157 changed files with 3817 additions and 7200 deletions

View File

@@ -1,13 +1,13 @@
{
"editor.insertSpaces": true,
"files.exclude": {
"**/node_modules": true,
"**/out": true
"node_modules": true,
"out": true
},
"files.trimTrailingWhitespace": true,
"search.exclude": {
"**/node_modules": true,
"**/out": true
"node_modules": true,
"out": true
},
"javascript.format.insertSpaceAfterFunctionKeywordForAnonymousFunctions": false,
"typescript.tsdk": "./node_modules/typescript/lib" // we want to use the TS server from our node_modules folder to control its version

25
.vscode/tasks.json vendored
View File

@@ -9,18 +9,13 @@
// A task runner that calls a custom npm script that compiles the extension.
{
"version": "2.0.0",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
},
"showOutput": "silent",
"tasks": [
{
"label": "compile",
"type": "npm",
"script": "compile",
"group": "build",
"taskName": "compile",
"command": "npm run compile --silent",
"isBuildCommand": true,
"isShellCommand": true,
"problemMatcher": [
"$tsc",
{
@@ -30,17 +25,19 @@
]
},
{
"type": "npm",
"script": "lint",
"taskName": "lint",
"command": "npm run lint --silent",
"isShellCommand": true,
"problemMatcher": {
"base": "$tslint5",
"fileLocation": "relative"
}
},
{
"type": "npm",
"script": "watch",
"taskName": "watch",
"command": "npm run watch --silent",
"isBackground": true,
"isShellCommand": true,
"problemMatcher": "$tsc-watch"
}
]

View File

@@ -1,6 +1,4 @@
!images/dark/**
!images/light/**
!images/gitlens-icon.png
!images/*.svg
images/**
.vscode/**
.vscode-test/**

View File

@@ -4,135 +4,16 @@ 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
## 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
- Adds automatic disabling of the current line blame annotations when starting a debug session and will restore them when the debug session ends -- can still be manually toggled via the `Toggle Line Blame Annotations` command (`gitlens.toggleLineBlame`)
## 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
## 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 the `gitlens.theme.annotations.file.hover.separateLines` configuration setting
## Fixed
- Fixes jumpiness when opening a diff to a certain line
## [4.3.3] - 2017-07-28
## Added
- Adds progress indicator for when computing annotations takes a while
## Changed
- Optimizes performance of the providing blame annotations, especially for large files (saw a 3.5x improvement on some files)
## Fixed
- Fixes [#107](https://github.com/eamodio/vscode-gitlens/issues/107) - Double-byte characters break blame layout (still requires proper font support)
## [4.3.2] - 2017-07-20
## Fixed
- Fixes [#118](https://github.com/eamodio/vscode-gitlens/issues/118) - GitLens stopped working on latest insiders build -- thanks to [PR #121](https://github.com/eamodio/vscode-gitlens/pull/121) by Johannes Rieken ([@jrieken](https://github.com/jrieken))
## [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
## Changed
- Hides the `Git Stashes` explorer by default
## Fixed
- Fixes [#108](https://github.com/eamodio/vscode-gitlens/issues/108) - Option to remove stash explorer from the main explorer?
## [4.3.0] - 2017-07-03
## Added
- Adds `Git Stashes` view to the Explorer activity
![Git Stashes view](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-git-stashes.png)
- Shows all of the stashed changes in the repository
- Provides toolbar buttons to `Stash Changes` and `Refresh`
- Provides a context menu with `Apply Stashed Changes` and `Delete Stashed Changes` commands - both require a confirmation
- Expand each stash to quickly see the set of files changed, complete with status indicators for adds, changes, renames, and deletes
- Provides a context menu with `Open Changes`, `Open File`, `Open Stashed File`, `Open File in Remote`, and `Compare File with Working Tree` commands
## [4.2.0] - 2017-06-27
## Added
- Adds `Compare File with Revision...` command (`gitlens.diffWithRevision`) - compare the active file with the selected revision of the same file
- Adds `Open Changed Files` command (`gitlens.openChangedFiles`) to the source control group context menu
- Adds `Close Unchanged Files` command (`gitlens.closeUnchangedFiles`) to the source control group context menu
- Adds `Open File in Remote` command (`gitlens.openFileInRemote`) to the source control resource context menu
- Adds `Compare File with Revision...` command (`gitlens.diffWithRevision`) to the source control resource context menu
- Adds `Show File History` command (`gitlens.showQuickFileHistory`) to the source control resource context menu
## Changed
- Renames `Compare File with...` command to `Compare File with Branch...`
- Renames `Open Line Commit in Remote` command to `Open Commit in Remote`
- Renames `Show Line Commit Details` command to `Show Commit File Details`
- Updates the description of `gitlens.blame.line.enabled` to be clearer about its behavior
- Updates the description of `gitlens.codeLens.enabled` to be clearer about its behavior
### Fixed
- Fixes [#103](https://github.com/eamodio/vscode-gitlens/issues/103) - Toggle file blame annotations disables line blame annotations if line blame annotations are off by default
- Fixes another infinite loop in the `Close Unchanged Files` command
## [4.1.4] - 2017-06-25
## Changed
- Optimizes performance of the `Compare with Previous` commands - also avoids trying to focus a line if we don't have one
### Fixed
- Fixes `changes` (diff) hover not showing the correct previous line (for real this time)
- Attempts to fix [#99](https://github.com/eamodio/vscode-gitlens/issues/99) - undo/redo spawns too many git processes
## [4.1.3] - 2017-06-20
### Fixed
- Fixes `changes` (diff) hover not showing the correct previous line when showing recent changes annotations of the whole-file
## [4.1.2] - 2017-06-15
### Fixed
- Fixes [#96](https://github.com/eamodio/vscode-gitlens/issues/96) - External diff command can be unintentionally triggered
## [4.1.1] - 2017-06-13
### Added
- Adds an `alt` command to the `Toggle File Blame Annotations` command button, which when you hold down `alt` and click it will execute the `Toggle Recent File Changes Annotations` command instead
### Fixed
- Fixes missing `Toggle File Blame Annotations` command icon
## [4.1.0] - 2017-06-13
### Added
- Adds all-new recent changes annotations of the whole-file - annotates and highlights all of lines changed in the most recent commit
- Can customize the [layout](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens#file-recent-changes-annotation-settings), as well as the [theme](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens#theme-settings)
- Adds `Toggle Recent File Changes Annotations` command (`gitlens.toggleFileRecentChanges`) - toggles the recent changes annotations on and off
- Adds ability to press `Escape` to quickly toggle any whole-file annotations off
- Improves performance
- Optimized git output parsing to increase speed and dramatically reduce memory usage
- Defers diff chunk parsing until it is actually required
- Adds `gitlens.defaultDateFormat` setting to specify how all absolute dates will be formatted by default
### Fixed
- Fixes excessive memory usage when parsing diffs
- Fixes extra newline in multiline commit messages
- Fixes (again) [#33](https://github.com/eamodio/vscode-gitlens/issues/33) - Commit messages can causes markdown formatting in hovers
## [4.0.1] - 2017-06-09
### Fixed
- Fixes [#87](https://github.com/eamodio/vscode-gitlens/issues/87) - Can't open files in remote when using git@ urls (ssh)
## [4.0.0] - 2017-06-09
## [4.0.0-alpha.2] - 2017-06-05
### Added
- Adds all-new, beautiful, highly customizable and themeable, file blame annotations
- Can now fully customize the [layout and content](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens#file-blame-annotation-settings), as well as the [theme](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens#theme-settings)
- Can now fully customize the [layout and content](https://github.com/eamodio/vscode-gitlens/blob/develop/README.md#file-blame-annotation-settings), as well as the [theme](https://github.com/eamodio/vscode-gitlens/blob/develop/README.md#theme-settings)
- Adds all-new configurability and themeability to the current line blame annotations
- Can now fully customize the [layout and content](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens#line-blame-annotation-settings), as well as the [theme](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens#theme-settings)
- Can now fully customize the [layout and content](https://github.com/eamodio/vscode-gitlens/blob/develop/README.md#line-blame-annotation-settings), as well as the [theme](https://github.com/eamodio/vscode-gitlens/blob/develop/README.md#theme-settings)
- Adds all-new configurability to the status bar blame information
- Can now fully customize the [layout and content](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens#status-bar-settings)
- Adds all-new [configurability](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens#advanced-settings) over which commands are added to which menus via the `gitlens.advanced.menus` setting
- Adds better [configurability](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens#code-lens-settings) over where Git code lens will be shown -- both by default and per language
- Can now fully customize the [layout and content](https://github.com/eamodio/vscode-gitlens/blob/develop/README.md#status-bar-settings)
- Adds all-new [configurability](https://github.com/eamodio/vscode-gitlens/blob/develop/README.md#advanced-settings) over which commands are added to which menus via the `gitlens.advanced.menus` setting
- Adds better [configurability](https://github.com/eamodio/vscode-gitlens/blob/develop/README.md#code-lens-settings) over where Git code lens will be shown -- both by default and per language
- Adds an all-new `changes` (diff) hover annotation to the current line - provides instant access to the line's previous version
- Adds `Toggle Line Blame Annotations` command (`gitlens.toggleLineBlame`) - toggles the current line blame annotations on and off
- Adds `Show Line Blame Annotations` command (`gitlens.showLineBlame`) - shows the current line blame annotations
@@ -140,33 +21,17 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- Adds `Show File Blame Annotations` command (`gitlens.showFileBlame`) - shows the file blame annotations
- Adds `Open File in Remote` command (`gitlens.openFileInRemote`) to the `editor/title` context menu
- Adds `Open Repo in Remote` command (`gitlens.openRepoInRemote`) to the `editor/title` context menu
- Adds `gitlens.strings.*` settings to allow for the customization of certain strings displayed
- Adds `gitlens.theme.*` settings to allow for the theming of certain elements
- Adds `gitlens.advanced.telemetry.enabled` settings to explicitly opt-in or out of telemetry, but still ultimately honors the `telemetry.enableTelemetry` setting
- Adds ability to suppress most warning messages - which can be re-enabled using the `Reset Suppressed Warnings` command (`gitlens.resetSuppressedWarnings`)
### Changed
- (BREAKING) Almost all of the GitLens settings have either been renamed, removed, or otherwise changed - see the [README](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens#extension-settings)`
- Changes the positioning of the Git code lens to try to be at the end of any other code lens on the same line
- (BREAKING) Almost all of the GitLens settings have either been renamed, removed, or otherwise changed - see the [README](https://github.com/eamodio/vscode-gitlens/blob/develop/README.md#extension-settings)`
- Changes the position of the `Open File in Remote` command (`gitlens.openFileInRemote`) in the context menus - now in the `navigation` group
- Changes the `Toggle Git Code Lens` command (`gitlens.toggleCodeLens`) to always toggle the Git code lens on and off
- Changes the default of `gitlens.advanced.toggleWhitespace.enabled` back to `true`, but automatically disables whitespace toggling if whitespace rendering is not on
### Removed
- Removes the on-demand `trailing` file blame annotations -- didn't work out and just ended up with a ton of visual noise
- Removes `Toggle Blame Annotations` command (`gitlens.toggleBlame`) - replaced by the `Toggle File Blame Annotations` command (`gitlens.toggleFileBlame`)
- Removes `Show Blame Annotations` command (`gitlens.showBlame`) - replaced by the `Show File Blame Annotations` command (`gitlens.showFileBlame`)
### Fixed
- Fixes [#81](https://github.com/eamodio/vscode-gitlens/issues/81) - Current line annotation feels too sticky
- Fixes [#83](https://github.com/eamodio/vscode-gitlens/issues/83) - Calling "close unchanged files" results in no new files being openable
- Fixes issues with the zone.js monkey patching done by application insights (telemetry) - disables all the monkey patching
- Fixes issue with `Open Branch in Remote` & `Open Repository in Remote` not showing when there are no open editors
## [3.6.1] - 2017-06-07
### Fixed
- Fixes issues with the zone.js monkey patching done by application insights (telemetry) - disables all the monkey patching
## [3.6.0] - 2017-06-02
### Added
- Adds diff information (the line's previous version) into the active line hover
@@ -259,7 +124,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
## [3.4.5] - 2017-04-13
### Added
- Completely overhauls the [GitLens documentation](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens) and messaging -- make sure to check it out to see all the powerful features GitLen provides!
- Completely overhauls the [GitLens documentation](https://github.com/eamodio/vscode-gitlens/blob/master/README.md) and messaging -- make sure to check it out to see all the powerful features GitLen provides!
- Adds `gitlens.blame.annotation.activeLineDarkColor` & `gitlens.blame.annotation.activeLineLightColor` settings to control the colors of the active line blame annotation
### Changed

170
README.md
View File

@@ -1,43 +1,36 @@
[![](https://vsmarketplacebadge.apphb.com/version/eamodio.gitlens.svg)](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens)
[![](https://vsmarketplacebadge.apphb.com/installs/eamodio.gitlens.svg)](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens)
[![](https://vsmarketplacebadge.apphb.com/rating/eamodio.gitlens.svg)](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens)
[![Chat at https://vscode-gitlens.slack.com/](https://raw.githubusercontent.com/eamodio/vscode-gitlens/develop/images/chat-badge.png)](https://join.slack.com/t/vscode-gitlens/shared_invite/MjIxOTgxNDE3NzM0LTE1MDE2Nzk1MTgtMjkwMmZjMzcxNQ)
[![Chat at https://gitter.im/vscode-gitlens/Lobby](https://badges.gitter.im/vscode-gitlens/Lobby.svg)](https://gitter.im/vscode-gitlens/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
# GitLens
GitLens **supercharges** the built-in Visual Studio Code Git capabilities. It helps you to **visualize code authorship** at a glance via Git blame annotations and code lens, **seamlessly navigate and explore** the history of a file or branch, **gain valuable insights** via powerful comparison commands, and so much more.
GitLens **supercharges** the built-in Visual Studio Code Git capabilities. It helps you to **visualize code authorship** at a glance via Git blame annotations and code lens, **seamlessly navigate and explore** the history of a file or branch, **gain valuable insights** via powerful comparision commands, and so much more.
GitLens provides an unobtrusive blame annotation at the end of the current line, a status bar item showing the commit information (author and date, by default) of the current line, code lens showing the most recent commit and # of authors of the file and/or code block, and many commands for exploring commits and histories, comparing and navigating revisions, stash access, repository status, and more. GitLens is also [highly customizable](#extension-settings) to meet your specific needs — find code lens intrusive or the current line blame annotation distracting — no problem, it is easy to [turn them off or change how they behave](#extension-settings).
### Preview — featuring blame annotations, code lens, status bar details, quick pick menus for navigation and exploration, compare with previous, and more
![GitLens preview](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/gitlens-preview.gif)
## Previews
#### Featuring code lens, file blame annotations, and navigation and exploration via quick pick menus
![GitLens preview 1](https://raw.githubusercontent.com/eamodio/vscode-git-codelens/master/images/gitlens-preview1.gif)
#### Featuring current line blame annotation and hovers, status bar commit details, quick pick menus, compare with previous, and more
![GitLens preview 2](https://raw.githubusercontent.com/eamodio/vscode-git-codelens/master/images/gitlens-preview2.gif)
## Features
### Git Blame Annotations
#### Git Blame Annotations
- Adds an unobtrusive, highly [customizable](#line-blame-annotation-settings) and [themeable](#theme-settings), **Git blame annotation** to the end of the current line ([optional](#line-blame-annotation-settings), on by default)
![Line Blame Annotation](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-line-blame-annotation.png)
- Contains the author, date, and message of the line's most recent commit, by [default](#line-blame-annotation-settings)
- Adds a `details` hover annotation to the current line annotation, which provides more commit details ([optional](#line-blame-annotation-settings), on by default)
- Adds a `changes` (diff) hover annotation to the current line annotation, which provides **instant** access to the line's previous version ([optional](#line-blame-annotation-settings), on by default)
![Line Blame Annotations](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-line-blame-annotations.png)
- Also adds a `details` hover annotation to the current line annotation which provides more commit details ([optional](#line-blame-annotation-settings), on by default)
- Also adds a `changes` (diff) hover annotation to the current line annotation which provides **instant** access to the line's previous version ([optional](#line-blame-annotation-settings), on by default)
- Adds on-demand, beautiful, highly [customizable](#file-blame-annotation-settings) and [themeable](#theme-settings), **Git blame annotations** of the whole file
![File Blame Annotation](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-file-blame-annotations.png)
- Choose between `gutter` (default) and `hover` [annotation styles](#file-blame-annotation-settings)
- Contains the commit message and date, by [default](#file-blame-annotation-settings)
- Adds a `details` hover annotation to the line's annotation, which provides more commit details ([optional](#file-blame-annotation-settings), on by default)
- Adds a `heatmap` (age) indicator to the gutter annotations (on right edge by [default](#file-blame-annotation-settings)), which provides an easy, at-a-glance way to tell the age of a line ([optional](#file-blame-annotation-settings), on by default)
- Indicator ranges from bright yellow (newer) to dark brown (older)
- Press `Escape` to quickly toggle the annotations off
- Also adds a `details` hover annotation to the line's annotation which provides more commit details ([optional](#file-blame-annotation-settings), on by default)
- Adds [customizable](#status-bar-settings) **blame information** about the current line to the **status bar** ([optional](#status-bar-settings), on by default)
![Status Bar Blame](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-status-bar.png)
- Contains the commit author and date, by [default](#status-bar-settings)
- Clicking the status bar item will, by [default](#status-bar-settings), show a **commit details quick pick menu** with commands for comparing, navigating and exploring commits, and more
- Provides [customizable](#status-bar-settings) click behavior — choose between one of the following
@@ -56,21 +49,9 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
- Adds a `Toggle Line Blame Annotations` command (`gitlens.toggleLineBlame`) to toggle the current line blame annotations on and off
- Also adds a `Show Line Blame Annotations` command (`gitlens.showLineBlame`)
### Git Recent Changes Annotations
- Adds on-demand, [customizable](#file-recent-changes-annotation-settings) and [themeable](#theme-settings), **recent changes annotations** of the whole file
- Highlights all of lines changed in the most recent commit
- Adds a `details` hover annotation to each line, which provides more commit details ([optional](#file-blame-annotation-settings), on by default)
- Adds a `changes` (diff) hover annotation to each line, which provides **instant** access to the line's previous version ([optional](#file-recent-changes-annotation-settings), on by default)
- Press `Escape` to quickly toggle the annotations off
- Adds `Toggle Recent File Changes Annotations` command (`gitlens.toggleFileRecentChanges`) to toggle the recent changes annotations on and off
### Git Code Lens
#### Git Code Lens
- Adds **code lens** to the top of the file and on code blocks ([optional](#code-lens-settings), on by default)
![Git Code Lens](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-code-lens.png)
- **Recent Change** — author and date of the most recent commit for the file or code block
- Clicking the code lens will, by [default](#code-lens-settings), show a **commit file details quick pick menu** with commands for comparing, navigating and exploring commits, and more
- **Authors** — number of authors of the file or code block and the most prominent author (if there is more than one)
@@ -87,15 +68,15 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
- Adds a `Toggle Git Code Lens` command (`gitlens.toggleCodeLens`) with a shortcut of `shift+alt+b` to toggle the code lens on and off
### Powerful Comparison Tools
#### Powerful Comparison Tools
- Effortlessly navigate between comparisons via the `alt+,` and `alt+.` shortcut keys to go back and forth through a file's revisions
- Effortlessly navigate between comparisions via the `alt+,` and `alt+.` shortcut keys to go back and forth through a file's revisions
- Provides easy access to the following comparison commands via the `Command Palette` as well as in context via the many provided quick pick menus
- Adds a `Directory Compare` command (`gitlens.diffDirectory`) to open the configured Git difftool to compare directories between branches
- Adds a `Compare File with Branch...` command (`gitlens.diffWithBranch`) to compare the active file with the same file on the selected branch
- Adds a `Compare File with...` command (`gitlens.diffWithBranch`) to compare the active file with the same file on the selected branch
- Adds a `Compare File with Next Commit` command (`gitlens.diffWithNext`) with a shortcut of `alt+.` to compare the active file/diff with the next commit revision
@@ -103,35 +84,23 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
- Adds a `Compare Line Commit with Previous` command (`gitlens.diffLineWithPrevious`) with a shortcut of `shift+alt+,` to compare the active file/diff with the previous line commit revision
- Adds a `Compare File with Revision...` command (`gitlens.diffWithRevision`) to compare the active file with the selected revision of the same file
- Adds a `Compare File with Working Tree` command (`gitlens.diffWithWorking`) with a shortcut of `shift+alt+w` to compare the most recent commit revision of the active file/diff with the working tree
- Adds a `Compare Line Commit with Working Tree` command (`gitlens.diffLineWithWorking`) with a shortcut of `alt+w` to compare the commit revision of the active line with the working tree
### Navigate and Explore
- Adds a `Git Stashes` explorer to the Explorer activity ([optional](#git-stashes-explorer-settings), off by default)
![Git Stashes explorer](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-git-stashes.png)
- Shows all of the stashed changes in the repository
- Provides toolbar buttons to `Stash Changes` and `Refresh`
- Provides a context menu with `Apply Stashed Changes` and `Delete Stashed Changes` commands — both require a confirmation
- Expand each stash to quickly see the set of files changed, complete with status indicators for adds, changes, renames, and deletes
- Provides a context menu with `Open Changes`, `Open File`, `Open Stashed File`, `Open File in Remote`, and `Compare File with Working Tree` commands
#### Navigate and Explore
- Adds a `Search Commits` command (`gitlens.showCommitSearch`) with a shortcut of `alt+/` to search for commits by message, author, file(s), or commit id
- Adds commands to open files, commits, branches, and the repository in the supported remote services, currently **BitBucket, GitHub, GitLab, and Visual Studio Team Services** — only available if a Git upstream service is configured in the repository
- `Open Branch in Remote` command (`gitlens.openBranchInRemote`) — opens the current branch commits in the supported remote service
- `Open Commit in Remote` command (`gitlens.openCommitInRemote`) — opens the commit revision of the active line in the supported remote service
- `Open Line Commit in Remote` command (`gitlens.openCommitInRemote`) — opens the commit revision of the active line in the supported remote service
- `Open File in Remote` command (`gitlens.openFileInRemote`) — opens the active file/revision in the supported remote service
- `Open Repository in Remote` command (`gitlens.openRepoInRemote`) — opens the repository in the supported remote service
- Adds a `Show Current Branch History` command (`gitlens.showQuickRepoHistory`) with a shortcut of `shift+alt+h` to show a paged **branch history quick pick menu** of the current branch for exploring its commit history
![Branch History Quick Pick Menu](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-branch-history.png)
![Branch History Quick Pick Menu](https://raw.githubusercontent.com/eamodio/vscode-git-codelens/master/images/screenshot-branch-history.png)
- Provides entries to `Show Commit Search` and `Open Branch in <remote-service>` when available
- Navigate back to the previous quick pick menu via `alt+left arrow`, if available
@@ -142,7 +111,7 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
- Adds a `Show File History` command (`gitlens.showQuickFileHistory`) to show a paged **file history quick pick menu** of the active file for exploring its commit history
![File History Quick Pick Menu](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-file-history.png)
![File History Quick Pick Menu](https://raw.githubusercontent.com/eamodio/vscode-git-codelens/master/images/screenshot-file-history.png)
- Provides entries to `Show Branch History` and `Open File in <remote-service>` when available
- Navigate back to the previous quick pick menu via `alt+left arrow`, if available
@@ -150,17 +119,18 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
- Adds a `Show Commit Details` command (`gitlens.showQuickCommitDetails`) to show a **commit details quick pick menu** of the most recent commit of the active file
![Commit Details Quick Pick Menu](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-commit-details.png)
![Commit Details Quick Pick Menu](https://raw.githubusercontent.com/eamodio/vscode-git-codelens/master/images/screenshot-commit-details.png)
- Quickly see the set of files changed in the commit, complete with status indicators for adds, changes, renames, and deletes
- Provides entries to `Copy to Clipboard`, `Directory Compare`, `Open Changed Files`, `Open File in <remote-service>` when available, and more
- Navigate back to the previous quick pick menu via `alt+left arrow`, if available
- Use the `alt+right arrow` shortcut on an entry to execute it without closing the quick pick menu, if possible — commands that open windows outside of VS Code will still close the quick pick menu unless [`"gitlens.advanced.quickPick.closeOnFocusOut": false`](#extension-settings) is set
- Use the `alt+right arrow` shortcut on a file entry in the `Changed Files` section to preview the comparison of the current revision with the previous one
- Use the `alt+right arrow` shortcut on a file entry in the `Changed Files` section to preview the current revision of the while leaving the quick pick menu open
- NOTE: Once [vscode issue #10568](https://github.com/Microsoft/vscode/issues/10568) is resolved this will change to preview the comparison of the current revision with the previous one
- Adds a `Show Commit File Details` command (`gitlens.showQuickCommitFileDetails`) with a shortcut of `alt+c` to show a **file commit details quick pick menu** of the most recent commit of the active file
- Adds a `Show Line Commit Details` command (`gitlens.showQuickCommitFileDetails`) with a shortcut of `alt+c` to show a **file commit details quick pick menu** of the most recent commit of the active file
![Commit File Details Quick Pick Menu](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-commit-file-details.png)
![Line Commit Details Quick Pick Menu](https://raw.githubusercontent.com/eamodio/vscode-git-codelens/master/images/screenshot-commit-file-details.png)
- Provides entries to `Show Commit Details`, `Show File History`, `Compare File with...`, `Copy to Clipboard`, `Open File`, `Open File in <remote-service>` when available, and more
- Navigate back to the previous quick pick menu via `alt+left arrow`, if available
@@ -168,33 +138,35 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
- Adds a `Show Repository Status` command (`gitlens.showQuickRepoStatus`) with a shortcut of `alt+s` to show a **repository status quick pick menu** for visualizing the current repository status
![Repository Status Quick Pick Menu](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-repo-status.png)
![Repository Status Quick Pick Menu](https://raw.githubusercontent.com/eamodio/vscode-git-codelens/master/images/screenshot-repo-status.png)
- Quickly see upstream status (if an Git upstream is configured) — complete with ahead and behind information
- If you are ahead of the upstream, an entry will be shown with the number of commits ahead. Choosing it will show a limited **branch history quick pick menu** containing just the commits ahead of the upstream
- If you are behind the upstream, an entry will be shown with the number of commits behind. Choosing it will show a limited **branch history quick pick menu** containing just the commits behind the upstream
- If you are ahead of the upstream, an entry will be shown with the number of commits ahead. Chosing it will show a limited **branch history quick pick menu** containing just the commits ahead of the upstream
- If you are behind the upstream, an entry will be shown with the number of commits behind. Chosing it will show a limited **branch history quick pick menu** containing just the commits behind the upstream
- Quickly see all working changes, both staged and unstaged, complete with status indicators for adds, changes, renames, and deletes
- Provides entries to `Show Stashed Changes`, `Open Changed Files`, and `Close Unchanged Files`
- Use the `alt+right arrow` shortcut on an entry to execute it without closing the quick pick menu, if possible — commands that open windows outside of VS Code will still close the quick pick menu unless [`"gitlens.advanced.quickPick.closeOnFocusOut": false`](#extension-settings) is set
- Use the `alt+right arrow` shortcut on a file entry in the `Staged Files` or `Unstaged Files` sections to preview the comparison of the working file with the previous revision
- Use the `alt+right arrow` shortcut on a file entry in the `Staged Files` or `Unstaged Files` sections to preview the working file while leaving the quick pick menu open
- NOTE: Once [vscode issue #10568](https://github.com/Microsoft/vscode/issues/10568) is resolved this will change to preview the comparison of the working file with the previous revision
- Adds a `Show Stashed Changes` command (`gitlens.showQuickStashList`) to show a **stashed changes quick pick menu** for exploring your repository stash history
![Stashed Changes Quick Pick Menu](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-stash-list.png)
![Stashed Changes Quick Pick Menu](https://raw.githubusercontent.com/eamodio/vscode-git-codelens/master/images/screenshot-stash-list.png)
- Provides entries to `Stash Changes`
- Navigate back to the previous quick pick menu via `alt+left arrow`, if available
- Choosing a stash entry shows a **stash details quick pick menu** which is very similar to the **commit details quick pick menu** above
- Chosing a stash entry shows a **stash details quick pick menu** which is very similar to the **commit details quick pick menu** above
![Stash Details Quick Pick Menu](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-stash-details.png)
![Stash Details Quick Pick Menu](https://raw.githubusercontent.com/eamodio/vscode-git-codelens/master/images/screenshot-stash-details.png)
- Quickly see the set of files changed in the stash, complete with status indicators for adds, changes, renames, and deletes
- Provides entries to `Copy Message to Clipboard`, `Directory Compare`, and `Open Changed Files`
- Provides entries to `Apply Stashed Changes` and `Delete Stashed Changes` — both require a confirmation
- Navigate back to the previous quick pick menu via `alt+left arrow`, if available
- Use the `alt+right arrow` shortcut on an entry to execute it without closing the quick pick menu, if possible — commands that open windows outside of VS Code will still close the quick pick menu unless [`"gitlens.advanced.quickPick.closeOnFocusOut": false`](#extension-settings) is set
- Use the `alt+right arrow` shortcut on a file entry in the `Changed Files` section to preview the comparison of the current revision with the previous one
- Use the `alt+right arrow` shortcut on a file entry in the `Changed Files` section to preview the current revision of the while leaving the quick pick menu open
- NOTE: Once [vscode issue #10568](https://github.com/Microsoft/vscode/issues/10568) is resolved this will change to preview the comparison of the current revision with the previous one
- Adds a `Show Last Opened Quick Pick` command (`gitlens.showLastQuickPick`) with a shortcut of `alt+-` to quickly get back to where you were when the last GitLens quick pick menu closed
@@ -204,11 +176,11 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
- Adds a `Open Blame History Explorer` command (`gitlens.showBlameHistory`) to show a **blame history explorer** (peek style) to visualize the blame history of a file or code block
- Likely to be deprecated in a future release, add your voice to [#66](https://github.com/eamodio/vscode-gitlens/issues/66) if you feel it should not be removed
### And More
#### And More
- Adds a `Copy Commit ID to Clipboard` command (`gitlens.copyShaToClipboard`) to copy the commit id (sha) of the active line to the clipboard or from the most recent commit to the current branch, if there is no active editor
- Adds a `Copy Commit ID to Clipboard` command (`gitlens.copyShaToClipboard`) to copy the commit id (sha) of the active line to the clipboard
- Adds a `Copy Commit Message to Clipboard` command (`gitlens.copyMessageToClipboard`) to copy the commit message of the active line to the clipboard or from the most recent commit to the current branch, if there is no active editor
- Adds a `Copy Commit Message to Clipboard` command (`gitlens.copyMessageToClipboard`) to copy the commit message of the active line to the clipboard
- Adds a `Open Changed Files` command (`gitlens.openChangedFiles`) to open any files with working tree changes
@@ -230,7 +202,6 @@ GitLens is highly customizable and provides many configuration settings to allow
|Name | Description
|-----|------------
|`gitlens.defaultDateFormat`|Specifies how all absolute dates will be formatted by default\nSee https://momentjs.com/docs/#/displaying/format/ for valid formats
|`gitlens.insiders`|Opts into the insiders channel -- provides access to upcoming features
|`gitlens.outputLevel`|Specifies how much (if any) output will be sent to the GitLens output channel
@@ -240,14 +211,14 @@ GitLens is highly customizable and provides many configuration settings to allow
|Name | Description
|-----|------------
|`gitlens.blame.file.annotationType`|Specifies the type of blame annotations that will be shown for the current file<br />`gutter` - adds an annotation to the beginning of each line<br />`hover` - shows annotations when hovering over each line
|`gitlens.blame.file.annotationType`|Specifies the type of blame annotations that will be shown for the current file. `gutter` - adds an annotation to the beginning of each line. `hover` - shows annotations when hovering over each line
|`gitlens.blame.file.lineHighlight.enabled`|Specifies whether or not to highlight lines associated with the current line
|`gitlens.blame.file.lineHighlight.locations`|Specifies where the associated line highlights will be shown<br />`gutter` - adds a gutter glyph<br />`line` - adds a full-line highlight background color<br />`overviewRuler` - adds a decoration to the overviewRuler (scroll bar)
|`gitlens.annotations.file.gutter.format`|Specifies the format of the gutter blame annotations<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.annotations.file.gutter.dateFormat`)<br />`${authorAgo}` - commit author, relative commit date<br />See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting
|`gitlens.annotations.file.gutter.dateFormat`|Specifies how to format absolute dates (using the `${date}` token) in gutter blame annotations<br />See https://momentjs.com/docs/#/displaying/format/ for valid formats
|`gitlens.blame.file.lineHighlight.locations`|Specifies where the associated line highlights will be shown. `gutter` - adds a gutter glyph. `line` - adds a full-line highlight background color. `overviewRuler` - adds a decoration to the overviewRuler (scroll bar)
|`gitlens.annotations.file.gutter.format`|Specifies the format of the gutter blame annotations. Available tokens: `${id}` - commit id, `${author}` - commit author, `${message}` - commit message, `${ago}` - relative commit date (e.g. 1 day ago), `${date}` - formatted commit date (format specified by `gitlens.annotations.file.dateFormat`), `${authorAgo}` - commit author, relative commit date
|`gitlens.annotations.file.gutter.dateFormat`|Specifies how to format absolute dates (using the `${date}` token) in gutter blame annotations. See https://momentjs.com/docs/#/displaying/format/ for valid formats
|`gitlens.annotations.file.gutter.compact`|Specifies whether or not to compact (deduplicate) matching adjacent gutter blame annotations
|`gitlens.annotations.file.gutter.heatmap.enabled`|Specifies whether or not to provide a heatmap indicator in the gutter blame annotations
|`gitlens.annotations.file.gutter.heatmap.location`|Specifies where the heatmap indicators will be shown in the gutter blame annotations<br />`left` - adds a heatmap indicator on the left edge of the gutter blame annotations<br />`right` - adds a heatmap indicator on the right edge of the gutter blame annotations
|`gitlens.annotations.file.gutter.heatmap.location`|Specifies where the heatmap indicators will be shown in the gutter blame annotations. `left` - adds a heatmap indicator on the left edge of the gutter blame annotations. `right` - adds a heatmap indicator on the right edge of the gutter blame annotations
|`gitlens.annotations.file.gutter.hover.details`|Specifies whether or not to provide a commit details hover annotation over the gutter blame annotations
|`gitlens.annotations.file.gutter.hover.wholeLine`|Specifies whether or not to trigger hover annotations over the whole line
|`gitlens.annotations.file.hover.heatmap.enabled`|Specifies whether or not to provide heatmap indicators on the left edge of each line
@@ -257,74 +228,52 @@ GitLens is highly customizable and provides many configuration settings to allow
|Name | Description
|-----|------------
|`gitlens.blame.line.enabled`|Specifies whether or not to provide a blame annotation for the current line, by default<br />Use the `gitlens.toggleLineBlame` command to toggle the annotations on and off for the current session
|`gitlens.blame.line.annotationType`|Specifies the type of blame annotations that will be shown for the current line<br />`trailing` - adds an annotation to the end of the current line<br />`hover` - shows annotations when hovering over the current line
|`gitlens.annotations.line.trailing.format`|Specifies the format of the trailing blame annotations<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.annotations.line.trailing.dateFormat`)<br />`${authorAgo}` - commit author, relative commit date<br />See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting
|`gitlens.annotations.line.trailing.dateFormat`|Specifies how to format absolute dates (using the `${date}` token) in trailing blame annotations<br />See https://momentjs.com/docs/#/displaying/format/ for valid formats
|`gitlens.blame.line.enabled`|Specifies whether or not to provide a blame annotation for the current line
|`gitlens.blame.line.annotationType`|Specifies the type of blame annotations that will be shown for the current line. `trailing` - adds an annotation to the end of the current line. `hover` - shows annotations when hovering over the current line
|`gitlens.annotations.line.trailing.format`|Specifies the format of the trailing blame annotations. Available tokens: `${id}` - commit id, `${author}` - commit author, `${message}` - commit message, `${ago}` - relative commit date (e.g. 1 day ago), `${date}` - formatted commit date (format specified by `gitlens.annotations.currentLine.dateFormat`), `${authorAgo}` - commit author, relative commit date
|`gitlens.annotations.line.trailing.dateFormat`|Specifies how to format absolute dates (using the `${date}` token) in trailing blame annotations. See https://momentjs.com/docs/#/displaying/format/ for valid formats
|`gitlens.annotations.line.trailing.hover.details`|Specifies whether or not to provide a commit details hover annotation over the trailing blame annotations
|`gitlens.annotations.line.trailing.hover.changes`|Specifies whether or not to provide a changes (diff) hover annotation over the trailing blame annotations
|`gitlens.annotations.line.trailing.hover.wholeLine`|Specifies whether or not to trigger hover annotations over the whole line
|`gitlens.annotations.line.hover.details`|Specifies whether or not to provide a commit details hover annotation for the current line
|`gitlens.annotations.line.hover.changes`|Specifies whether or not to provide a changes (diff) hover annotation for the current line
### File Recent Changes Annotation Settings
|Name | Description
|-----|------------
|`gitlens.recentChanges.file.lineHighlight.locations`|Specifies where the highlights of the recently changed lines will be shown<br />`gutter` - adds a gutter glyph<br />`line` - adds a full-line highlight background color<br />`overviewRuler` - adds a decoration to the overviewRuler (scroll bar)
|`gitlens.annotations.file.recentChanges.hover.details`|Specifies whether or not to provide a commit details hover annotation
|`gitlens.annotations.file.recentChanges.hover.changes`|Specifies whether or not to provide a changes (diff) hover annotation
|`gitlens.annotations.file.recentChanges.hover.wholeLine`|Specifies whether or not to trigger hover annotations over the whole line
### Code Lens Settings
|Name | Description
|-----|------------
|`gitlens.codeLens.enabled`|Specifies whether or not to provide any Git code lens, by default<br />Use the `gitlens.toggleCodeLens` command to toggle the Git code lens on and off for the current session
|`gitlens.codeLens.enabled`|Specifies whether or not to provide any Git code lens
|`gitlens.codeLens.recentChange.enabled`|Specifies whether or not to show a `recent change` code lens showing the author and date of the most recent commit for the file or code block
|`gitlens.codeLens.recentChange.command`|Specifies the command to be executed when the `recent change` code lens is clicked<br />`gitlens.toggleFileBlame` - toggles file blame annotations<br />`gitlens.showBlameHistory` - opens the blame history explorer<br />`gitlens.showFileHistory` - opens the file history explorer<br />`gitlens.diffWithPrevious` - compares the current committed file with the previous commit<br />`gitlens.showQuickCommitDetails` - shows a commit details quick pick<br />`gitlens.showQuickCommitFileDetails` - shows a commit file details quick pick<br />`gitlens.showQuickFileHistory` - shows a file history quick pick<br />`gitlens.showQuickRepoHistory` - shows a branch history quick pick
|`gitlens.codeLens.recentChange.command`|Specifies the command to be executed when the `recent change` code lens is clicked. `gitlens.toggleFileBlame` - toggles file blame annotations. `gitlens.showBlameHistory` - opens the blame history explorer. `gitlens.showFileHistory` - opens the file history explorer. `gitlens.diffWithPrevious` - compares the current committed file with the previous commit. `gitlens.showQuickCommitDetails` - shows a commit details quick pick. `gitlens.showQuickCommitFileDetails` - shows a commit file details quick pick. `gitlens.showQuickFileHistory` - shows a file history quick pick. `gitlens.showQuickRepoHistory` - shows a branch history quick pick
|`gitlens.codeLens.authors.enabled`|Specifies whether or not to show an `authors` code lens showing number of authors of the file or code block and the most prominent author (if there is more than one)
|`gitlens.codeLens.authors.command`|Specifies the command to be executed when the `authors` code lens is clicked<br />`gitlens.toggleFileBlame` - toggles file blame annotations<br />`gitlens.showBlameHistory` - opens the blame history explorer<br />`gitlens.showFileHistory` - opens the file history explorer<br />`gitlens.diffWithPrevious` - compares the current committed file with the previous commit<br />`gitlens.showQuickCommitDetails` - shows a commit details quick pick<br />`gitlens.showQuickCommitFileDetails` - shows a commit file details quick pick<br />`gitlens.showQuickFileHistory` - shows a file history quick pick<br />`gitlens.showQuickRepoHistory` - shows a branch history quick pick
|`gitlens.codeLens.locations`|Specifies where Git code lens will be shown in the document<br />`document` - adds code lens at the top of the document<br />`containers` - adds code lens at the start of container-like symbols (modules, classes, interfaces, etc)<br />`blocks` - adds code lens at the start of block-like symbols (functions, methods, properties, etc) lines<br />`custom` - adds code lens at the start of symbols contained in `gitlens.codeLens.locationCustomSymbols`
|`gitlens.codeLens.authors.command`|Specifies the command to be executed when the `authors` code lens is clicked. `gitlens.toggleFileBlame` - toggles file blame annotations. `gitlens.showBlameHistory` - opens the blame history explorer. `gitlens.showFileHistory` - opens the file history explorer. `gitlens.diffWithPrevious` - compares the current committed file with the previous commit. `gitlens.showQuickCommitDetails` - shows a commit details quick pick. `gitlens.showQuickCommitFileDetails` - shows a commit file details quick pick. `gitlens.showQuickFileHistory` - shows a file history quick pick. `gitlens.showQuickRepoHistory` - shows a branch history quick pick
|`gitlens.codeLens.locations`|Specifies where Git code lens will be shown in the document. `document` - adds code lens at the top of the document. `containers` - adds code lens at the start of container-like symbols (modules, classes, interfaces, etc). `blocks` - adds code lens at the start of block-like symbols (functions, methods, properties, etc) lines. `custom` - adds code lens at the start of symbols contained in `gitlens.codeLens.locationCustomSymbols`
|`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 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
### Status Bar Settings
|Name | Description
|-----|------------
|`gitlens.statusBar.enabled`|Specifies whether or not to provide blame information on the status bar
|`gitlens.statusBar.alignment`|Specifies the blame alignment in the status bar<br />`left` - align to the left, `right` - align to the right
|`gitlens.statusBar.command`|Specifies the command to be executed when the blame status bar item is clicked<br />`gitlens.toggleFileBlame` - toggles file blame annotations<br />`gitlens.showBlameHistory` - opens the blame history explorer<br />`gitlens.showFileHistory` - opens the file history explorer<br />`gitlens.diffWithPrevious` - compares the current line commit with the previous<br />`gitlens.diffWithWorking` - compares the current line commit with the working tree<br />`gitlens.toggleCodeLens` - toggles Git code lens<br />`gitlens.showQuickCommitDetails` - shows a commit details quick pick<br />`gitlens.showQuickCommitFileDetails` - shows a commit file details quick pick<br />`gitlens.showQuickFileHistory` - shows a file history quick pick<br />`gitlens.showQuickRepoHistory` - shows a branch history quick pick
|`gitlens.statusBar.format`|Specifies the format of the blame information on the status bar<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 />See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting
|`gitlens.statusBar.dateFormat`|Specifies the date format of absolute dates shown in the blame information on the status bar<br />See https://momentjs.com/docs/#/displaying/format/ for valid formats
### Strings Settings
|Name | Description
|-----|------------
|`gitlens.strings.codeLens.unsavedChanges.recentChangeAndAuthors`|Specifies the string to be shown in place of both the `recent change` and `authors` code lens when there are unsaved changes
|`gitlens.strings.codeLens.unsavedChanges.recentChangeOnly`|Specifies the string to be shown in place of the `recent change` code lens when there are unsaved changes
|`gitlens.strings.codeLens.unsavedChanges.authorsOnly`|Specifies the string to be shown in place of the `authors` code lens when there are unsaved changes
|`gitlens.statusBar.alignment`|Specifies the blame alignment in the status bar. `left` - align to the left, `right` - align to the right
|`gitlens.statusBar.format`|Specifies the format of the blame information on the status bar. Available tokens: `${id}` - commit id, `${author}` - commit author, `${message}` - commit message, `${ago}` - relative commit date (e.g. 1 day ago), `${date}` - formatted commit date (format specified by `gitlens.statusBar.dateFormat`)
|`gitlens.statusBar.command`|Specifies the command to be executed when the blame status bar item is clicked. `gitlens.toggleFileBlame` - toggles file blame annotations. `gitlens.showBlameHistory` - opens the blame history explorer. `gitlens.showFileHistory` - opens the file history explorer. `gitlens.diffWithPrevious` - compares the current line commit with the previous. `gitlens.diffWithWorking` - compares the current line commit with the working tree. `gitlens.toggleCodeLens` - toggles Git code lens. `gitlens.showQuickCommitDetails` - shows a commit details quick pick. `gitlens.showQuickCommitFileDetails` - shows a commit file details quick pick. `gitlens.showQuickFileHistory` - shows a file history quick pick. `gitlens.showQuickRepoHistory` - shows a branch history quick pick
|`gitlens.statusBar.format`|Specifies the format of the status bar blame information. Available tokens: `${id}` - commit id, `${author}` - commit author, `${message}` - commit message, `${ago}` - relative commit date (e.g. 1 day ago), `${date}` - formatted commit date (format specified by `gitlens.statusBar.dateFormat`), `${authorAgo}` - commit author, relative commit date
|`gitlens.statusBar.dateFormat`|Specifies the date format of absolute dates shown in the blame information on the status bar. See https://momentjs.com/docs/#/displaying/format/ for valid formats
### Theme Settings
|Name | Description
|-----|------------
|`gitlens.theme.annotations.file.gutter.separateLines`|Specifies whether or not gutter blame annotations will have line separators
|`gitlens.theme.annotations.file.gutter.separateLines`|Specifies whether or not gutter blame annotations will be separated by a small gap
|`gitlens.theme.annotations.file.gutter.dark.backgroundColor`|Specifies the dark theme background color of the gutter blame annotations
|`gitlens.theme.annotations.file.gutter.light.backgroundColor`|Specifies the light theme background color of the gutter blame annotations
|`gitlens.theme.annotations.file.gutter.dark.foregroundColor`|Specifies the dark theme foreground color of the gutter blame annotations
|`gitlens.theme.annotations.file.gutter.light.foregroundColor`|Specifies the light theme foreground color of the gutter blame annotations
|`gitlens.theme.annotations.file.gutter.dark.uncommittedForegroundColor`|Specifies the dark theme foreground color of an uncommitted line in the gutter blame annotations
|`gitlens.theme.annotations.file.gutter.light.uncommittedForegroundColor`|Specifies the light theme foreground color of an uncommitted line in the gutter blame annotations
|`gitlens.theme.annotations.file.hover.separateLines`|Specifies whether or not hover blame annotations will be separated by a small gap (if heatmap is enabled)
|`gitlens.theme.annotations.line.trailing.dark.backgroundColor`|Specifies the dark theme background color of the trailing blame annotation
|`gitlens.theme.annotations.line.trailing.light.backgroundColor`|Specifies the light theme background color of the trailing blame annotation
|`gitlens.theme.annotations.line.trailing.dark.foregroundColor`|Specifies the dark theme foreground color of the trailing blame annotation
@@ -339,7 +288,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
|`gitlens.advanced.caching.maxLines`|Specifies the threshold for caching larger documents
@@ -357,7 +305,5 @@ GitLens is highly customizable and provides many configuration settings to allow
A big thanks to the people that have contributed to this project:
- Peng Lyu ([@rebornix](https://github.com/rebornix)) — [contributions](https://github.com/eamodio/vscode-gitlens/commits?author=rebornix))
- Aurelio Ogliari ([@nobitagit](https://github.com/nobitagit)) — [contributions](https://github.com/eamodio/vscode-gitlens/commits?author=nobitagit)
- Johannes Rieken ([@jrieken](https://github.com/jrieken)) — [contributions](https://github.com/eamodio/vscode-gitlens/commits?author=jrieken))
- Zack Schuster ([@zackschuster](https://github.com/zackschuster)) — [contributions](https://github.com/eamodio/vscode-gitlens/commits?author=zackschuster)

View File

Before

Width:  |  Height:  |  Size: 312 B

After

Width:  |  Height:  |  Size: 312 B

View File

Before

Width:  |  Height:  |  Size: 313 B

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,88 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="92" height="20" xml:space="preserve">
<style type="text/css">
.white{fill:#FFF;}
.shadow{fill:#2e840e;}
</style>
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<clipPath id="a">
<rect width="92" height="20" rx="3" fill="#fff"/>
</clipPath>
<g clip-path="url(#a)">
<path fill="#555" d="M0 0h34v20H0z"/>
<path fill="#4c1" d="M34 0h58v20H34z"/>
<path fill="url(#b)" d="M0 0h92v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="17" y="15" fill="#010101" fill-opacity=".3">chat</text>
<text x="17" y="14">chat</text>
<g transform="scale(0.1) translate(340, -21)">
<path class="shadow" d="M263.5,105.5c3.9,1.7,4.2,3,1.1,8.8c-3.1,6-3.9,6.3-7.7,4.8c-4.8-2.1-11-3.6-15-3.6c-6.5,0-10.9,2.3-10.9,5.9
c0,11.7,37.4,5.4,37.4,30.4c0,12.6-10.8,21-27,21c-8.5,0-19-2.8-26.3-6.5c-3.6-1.8-3.8-2.9-0.7-8.9c2.7-5.3,3.6-5.8,7.5-4.2
c6.2,2.7,14,4.8,19.3,4.8c6,0,9.9-2.4,9.9-6c0-11.4-38.1-6-38.1-30.2c0-12.9,10.7-21.5,26.8-21.5
C247.4,100.2,256.9,102.5,263.5,105.5z"/>
<path class="shadow" d="M293.7,75.8V169c0,1.4-1.5,2.9-3.6,2.9h-9.8c-2.1,0-3.6-1.5-3.6-2.9V75.8c0-4.6,1.3-5,8.5-5
C293.4,70.7,293.7,71.3,293.7,75.8z"/>
<path class="shadow" d="M363.4,128.2v40.1c0,2.1-1.5,3.6-3.6,3.6h-9.7c-2.2,0-3.8-1.6-3.6-3.8l0.1-4.3c-5.3,5.8-12.8,8.9-20.3,8.9
c-14.6,0-24.4-8.5-24.4-21.1c0-13.4,11.1-22.5,27.7-22.5c6.3,0,12.1,1.1,16.8,3.1v-4.6c0-7.4-5.8-11.8-15.7-11.8
c-4.6,0-10.3,1.8-14.8,4.5c-3.5,2-4.3,1.8-8.1-3.8c-3.7-5.6-3.6-6.7,0-9c6.8-4.4,16.1-7.2,24.6-7.2
C351.4,100.2,363.4,110.6,363.4,128.2z M318.2,151.4c0,4.8,4,8,10.2,8c7.4,0,14.1-3.6,18-9.6v-6.3c-3.9-1.5-8.7-2.3-12.9-2.3
C324.3,141.2,318.2,145.5,318.2,151.4z"/>
<path class="shadow" d="M429.9,105.6c3.6,2.1,3.7,3.2-0.2,9.2c-3.7,5.7-4.3,6-8.2,4c-3-1.6-7.7-2.9-11.7-2.9
c-12.3,0-20.5,8.1-20.5,20.3c0,12.7,8.2,21.2,20.5,21.2c4.3,0,9.6-1.6,13.1-3.6c3.6-2.1,4.3-1.9,8.1,3.6c3.4,5.1,3.3,6.3,0.3,8.5
c-5.5,3.8-14.1,6.7-21.7,6.7c-22.7,0-37.9-14.6-37.9-36.4c0-21.7,15.2-36.1,38.1-36.1C416.6,100.2,424.8,102.6,429.9,105.6z"/>
<path class="shadow" d="M504.1,163.1c2.8,3.6,1.7,4.9-5.4,7.5c-7.2,2.6-8.2,2.5-10.8-0.9l-20.3-27.1l-9.1,8.8V169
c0,1.4-1.5,2.9-3.6,2.9H445c-2.1,0-3.6-1.5-3.6-2.9V75.8c0-4.6,1.3-5,8.5-5c8.2,0,8.5,0.6,8.5,5v53l27.8-26.7
c3.1-2.9,4.8-2.7,10.2,0.9c6,3.9,6.5,5,3.6,7.8L479.3,131L504.1,163.1z"/>
</g>
<g transform="scale(0.1) translate(340, -21)">
<rect x="115.9" y="126.3" transform="matrix(0.9482 -0.3176 0.3176 0.9482 -36.3582 46.5843)" class="shadow" width="17.6" height="17"/>
<g>
<rect x="115.9" y="126.3" transform="matrix(0.9482 -0.3176 0.3176 0.9482 -36.3582 46.5843)" class="shadow" width="17.6" height="17"/>
<path class="shadow" d="M182,117.5c-12.9-43-31.5-53-74.5-40.1s-53,31.5-40.1,74.5s31.5,53,74.5,40.1S194.9,160.5,182,117.5z
M160.3,145.4l-8.1,2.7l2.8,8.4c1.1,3.4-0.7,7.1-4.1,8.2c-0.7,0.2-1.5,0.4-2.2,0.3c-2.6-0.1-5.1-1.8-6-4.4l-2.8-8.4l-16.7,5.6
l2.8,8.4c1.1,3.4-0.7,7.1-4.1,8.2c-0.7,0.2-1.5,0.4-2.2,0.3c-2.6-0.1-5.1-1.8-6-4.4l-2.8-8.4l-8.1,2.7c-0.7,0.2-1.5,0.4-2.2,0.3
c-2.6-0.1-5.1-1.8-6-4.4c-1.1-3.4,0.7-7.1,4.1-8.2l8.1-2.7l-5.4-16.1l-8.1,2.7c-0.7,0.2-1.5,0.4-2.2,0.3c-2.6-0.1-5.1-1.8-6-4.4
c-1.1-3.4,0.7-7.1,4.1-8.2l8.1-2.7l-2.8-8.4c-1.1-3.4,0.7-7.1,4.1-8.2s7.1,0.7,8.2,4.1l2.8,8.4l16.7-5.6l-2.8-8.4
c-1.1-3.4,0.7-7.1,4.1-8.2s7.1,0.7,8.2,4.1l2.8,8.4l8.1-2.7c3.4-1.1,7.1,0.7,8.2,4.1c1.1,3.4-0.7,7.1-4.1,8.2l-8.1,2.7l5.4,16.1
l8.1-2.7c3.4-1.1,7.1,0.7,8.2,4.1C165.5,140.6,163.7,144.3,160.3,145.4z"/>
</g>
</g>
<g transform="scale(0.1) translate(340, -31)">
<path class="white" d="M263.5,105.5c3.9,1.7,4.2,3,1.1,8.8c-3.1,6-3.9,6.3-7.7,4.8c-4.8-2.1-11-3.6-15-3.6c-6.5,0-10.9,2.3-10.9,5.9
c0,11.7,37.4,5.4,37.4,30.4c0,12.6-10.8,21-27,21c-8.5,0-19-2.8-26.3-6.5c-3.6-1.8-3.8-2.9-0.7-8.9c2.7-5.3,3.6-5.8,7.5-4.2
c6.2,2.7,14,4.8,19.3,4.8c6,0,9.9-2.4,9.9-6c0-11.4-38.1-6-38.1-30.2c0-12.9,10.7-21.5,26.8-21.5
C247.4,100.2,256.9,102.5,263.5,105.5z"/>
<path class="white" d="M293.7,75.8V169c0,1.4-1.5,2.9-3.6,2.9h-9.8c-2.1,0-3.6-1.5-3.6-2.9V75.8c0-4.6,1.3-5,8.5-5
C293.4,70.7,293.7,71.3,293.7,75.8z"/>
<path class="white" d="M363.4,128.2v40.1c0,2.1-1.5,3.6-3.6,3.6h-9.7c-2.2,0-3.8-1.6-3.6-3.8l0.1-4.3c-5.3,5.8-12.8,8.9-20.3,8.9
c-14.6,0-24.4-8.5-24.4-21.1c0-13.4,11.1-22.5,27.7-22.5c6.3,0,12.1,1.1,16.8,3.1v-4.6c0-7.4-5.8-11.8-15.7-11.8
c-4.6,0-10.3,1.8-14.8,4.5c-3.5,2-4.3,1.8-8.1-3.8c-3.7-5.6-3.6-6.7,0-9c6.8-4.4,16.1-7.2,24.6-7.2
C351.4,100.2,363.4,110.6,363.4,128.2z M318.2,151.4c0,4.8,4,8,10.2,8c7.4,0,14.1-3.6,18-9.6v-6.3c-3.9-1.5-8.7-2.3-12.9-2.3
C324.3,141.2,318.2,145.5,318.2,151.4z"/>
<path class="white" d="M429.9,105.6c3.6,2.1,3.7,3.2-0.2,9.2c-3.7,5.7-4.3,6-8.2,4c-3-1.6-7.7-2.9-11.7-2.9
c-12.3,0-20.5,8.1-20.5,20.3c0,12.7,8.2,21.2,20.5,21.2c4.3,0,9.6-1.6,13.1-3.6c3.6-2.1,4.3-1.9,8.1,3.6c3.4,5.1,3.3,6.3,0.3,8.5
c-5.5,3.8-14.1,6.7-21.7,6.7c-22.7,0-37.9-14.6-37.9-36.4c0-21.7,15.2-36.1,38.1-36.1C416.6,100.2,424.8,102.6,429.9,105.6z"/>
<path class="white" d="M504.1,163.1c2.8,3.6,1.7,4.9-5.4,7.5c-7.2,2.6-8.2,2.5-10.8-0.9l-20.3-27.1l-9.1,8.8V169
c0,1.4-1.5,2.9-3.6,2.9H445c-2.1,0-3.6-1.5-3.6-2.9V75.8c0-4.6,1.3-5,8.5-5c8.2,0,8.5,0.6,8.5,5v53l27.8-26.7
c3.1-2.9,4.8-2.7,10.2,0.9c6,3.9,6.5,5,3.6,7.8L479.3,131L504.1,163.1z"/>
</g>
<g transform="scale(0.1) translate(340, -31)">
<rect x="115.9" y="126.3" transform="matrix(0.9482 -0.3176 0.3176 0.9482 -36.3582 46.5843)" class="white" width="17.6" height="17"/>
<g>
<rect x="115.9" y="126.3" transform="matrix(0.9482 -0.3176 0.3176 0.9482 -36.3582 46.5843)" class="white" width="17.6" height="17"/>
<path class="white" d="M182,117.5c-12.9-43-31.5-53-74.5-40.1s-53,31.5-40.1,74.5s31.5,53,74.5,40.1S194.9,160.5,182,117.5z
M160.3,145.4l-8.1,2.7l2.8,8.4c1.1,3.4-0.7,7.1-4.1,8.2c-0.7,0.2-1.5,0.4-2.2,0.3c-2.6-0.1-5.1-1.8-6-4.4l-2.8-8.4l-16.7,5.6
l2.8,8.4c1.1,3.4-0.7,7.1-4.1,8.2c-0.7,0.2-1.5,0.4-2.2,0.3c-2.6-0.1-5.1-1.8-6-4.4l-2.8-8.4l-8.1,2.7c-0.7,0.2-1.5,0.4-2.2,0.3
c-2.6-0.1-5.1-1.8-6-4.4c-1.1-3.4,0.7-7.1,4.1-8.2l8.1-2.7l-5.4-16.1l-8.1,2.7c-0.7,0.2-1.5,0.4-2.2,0.3c-2.6-0.1-5.1-1.8-6-4.4
c-1.1-3.4,0.7-7.1,4.1-8.2l8.1-2.7l-2.8-8.4c-1.1-3.4,0.7-7.1,4.1-8.2s7.1,0.7,8.2,4.1l2.8,8.4l16.7-5.6l-2.8-8.4
c-1.1-3.4,0.7-7.1,4.1-8.2s7.1,0.7,8.2,4.1l2.8,8.4l8.1-2.7c3.4-1.1,7.1,0.7,8.2,4.1c1.1,3.4-0.7,7.1-4.1,8.2l-8.1,2.7l5.4,16.1
l8.1-2.7c3.4-1.1,7.1,0.7,8.2,4.1C165.5,140.6,163.7,144.3,160.3,145.4z"/>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 93 93" xml:space="preserve">
<g>
<path fill="#F05133" d="M90,41.8L49.9,1.7c-2.3-2.3-6.1-2.3-8.4,0L33.2,10l10.6,10.6c2.5-0.8,5.3-0.3,7.2,1.7c2,2,2.5,4.8,1.7,7.3
l10.2,10.2c2.5-0.8,5.3-0.3,7.3,1.7c2.8,2.7,2.8,7.2,0,10s-7.2,2.8-10,0c-2.1-2.1-2.6-5.1-1.5-7.7l-9.5-9.5v25
c0.7,0.3,1.3,0.8,1.9,1.3c2.8,2.7,2.8,7.2,0,10c-2.8,2.7-7.2,2.7-10,0c-2.8-2.8-2.8-7.2,0-10c0.7-0.7,1.5-1.2,2.3-1.5V33.8
c-0.8-0.3-1.6-0.9-2.3-1.5c-2.1-2.1-2.6-5.1-1.5-7.7L29.2,14.2L1.7,41.7c-2.3,2.3-2.3,6.1,0,8.4l40.1,40.1c2.3,2.3,6.1,2.3,8.4,0
l39.9-39.9C92.4,47.9,92.4,44.1,90,41.8z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 795 B

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 93 93" xml:space="preserve">
<g>
<path fill="#FFFFFF" fill-opacity="0.74" d="M90,41.8L49.9,1.7c-2.3-2.3-6.1-2.3-8.4,0L33.2,10l10.6,10.6c2.5-0.8,5.3-0.3,7.2,1.7c2,2,2.5,4.8,1.7,7.3
l10.2,10.2c2.5-0.8,5.3-0.3,7.3,1.7c2.8,2.7,2.8,7.2,0,10s-7.2,2.8-10,0c-2.1-2.1-2.6-5.1-1.5-7.7l-9.5-9.5v25
c0.7,0.3,1.3,0.8,1.9,1.3c2.8,2.7,2.8,7.2,0,10c-2.8,2.7-7.2,2.7-10,0c-2.8-2.8-2.8-7.2,0-10c0.7-0.7,1.5-1.2,2.3-1.5V33.8
c-0.8-0.3-1.6-0.9-2.3-1.5c-2.1-2.1-2.6-5.1-1.5-7.7L29.2,14.2L1.7,41.7c-2.3,2.3-2.3,6.1,0,8.4l40.1,40.1c2.3,2.3,6.1,2.3,8.4,0
l39.9-39.9C92.4,47.9,92.4,44.1,90,41.8z">
<animate attributeName="fill" values="#FFFFFF;#F05133;#FFFFFF" dur="1s" repeatCount="indefinite"/>
</path>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 941 B

View File

@@ -1 +0,0 @@
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><title>Layer 1</title><rect height="11" width="3" y="3" x="7" fill="#C5C5C5"/><rect height="3" width="11" y="7" x="3" fill="#C5C5C5"/></svg>

Before

Width:  |  Height:  |  Size: 203 B

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="256" height="256" viewBox="0 0 14 16" xml:space="preserve">
<path fill="#C5C5C5" d="M10.86 7c-.45-1.72-2-3-3.86-3-1.86 0-3.41 1.28-3.86 3H0v2h3.14c.45 1.72 2 3 3.86 3 1.86 0 3.41-1.28 3.86-3H14V7h-3.14zM7 10.2c-1.22 0-2.2-.98-2.2-2.2 0-1.22.98-2.2 2.2-2.2 1.22 0 2.2.98 2.2 2.2 0 1.22-.98 2.2-2.2 2.2z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 480 B

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16">
<path d="M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3a2.98 2.98 0 0 1-2.107-.868 2.98 2.98 0 0 1-.873-2.111 3.004 3.004 0 0 1 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012L13.115 4.1 8.196 0H7.059v2.404A6.759 6.759 0 0 0 .938 9.125c0 1.809.707 3.508 1.986 4.782a6.707 6.707 0 0 0 4.784 1.988 6.758 6.758 0 0 0 6.75-6.75 6.741 6.741 0 0 0-1.007-3.536z" fill="#2D2D30"/>
<path d="M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4a3.986 3.986 0 0 1-2.817-1.164 3.987 3.987 0 0 1-1.163-2.815c0-2.206 1.794-4 4-4l.351.025v1.85S9.685 5.679 9.69 5.682l1.869-1.577-3.5-2.917v2.218l-.371-.03a5.75 5.75 0 0 0-4.055 9.826 5.75 5.75 0 0 0 9.826-4.056 5.725 5.725 0 0 0-.859-3.012z" fill="#C5C5C5"/>
</svg>

Before

Width:  |  Height:  |  Size: 987 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#3c8746" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
A
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#7F4E7E" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
C
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#692C77" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
C
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#9E121D" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
D
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#969696" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
I
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#1B80B2" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
M
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#CC6633" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
R
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#6C6C6C" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
U
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

View File

Before

Width:  |  Height:  |  Size: 815 B

After

Width:  |  Height:  |  Size: 815 B

View File

Before

Width:  |  Height:  |  Size: 814 B

After

Width:  |  Height:  |  Size: 814 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 93 93" xml:space="preserve">
<g>
<path fill="#F05133" d="M90,41.8L49.9,1.7c-2.3-2.3-6.1-2.3-8.4,0L33.2,10l10.6,10.6c2.5-0.8,5.3-0.3,7.2,1.7c2,2,2.5,4.8,1.7,7.3
l10.2,10.2c2.5-0.8,5.3-0.3,7.3,1.7c2.8,2.7,2.8,7.2,0,10s-7.2,2.8-10,0c-2.1-2.1-2.6-5.1-1.5-7.7l-9.5-9.5v25
c0.7,0.3,1.3,0.8,1.9,1.3c2.8,2.7,2.8,7.2,0,10c-2.8,2.7-7.2,2.7-10,0c-2.8-2.8-2.8-7.2,0-10c0.7-0.7,1.5-1.2,2.3-1.5V33.8
c-0.8-0.3-1.6-0.9-2.3-1.5c-2.1-2.1-2.6-5.1-1.5-7.7L29.2,14.2L1.7,41.7c-2.3,2.3-2.3,6.1,0,8.4l40.1,40.1c2.3,2.3,6.1,2.3,8.4,0
l39.9-39.9C92.4,47.9,92.4,44.1,90,41.8z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 795 B

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 93 93" xml:space="preserve">
<g>
<path fill="#000000" fill-opacity="0.6" d="M90,41.8L49.9,1.7c-2.3-2.3-6.1-2.3-8.4,0L33.2,10l10.6,10.6c2.5-0.8,5.3-0.3,7.2,1.7c2,2,2.5,4.8,1.7,7.3
l10.2,10.2c2.5-0.8,5.3-0.3,7.3,1.7c2.8,2.7,2.8,7.2,0,10s-7.2,2.8-10,0c-2.1-2.1-2.6-5.1-1.5-7.7l-9.5-9.5v25
c0.7,0.3,1.3,0.8,1.9,1.3c2.8,2.7,2.8,7.2,0,10c-2.8,2.7-7.2,2.7-10,0c-2.8-2.8-2.8-7.2,0-10c0.7-0.7,1.5-1.2,2.3-1.5V33.8
c-0.8-0.3-1.6-0.9-2.3-1.5c-2.1-2.1-2.6-5.1-1.5-7.7L29.2,14.2L1.7,41.7c-2.3,2.3-2.3,6.1,0,8.4l40.1,40.1c2.3,2.3,6.1,2.3,8.4,0
l39.9-39.9C92.4,47.9,92.4,44.1,90,41.8z">
<animate attributeName="fill" values="#000000;#F05133;#000000" dur="1s" repeatCount="indefinite"/>
</path>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 941 B

View File

@@ -1 +0,0 @@
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><title>Layer 1</title><rect height="11" width="3" y="3" x="7" fill="#424242"/><rect height="3" width="11" y="7" x="3" fill="#424242"/></svg>

Before

Width:  |  Height:  |  Size: 203 B

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="256" height="256" viewBox="0 0 14 16" xml:space="preserve">
<path fill="#6c6c6c" d="M10.86 7c-.45-1.72-2-3-3.86-3-1.86 0-3.41 1.28-3.86 3H0v2h3.14c.45 1.72 2 3 3.86 3 1.86 0 3.41-1.28 3.86-3H14V7h-3.14zM7 10.2c-1.22 0-2.2-.98-2.2-2.2 0-1.22.98-2.2 2.2-2.2 1.22 0 2.2.98 2.2 2.2 0 1.22-.98 2.2-2.2 2.2z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 480 B

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16">
<path d='M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3a2.98 2.98 0 0 1-2.107-.868 2.98 2.98 0 0 1-.873-2.111 3.004 3.004 0 0 1 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012L13.115 4.1 8.196 0H7.059v2.404A6.759 6.759 0 0 0 .938 9.125c0 1.809.707 3.508 1.986 4.782a6.707 6.707 0 0 0 4.784 1.988 6.758 6.758 0 0 0 6.75-6.75 6.741 6.741 0 0 0-1.007-3.536z' fill='#F6F6F6'/>
<path d='M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4a3.986 3.986 0 0 1-2.817-1.164 3.987 3.987 0 0 1-1.163-2.815c0-2.206 1.794-4 4-4l.351.025v1.85S9.685 5.679 9.69 5.682l1.869-1.577-3.5-2.917v2.218l-.371-.03a5.75 5.75 0 0 0-4.055 9.826 5.75 5.75 0 0 0 9.826-4.056 5.725 5.725 0 0 0-.859-3.012z' fill='#424242'/>
</svg>

Before

Width:  |  Height:  |  Size: 987 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#2d883e" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
A
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#9B4F96" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
C
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#682079" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
C
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#B9131A" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
D
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#969696" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
I
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#007ACC" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
M
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#CC6633" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
R
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,6 +0,0 @@
<svg width="14px" height="14px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect fill="#6C6C6C" x="0" y="0" width="100" height="100" rx="35" ry="35"/>
<text x="50" y="75" font-size="75" text-anchor="middle" style="font-family: Menlo, Monaco, Consolas, &quot;Droid Sans Mono&quot;, &quot;Inconsolata&quot;, &quot;Courier New&quot;, monospace, &quot;Droid Sans Fallback&quot;;" fill="white">
U
</text>
</svg>

Before

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

1333
package-lock.json generated

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -16,9 +16,9 @@ interface AutoCollectConsole {
}
interface AutoCollectExceptions {
constructor(client: Client): AutoCollectExceptions;
constructor(client:Client): AutoCollectExceptions;
isInitialized(): boolean;
enable(isEnabled: boolean): void;
enable(isEnabled:boolean): void;
}
interface AutoCollectPerformance {
@@ -348,7 +348,7 @@ 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?: {
trackMetric(name: string, value: number, count?:number, min?: number, max?: number, stdDev?: number, properties?: {
[key: string]: string;
}): void;
@@ -374,8 +374,7 @@ interface Client {
* @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;
[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.
@@ -504,11 +503,6 @@ interface ApplicationInsights {
*
*/
setOfflineMode(value: boolean, resentIntervall?: number): ApplicationInsights;
/**
*
*/
setAutoDependencyCorrelation(value: boolean): ApplicationInsights;
}
declare module "applicationinsights" {

View File

@@ -1,6 +1,5 @@
'use strict';
import { Functions } from './system';
import { commands, Disposable, TextEditor, window } from 'vscode';
import { BuiltInCommands } from './constants';
@@ -12,20 +11,19 @@ export class ActiveEditorTracker extends Disposable {
constructor() {
super(() => this.dispose());
const fn = Functions.debounce((e: TextEditor) => this._resolver && this._resolver(e), 50);
this._disposable = window.onDidChangeActiveTextEditor(fn);
this._disposable = window.onDidChangeActiveTextEditor(e => this._resolver && this._resolver(e));
}
dispose() {
this._disposable && this._disposable.dispose();
}
async awaitClose(timeout: number = 500): Promise<TextEditor | undefined> {
async awaitClose(timeout: number = 500): Promise<TextEditor> {
this.close();
return this.wait(timeout);
}
async awaitNext(timeout: number = 500): Promise<TextEditor | undefined> {
async awaitNext(timeout: number = 500): Promise<TextEditor> {
this.next();
return this.wait(timeout);
}
@@ -38,15 +36,15 @@ export class ActiveEditorTracker extends Disposable {
return commands.executeCommand(BuiltInCommands.NextEditor);
}
async wait(timeout: number = 500): Promise<TextEditor | undefined> {
async wait(timeout: number = 500): Promise<TextEditor> {
const editor = await new Promise<TextEditor>((resolve, reject) => {
let timer: any;
this._resolver = (e: TextEditor) => {
this._resolver = (editor: TextEditor) => {
if (timer) {
clearTimeout(timer as any);
timer = 0;
resolve(e);
resolve(editor);
}
};
@@ -55,7 +53,6 @@ export class ActiveEditorTracker extends Disposable {
timer = 0;
}, timeout) as any;
});
this._resolver = undefined;
return editor;
}

View File

@@ -1,34 +1,20 @@
'use strict';
import { Functions, Objects } from '../system';
import { DecorationRenderOptions, Disposable, Event, EventEmitter, ExtensionContext, OverviewRulerLane, Progress, ProgressLocation, TextDocument, TextDocumentChangeEvent, TextEditor, TextEditorDecorationType, TextEditorViewColumnChangeEvent, window, workspace } from 'vscode';
import { DecorationRenderOptions, Disposable, Event, EventEmitter, ExtensionContext, OverviewRulerLane, TextDocument, TextDocumentChangeEvent, TextEditor, TextEditorDecorationType, TextEditorViewColumnChangeEvent, window, workspace } from 'vscode';
import { AnnotationProviderBase } from './annotationProvider';
import { Keyboard, KeyboardScope, KeyCommand, Keys } from '../keyboard';
import { TextDocumentComparer, TextEditorComparer } from '../comparers';
import { ExtensionKey, IConfig, LineHighlightLocations, themeDefaults } from '../configuration';
import { CommandContext, setCommandContext } from '../constants';
import { BlameLineHighlightLocations, ExtensionKey, FileAnnotationType, IConfig, themeDefaults } from '../configuration';
import { BlameabilityChangeEvent, GitContextTracker, GitService, GitUri } from '../gitService';
import { GutterBlameAnnotationProvider } from './gutterBlameAnnotationProvider';
import { HoverBlameAnnotationProvider } from './hoverBlameAnnotationProvider';
import { Logger } from '../logger';
import { RecentChangesAnnotationProvider } from './recentChangesAnnotationProvider';
import { WhitespaceController } from './whitespaceController';
import * as path from 'path';
export type FileAnnotationType = 'gutter' | 'hover' | 'recentChanges';
export const FileAnnotationType = {
Gutter: 'gutter' as FileAnnotationType,
Hover: 'hover' as FileAnnotationType,
RecentChanges: 'recentChanges' as FileAnnotationType
};
export const Decorations = {
blameAnnotation: window.createTextEditorDecorationType({
isWholeLine: true,
textDecoration: 'none'
annotation: window.createTextEditorDecorationType({
isWholeLine: true
} as DecorationRenderOptions),
blameHighlight: undefined as TextEditorDecorationType | undefined,
recentChangesAnnotation: undefined as TextEditorDecorationType | undefined,
recentChangesHighlight: undefined as TextEditorDecorationType | undefined
highlight: undefined as TextEditorDecorationType | undefined
};
export class AnnotationController extends Disposable {
@@ -59,8 +45,8 @@ export class AnnotationController extends Disposable {
dispose() {
this._annotationProviders.forEach(async (p, i) => await this.clear(i));
Decorations.blameAnnotation && Decorations.blameAnnotation.dispose();
Decorations.blameHighlight && Decorations.blameHighlight.dispose();
Decorations.annotation && Decorations.annotation.dispose();
Decorations.highlight && Decorations.highlight.dispose();
this._annotationsDisposable && this._annotationsDisposable.dispose();
this._whitespaceController && this._whitespaceController.dispose();
@@ -69,109 +55,67 @@ export class AnnotationController extends Disposable {
private _onConfigurationChanged() {
let toggleWhitespace = workspace.getConfiguration(`${ExtensionKey}.advanced.toggleWhitespace`).get<boolean>('enabled');
// Until https://github.com/Microsoft/vscode/issues/11485 is fixed we need to toggle whitespace for non-monospace fonts and ligatures
// TODO: detect monospace vs non-monospace font
// if (!toggleWhitespace) {
// // Since we know ligatures will break the whitespace rendering -- turn it back on
// toggleWhitespace = workspace.getConfiguration('editor').get<boolean>('fontLigatures', false);
// }
// If the setting is on and we aren't showing any annotations, make sure it is necessary (i.e. only when rendering whitespace)
if (toggleWhitespace && this._annotationProviders.size === 0) {
toggleWhitespace = (workspace.getConfiguration('editor').get<string>('renderWhitespace') !== 'none');
if (!toggleWhitespace) {
// Until https://github.com/Microsoft/vscode/issues/11485 is fixed we need to toggle whitespace for non-monospace fonts and ligatures
// TODO: detect monospace font
toggleWhitespace = workspace.getConfiguration('editor').get<boolean>('fontLigatures');
}
let changed = false;
if (toggleWhitespace && this._whitespaceController === undefined) {
changed = true;
if (toggleWhitespace && !this._whitespaceController) {
this._whitespaceController = new WhitespaceController();
}
else if (!toggleWhitespace && this._whitespaceController !== undefined) {
changed = true;
else if (!toggleWhitespace && this._whitespaceController) {
this._whitespaceController.dispose();
this._whitespaceController = undefined;
}
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
const cfgBlameHighlight = cfg.blame.file.lineHighlight;
const cfgChangesHighlight = cfg.recentChanges.file.lineHighlight;
const cfgHighlight = cfg.blame.file.lineHighlight;
const cfgTheme = cfg.theme.lineHighlight;
if (!Objects.areEquivalent(cfgBlameHighlight, this._config && this._config.blame.file.lineHighlight) ||
!Objects.areEquivalent(cfgChangesHighlight, this._config && this._config.recentChanges.file.lineHighlight) ||
let changed = false;
if (!Objects.areEquivalent(cfgHighlight, this._config && this._config.blame.file.lineHighlight) ||
!Objects.areEquivalent(cfgTheme, this._config && this._config.theme.lineHighlight)) {
changed = true;
Decorations.blameHighlight && Decorations.blameHighlight.dispose();
Decorations.highlight && Decorations.highlight.dispose();
if (cfgBlameHighlight.enabled) {
Decorations.blameHighlight = window.createTextEditorDecorationType({
if (cfgHighlight.enabled) {
Decorations.highlight = window.createTextEditorDecorationType({
gutterIconSize: 'contain',
isWholeLine: true,
overviewRulerLane: OverviewRulerLane.Right,
dark: {
backgroundColor: cfgBlameHighlight.locations.includes(LineHighlightLocations.Line)
backgroundColor: cfgHighlight.locations.includes(BlameLineHighlightLocations.Line)
? cfgTheme.dark.backgroundColor || themeDefaults.lineHighlight.dark.backgroundColor
: undefined,
gutterIconPath: cfgBlameHighlight.locations.includes(LineHighlightLocations.Gutter)
? this.context.asAbsolutePath('images/dark/highlight-gutter.svg')
gutterIconPath: cfgHighlight.locations.includes(BlameLineHighlightLocations.Gutter)
? this.context.asAbsolutePath('images/blame-dark.svg')
: undefined,
overviewRulerColor: cfgBlameHighlight.locations.includes(LineHighlightLocations.OverviewRuler)
overviewRulerColor: cfgHighlight.locations.includes(BlameLineHighlightLocations.OverviewRuler)
? cfgTheme.dark.overviewRulerColor || themeDefaults.lineHighlight.dark.overviewRulerColor
: undefined
},
light: {
backgroundColor: cfgBlameHighlight.locations.includes(LineHighlightLocations.Line)
backgroundColor: cfgHighlight.locations.includes(BlameLineHighlightLocations.Line)
? cfgTheme.light.backgroundColor || themeDefaults.lineHighlight.light.backgroundColor
: undefined,
gutterIconPath: cfgBlameHighlight.locations.includes(LineHighlightLocations.Gutter)
? this.context.asAbsolutePath('images/light/highlight-gutter.svg')
gutterIconPath: cfgHighlight.locations.includes(BlameLineHighlightLocations.Gutter)
? this.context.asAbsolutePath('images/blame-light.svg')
: undefined,
overviewRulerColor: cfgBlameHighlight.locations.includes(LineHighlightLocations.OverviewRuler)
overviewRulerColor: cfgHighlight.locations.includes(BlameLineHighlightLocations.OverviewRuler)
? cfgTheme.light.overviewRulerColor || themeDefaults.lineHighlight.light.overviewRulerColor
: undefined
}
});
}
else {
Decorations.blameHighlight = undefined;
Decorations.highlight = undefined;
}
Decorations.recentChangesHighlight && Decorations.recentChangesHighlight.dispose();
Decorations.recentChangesHighlight = window.createTextEditorDecorationType({
gutterIconSize: 'contain',
isWholeLine: true,
overviewRulerLane: OverviewRulerLane.Right,
dark: {
backgroundColor: cfgChangesHighlight.locations.includes(LineHighlightLocations.Line)
? cfgTheme.dark.backgroundColor || themeDefaults.lineHighlight.dark.backgroundColor
: undefined,
gutterIconPath: cfgChangesHighlight.locations.includes(LineHighlightLocations.Gutter)
? this.context.asAbsolutePath('images/dark/highlight-gutter.svg')
: undefined,
overviewRulerColor: cfgChangesHighlight.locations.includes(LineHighlightLocations.OverviewRuler)
? cfgTheme.dark.overviewRulerColor || themeDefaults.lineHighlight.dark.overviewRulerColor
: undefined
},
light: {
backgroundColor: cfgChangesHighlight.locations.includes(LineHighlightLocations.Line)
? cfgTheme.light.backgroundColor || themeDefaults.lineHighlight.light.backgroundColor
: undefined,
gutterIconPath: cfgChangesHighlight.locations.includes(LineHighlightLocations.Gutter)
? this.context.asAbsolutePath('images/light/highlight-gutter.svg')
: undefined,
overviewRulerColor: cfgChangesHighlight.locations.includes(LineHighlightLocations.OverviewRuler)
? cfgTheme.light.overviewRulerColor || themeDefaults.lineHighlight.light.overviewRulerColor
: undefined
}
});
}
if (!Objects.areEquivalent(cfg.blame.file, this._config && this._config.blame.file) ||
!Objects.areEquivalent(cfg.recentChanges.file, this._config && this._config.recentChanges.file) ||
!Objects.areEquivalent(cfg.annotations, this._config && this._config.annotations) ||
!Objects.areEquivalent(cfg.theme.annotations, this._config && this._config.theme.annotations)) {
changed = true;
@@ -184,31 +128,20 @@ export class AnnotationController extends Disposable {
for (const provider of this._annotationProviders.values()) {
if (provider === undefined) continue;
if (provider.annotationType === FileAnnotationType.RecentChanges) {
provider.reset(Decorations.recentChangesAnnotation, Decorations.recentChangesHighlight);
}
else {
provider.reset(Decorations.blameAnnotation, Decorations.blameHighlight, this._whitespaceController);
}
provider.reset();
}
}
}
async clear(column: number) {
const provider = this._annotationProviders.get(column);
if (provider === undefined) return;
if (!provider) return;
this._annotationProviders.delete(column);
await provider.dispose();
if (this._annotationProviders.size === 0) {
Logger.log(`Remove listener registrations for annotations`);
await setCommandContext(CommandContext.AnnotationStatus, undefined);
this._keyboardScope && this._keyboardScope.dispose();
this._keyboardScope = undefined;
this._annotationsDisposable && this._annotationsDisposable.dispose();
this._annotationsDisposable = undefined;
}
@@ -216,19 +149,17 @@ export class AnnotationController extends Disposable {
this._onDidToggleAnnotations.fire();
}
getAnnotationType(editor: TextEditor | undefined): FileAnnotationType | undefined {
getAnnotationType(editor: TextEditor): FileAnnotationType | undefined {
const provider = this.getProvider(editor);
return provider === undefined ? undefined : provider.annotationType;
}
getProvider(editor: TextEditor | undefined): AnnotationProviderBase | undefined {
getProvider(editor: TextEditor): AnnotationProviderBase | undefined {
if (!editor || !editor.document || !this.git.isEditorBlameable(editor)) return undefined;
return this._annotationProviders.get(editor.viewColumn || -1);
}
private _keyboardScope: KeyboardScope | undefined = undefined;
async showAnnotations(editor: TextEditor, type: FileAnnotationType, shaOrLine?: string | number): Promise<boolean> {
if (!editor || !editor.document || !this.git.isEditorBlameable(editor)) return false;
@@ -238,64 +169,15 @@ export class AnnotationController extends Disposable {
return true;
}
return window.withProgress({ location: ProgressLocation.Window }, async (progress: Progress<{ message: string }>) => {
await setCommandContext(CommandContext.AnnotationStatus, 'computing');
const computingAnnotations = this._showAnnotationsCore(currentProvider, editor, type, shaOrLine, progress);
const result = await computingAnnotations;
await setCommandContext(CommandContext.AnnotationStatus, result ? 'computed' : undefined);
return computingAnnotations;
});
}
private async _showAnnotationsCore(currentProvider: AnnotationProviderBase | undefined, editor: TextEditor, type: FileAnnotationType, shaOrLine?: string | number, progress?: Progress<{ message: string}>): Promise<boolean> {
if (progress !== undefined) {
let annotationsLabel = 'annotations';
switch (type) {
case FileAnnotationType.Gutter:
case FileAnnotationType.Hover:
annotationsLabel = 'blame annotations';
break;
case FileAnnotationType.RecentChanges:
annotationsLabel = 'recent changes annotations';
break;
}
progress!.report({ message: `Computing ${annotationsLabel} for ${path.basename(editor.document.fileName)}` });
}
// Allows pressing escape to exit the annotations
if (this._keyboardScope === undefined) {
this._keyboardScope = await Keyboard.instance.beginScope({
escape: {
onDidPressKey: (key: Keys) => {
const e = window.activeTextEditor;
if (e === undefined) return Promise.resolve(undefined);
this.clear(e.viewColumn || -1);
return Promise.resolve(undefined);
}
} as KeyCommand
});
}
const gitUri = await GitUri.fromUri(editor.document.uri, this.git);
let provider: AnnotationProviderBase | undefined = undefined;
switch (type) {
case FileAnnotationType.Gutter:
provider = new GutterBlameAnnotationProvider(this.context, editor, Decorations.blameAnnotation, Decorations.blameHighlight, this._whitespaceController, this.git, gitUri);
provider = new GutterBlameAnnotationProvider(this.context, editor, Decorations.annotation, Decorations.highlight, this._whitespaceController, this.git, gitUri);
break;
case FileAnnotationType.Hover:
provider = new HoverBlameAnnotationProvider(this.context, editor, Decorations.blameAnnotation, Decorations.blameHighlight, this._whitespaceController, this.git, gitUri);
break;
case FileAnnotationType.RecentChanges:
provider = new RecentChangesAnnotationProvider(this.context, editor, undefined, Decorations.recentChangesHighlight!, this.git, gitUri);
provider = new HoverBlameAnnotationProvider(this.context, editor, Decorations.annotation, Decorations.highlight, this._whitespaceController, this.git, gitUri);
break;
}
if (provider === undefined || !(await provider.validate())) return false;
@@ -313,7 +195,7 @@ export class AnnotationController extends Disposable {
subscriptions.push(window.onDidChangeTextEditorViewColumn(this._onTextEditorViewColumnChanged, this));
subscriptions.push(workspace.onDidChangeTextDocument(this._onTextDocumentChanged, this));
subscriptions.push(workspace.onDidCloseTextDocument(this._onTextDocumentClosed, this));
subscriptions.push(this.gitContextTracker.onDidChangeBlameability(this._onBlameabilityChanged, this));
subscriptions.push(this.gitContextTracker.onDidBlameabilityChange(this._onBlameabilityChanged, this));
this._annotationsDisposable = Disposable.from(...subscriptions);
}
@@ -323,22 +205,17 @@ export class AnnotationController extends Disposable {
this._onDidToggleAnnotations.fire();
return true;
}
return false;
}
async toggleAnnotations(editor: TextEditor, type: FileAnnotationType, shaOrLine?: string | number): Promise<boolean> {
if (!editor || !editor.document || (type === FileAnnotationType.RecentChanges ? !this.git.isTrackable(editor.document.uri) : !this.git.isEditorBlameable(editor))) return false;
if (!editor || !editor.document || !this.git.isEditorBlameable(editor)) return false;
const provider = this._annotationProviders.get(editor.viewColumn || -1);
if (provider === undefined) return this.showAnnotations(editor, type, shaOrLine);
const reopen = provider.annotationType !== type;
await this.clear(provider.editor.viewColumn || -1);
if (!reopen) return false;
return this.showAnnotations(editor, type, shaOrLine);
return false;
}
private _onBlameabilityChanged(e: BlameabilityChangeEvent) {
@@ -356,7 +233,6 @@ export class AnnotationController extends Disposable {
for (const [key, p] of this._annotationProviders) {
if (!TextDocumentComparer.equals(p.document, e.document)) continue;
// TODO: Rework this once https://github.com/Microsoft/vscode/issues/27231 is released in v1.13
// We have to defer because isDirty is not reliable inside this event
setTimeout(() => {
// If the document is dirty all is fine, just kick out since the GitContextTracker will handle it

View File

@@ -1,9 +1,8 @@
'use strict';
// import { Functions } from '../system';
import { Functions } from '../system';
import { Disposable, ExtensionContext, TextDocument, TextEditor, TextEditorDecorationType, TextEditorSelectionChangeEvent, window, workspace } from 'vscode';
import { FileAnnotationType } from '../annotations/annotationController';
import { TextDocumentComparer } from '../comparers';
import { ExtensionKey, IConfig } from '../configuration';
import { ExtensionKey, FileAnnotationType, IConfig } from '../configuration';
import { WhitespaceController } from './whitespaceController';
export abstract class AnnotationProviderBase extends Disposable {
@@ -14,7 +13,7 @@ import { WhitespaceController } from './whitespaceController';
protected _config: IConfig;
protected _disposable: Disposable;
constructor(context: ExtensionContext, public editor: TextEditor, protected decoration: TextEditorDecorationType | undefined, protected highlightDecoration: TextEditorDecorationType | undefined, protected whitespaceController: WhitespaceController | undefined) {
constructor(context: ExtensionContext, public editor: TextEditor, protected decoration: TextEditorDecorationType, protected highlightDecoration: TextEditorDecorationType | undefined, protected whitespaceController: WhitespaceController | undefined) {
super(() => this.dispose());
this.document = this.editor.document;
@@ -43,12 +42,15 @@ import { WhitespaceController } from './whitespaceController';
async clear() {
if (this.editor !== undefined) {
try {
this.editor.setDecorations(this.decoration, []);
this.highlightDecoration && this.editor.setDecorations(this.highlightDecoration, []);
// I have no idea why the decorators sometimes don't get removed, but if they don't try again with a tiny delay
if (this.highlightDecoration !== undefined) {
this.editor.setDecorations(this.highlightDecoration, []);
}
await Functions.wait(1);
if (this.decoration !== undefined) {
this.editor.setDecorations(this.decoration, []);
if (this.highlightDecoration === undefined) return;
this.editor.setDecorations(this.highlightDecoration, []);
}
}
catch (ex) { }
@@ -58,13 +60,10 @@ import { WhitespaceController } from './whitespaceController';
this.whitespaceController && await this.whitespaceController.restore();
}
async reset(decoration: TextEditorDecorationType | undefined, highlightDecoration: TextEditorDecorationType | undefined, whitespaceController?: WhitespaceController) {
async reset() {
await this.clear();
this._config = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
this.decoration = decoration;
this.highlightDecoration = highlightDecoration;
this.whitespaceController = whitespaceController;
await this.provideAnnotation(this.editor === undefined ? undefined : this.editor.selection.active.line);
}

View File

@@ -1,8 +1,6 @@
import { Strings } from '../system';
import { DecorationInstanceRenderOptions, DecorationOptions, ThemableDecorationRenderOptions } from 'vscode';
import { IThemeConfig, themeDefaults } from '../configuration';
import { GlyphChars } from '../constants';
import { CommitFormatter, GitCommit, GitDiffChunkLine, GitService, GitUri, ICommitFormatOptions } from '../gitService';
import { CommitFormatter, GitCommit, GitService, GitUri, ICommitFormatOptions } from '../gitService';
import * as moment from 'moment';
interface IHeatmapConfig {
@@ -22,8 +20,6 @@ interface IRenderOptions {
}
export const endOfLineIndex = 1000000;
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___';
export class Annotations {
@@ -47,67 +43,42 @@ export class Annotations {
return '#793738';
}
static getHoverMessage(commit: GitCommit, dateFormat: string | null): string | string[] {
if (dateFormat === null) {
dateFormat = 'MMMM Do, YYYY h:MMa';
}
let message = '';
if (!commit.isUncommitted) {
message = commit.message
// Escape markdown
.replace(escapeMarkdownRegEx, '\\$&')
// Escape markdown header (since the above regex won't match it)
.replace(/^===/gm, `${GlyphChars.ZeroWidthSpace}===`)
// Keep under the same block-quote
.replace(/\n/g, ' \n');
message = `\n\n> ${message}`;
}
return `\`${commit.shortSha}\` &nbsp; __${commit.author}__, ${moment(commit.date).fromNow()} &nbsp; _(${moment(commit.date).format(dateFormat)})_${message}`;
}
static getHoverDiffMessage(commit: GitCommit, chunkLine: GitDiffChunkLine | undefined): string | undefined {
if (chunkLine === undefined) return undefined;
const codeDiff = this._getCodeDiff(chunkLine);
return commit.isUncommitted
? `\`Changes\` &nbsp; ${GlyphChars.Dash} &nbsp; _uncommitted_\n${codeDiff}`
: `\`Changes\` &nbsp; ${GlyphChars.Dash} &nbsp; \`${commit.previousShortSha}\` ${GlyphChars.ArrowLeftRight} \`${commit.shortSha}\`\n${codeDiff}`;
}
private static _getCodeDiff(chunkLine: GitDiffChunkLine): string {
const previous = chunkLine.previous === undefined ? undefined : chunkLine.previous[0];
return `\`\`\`
- ${previous === undefined || previous.line === undefined ? '' : previous.line.trim()}
+ ${chunkLine.line === undefined ? '' : chunkLine.line.trim()}
\`\`\``;
}
static async changesHover(commit: GitCommit, line: number, uri: GitUri, git: GitService): Promise<DecorationOptions> {
const chunkLine = await git.getDiffForLine(uri, line + uri.offset, commit.isUncommitted ? undefined : commit.previousSha);
const message = this.getHoverDiffMessage(commit, chunkLine);
let message: string | undefined = undefined;
if (commit.isUncommitted) {
const [previous, current] = await git.getDiffForLine(uri, line + uri.offset);
message = CommitFormatter.toHoverDiff(commit, previous, current);
}
else if (commit.previousSha !== undefined) {
const [previous, current] = await git.getDiffForLine(uri, line + uri.offset, commit.previousSha);
message = CommitFormatter.toHoverDiff(commit, previous, current);
}
return {
hoverMessage: message
} as DecorationOptions;
}
static detailsHover(commit: GitCommit, dateFormat: string | null): DecorationOptions {
const message = this.getHoverMessage(commit, dateFormat);
static detailsHover(commit: GitCommit): DecorationOptions {
const message = CommitFormatter.toHoverAnnotation(commit);
return {
hoverMessage: message
} as DecorationOptions;
}
static gutter(commit: GitCommit, format: string, dateFormatOrFormatOptions: string | null | ICommitFormatOptions, renderOptions: IRenderOptions): DecorationOptions {
const content = Strings.pad(CommitFormatter.fromTemplate(format, commit, dateFormatOrFormatOptions), 1, 1);
static gutter(commit: GitCommit, format: string, dateFormatOrFormatOptions: string | null | ICommitFormatOptions, renderOptions: IRenderOptions, compact: boolean): DecorationOptions {
let content = `\u00a0${CommitFormatter.fromTemplate(format, commit, dateFormatOrFormatOptions)}\u00a0`;
if (compact) {
content = '\u00a0'.repeat(content.length);
}
return {
renderOptions: {
before: {
...renderOptions.before,
...{
contentText: content
contentText: content,
margin: '0 26px 0 0'
}
},
dark: {
@@ -142,25 +113,22 @@ export class Annotations {
before: {
borderStyle: borderStyle,
borderWidth: borderWidth,
height: '100%',
margin: '0 26px -1px 0'
height: cfgFileTheme.separateLines ? 'calc(100% - 1px)' : '100%'
},
dark: {
backgroundColor: cfgFileTheme.dark.backgroundColor || undefined,
color: cfgFileTheme.dark.foregroundColor || themeDefaults.annotations.file.gutter.dark.foregroundColor,
textDecoration: cfgFileTheme.separateLines ? 'overline solid rgba(0, 0, 0, .2)' : 'none'
color: cfgFileTheme.dark.foregroundColor || themeDefaults.annotations.file.gutter.dark.foregroundColor
} as DecorationInstanceRenderOptions,
light: {
backgroundColor: cfgFileTheme.light.backgroundColor || undefined,
color: cfgFileTheme.light.foregroundColor || themeDefaults.annotations.file.gutter.light.foregroundColor,
textDecoration: cfgFileTheme.separateLines ? 'overline solid rgba(0, 0, 0, .05)' : 'none'
color: cfgFileTheme.light.foregroundColor || themeDefaults.annotations.file.gutter.light.foregroundColor
} as DecorationInstanceRenderOptions
} as IRenderOptions;
};
}
static hover(commit: GitCommit, renderOptions: IRenderOptions, heatmap: boolean, dateFormat: string | null): DecorationOptions {
static hover(commit: GitCommit, renderOptions: IRenderOptions, heatmap: boolean): DecorationOptions {
return {
hoverMessage: this.getHoverMessage(commit, dateFormat),
hoverMessage: CommitFormatter.toHoverAnnotation(commit),
renderOptions: heatmap ? { before: { ...renderOptions.before } } : undefined
} as DecorationOptions;
}
@@ -172,10 +140,9 @@ export class Annotations {
before: {
borderStyle: 'solid',
borderWidth: '0 0 0 2px',
contentText: GlyphChars.ZeroWidthSpace,
height: '100%',
margin: '0 26px 0 0',
textDecoration: 'none'
contentText: '\u200B',
height: cfgTheme.annotations.file.hover.separateLines ? 'calc(100% - 1px)' : '100%',
margin: '0 26px 0 0'
}
} as IRenderOptions;
}
@@ -185,7 +152,7 @@ export class Annotations {
return {
renderOptions: {
after: {
contentText: Strings.pad(message, 1, 1)
contentText: `\u00a0${message}\u00a0`
},
dark: {
after: {

View File

@@ -2,20 +2,20 @@
import { Iterables } from '../system';
import { ExtensionContext, Range, TextEditor, TextEditorDecorationType } from 'vscode';
import { AnnotationProviderBase } from './annotationProvider';
import { GitBlame, GitService, GitUri } from '../gitService';
import { GitService, GitUri, IGitBlame } from '../gitService';
import { WhitespaceController } from './whitespaceController';
export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase {
protected _blame: Promise<GitBlame | undefined>;
protected _blame: Promise<IGitBlame>;
constructor(context: ExtensionContext, editor: TextEditor, decoration: TextEditorDecorationType | undefined, highlightDecoration: TextEditorDecorationType | undefined, whitespaceController: WhitespaceController | undefined, protected git: GitService, protected uri: GitUri) {
constructor(context: ExtensionContext, editor: TextEditor, decoration: TextEditorDecorationType, highlightDecoration: TextEditorDecorationType | undefined, whitespaceController: WhitespaceController | undefined, protected git: GitService, protected uri: GitUri) {
super(context, editor, decoration, highlightDecoration, whitespaceController);
this._blame = this.git.getBlameForFile(this.uri);
}
async selection(shaOrLine?: string | number, blame?: GitBlame) {
async selection(shaOrLine?: string | number, blame?: IGitBlame) {
if (!this.highlightDecoration) return;
if (blame === undefined) {
@@ -56,14 +56,15 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase
const blame = await this._blame;
return blame !== undefined && blame.lines.length !== 0;
}
protected async getBlame(requiresWhitespaceHack: boolean): Promise<GitBlame | undefined> {
protected async getBlame(requiresWhitespaceHack: boolean): Promise<IGitBlame | undefined> {
let whitespacePromise: Promise<void> | undefined;
// HACK: Until https://github.com/Microsoft/vscode/issues/11485 is fixed -- override whitespace (turn off)
if (requiresWhitespaceHack) {
whitespacePromise = this.whitespaceController && this.whitespaceController.override();
}
let blame: GitBlame | undefined;
let blame: IGitBlame;
if (whitespacePromise) {
[blame] = await Promise.all([this._blame, whitespacePromise]);
}
@@ -71,7 +72,7 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase
blame = await this._blame;
}
if (blame === undefined || !blame.lines.length) {
if (!blame || !blame.lines.length) {
this.whitespaceController && await this.whitespaceController.restore();
return undefined;
}

View File

@@ -0,0 +1,69 @@
'use strict';
import { DecorationOptions, ExtensionContext, Position, Range, TextEditor, TextEditorDecorationType } from 'vscode';
import { AnnotationProviderBase } from './annotationProvider';
import { GitService, GitUri } from '../gitService';
import { WhitespaceController } from './whitespaceController';
export class DiffAnnotationProvider extends AnnotationProviderBase {
constructor(context: ExtensionContext, editor: TextEditor, decoration: TextEditorDecorationType, highlightDecoration: TextEditorDecorationType | undefined, whitespaceController: WhitespaceController | undefined, private git: GitService, private uri: GitUri) {
super(context, editor, decoration, highlightDecoration, whitespaceController);
}
async provideAnnotation(shaOrLine?: string | number): Promise<boolean> {
// let sha1: string | undefined = undefined;
// let sha2: string | undefined = undefined;
// if (shaOrLine === undefined) {
// const commit = await this.git.getLogCommit(this.uri.repoPath, this.uri.fsPath, { previous: true });
// if (commit === undefined) return false;
// sha1 = commit.previousSha;
// }
// else if (typeof shaOrLine === 'string') {
// sha1 = shaOrLine;
// }
// else {
// const blame = await this.git.getBlameForLine(this.uri, shaOrLine);
// if (blame === undefined) return false;
// sha1 = blame.commit.previousSha;
// sha2 = blame.commit.sha;
// }
// if (sha1 === undefined) return false;
const commit = await this.git.getLogCommit(this.uri.repoPath, this.uri.fsPath, { previous: true });
if (commit === undefined) return false;
const diff = await this.git.getDiffForFile(this.uri, commit.previousSha);
if (diff === undefined) return false;
const decorators: DecorationOptions[] = [];
for (const chunk of diff.chunks) {
let count = chunk.currentStart - 2;
for (const change of chunk.current) {
if (change === undefined) continue;
count++;
if (change.state === 'unchanged') continue;
decorators.push({
range: new Range(new Position(count, 0), new Position(count, 0))
} as DecorationOptions);
}
}
this.editor.setDecorations(this.decoration, decorators);
return true;
}
async selection(shaOrLine?: string | number): Promise<void> {
}
async validate(): Promise<boolean> {
return true;
}
}

View File

@@ -1,11 +1,10 @@
'use strict';
import { Strings } from '../system';
import { DecorationOptions, Range } from 'vscode';
import { FileAnnotationType } from './annotationController';
import { Annotations, endOfLineIndex } from './annotations';
import { BlameAnnotationProviderBase } from './blameAnnotationProvider';
import { GlyphChars } from '../constants';
import { GitBlameCommit, ICommitFormatOptions } from '../gitService';
import { Annotations, endOfLineIndex } from './annotations';
import { FileAnnotationType } from '../configuration';
import { ICommitFormatOptions } from '../gitService';
import * as moment from 'moment';
export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
@@ -16,107 +15,61 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
const blame = await this.getBlame(true);
if (blame === undefined) return false;
// console.time('Computing blame annotations...');
const cfg = this._config.annotations.file.gutter;
// Precalculate the formatting options so we don't need to do it on each iteration
const tokenOptions = Strings.getTokensFromTemplate(cfg.format)
.reduce((map, token) => {
map[token.key] = token.options as ICommitFormatOptions;
map[token.key] = token.options;
return map;
}, {} as { [token: string]: ICommitFormatOptions });
const options: ICommitFormatOptions = {
dateFormat: cfg.dateFormat === null ? this._config.defaultDateFormat : cfg.dateFormat,
dateFormat: cfg.dateFormat,
tokenOptions: tokenOptions
};
const now = moment();
const offset = this.uri.offset;
let previousLine: string | undefined = undefined;
const renderOptions = Annotations.gutterRenderOptions(this._config.theme, cfg.heatmap);
const dateFormat = this._config.defaultDateFormat;
const separateLines = this._config.theme.annotations.file.gutter.separateLines;
const decorations: DecorationOptions[] = [];
const document = this.document;
let commit: GitBlameCommit | undefined;
let compacted = false;
let details: DecorationOptions | undefined;
let gutter: DecorationOptions | undefined;
let previousSha: string | undefined;
for (const l of blame.lines) {
commit = blame.commits.get(l.sha);
const commit = blame.commits.get(l.sha);
if (commit === undefined) continue;
const line = l.line + offset;
if (previousSha === l.sha) {
// Use a shallow copy of the previous decoration options
gutter = { ...gutter } as DecorationOptions;
if (cfg.compact && !compacted) {
// Since we are wiping out the contextText make sure to copy the objects
gutter.renderOptions = { ...gutter.renderOptions };
gutter.renderOptions.before = {
...gutter.renderOptions.before,
...{ contentText: GlyphChars.Space.repeat(gutter.renderOptions!.before!.contentText!.length) }
};
const gutter = Annotations.gutter(commit, cfg.format, options, renderOptions, cfg.compact && previousLine === l.sha);
if (separateLines) {
gutter.renderOptions.dark = { ...gutter.renderOptions.dark };
gutter.renderOptions.dark.before = { ...gutter.renderOptions.dark.before, ...{ textDecoration: 'none' } };
gutter.renderOptions.light = { ...gutter.renderOptions.light };
gutter.renderOptions.light.before = { ...gutter.renderOptions.light.before, ...{ textDecoration: 'none' } };
}
compacted = true;
}
const endIndex = document.lineAt(line).firstNonWhitespaceCharacterIndex;
gutter.range = new Range(line, 0, line, endIndex);
decorations.push(gutter);
if (details !== undefined) {
details = { ...details } as DecorationOptions;
details.range = cfg.hover.wholeLine
? document.validateRange(new Range(line, 0, line, endOfLineIndex))
: gutter.range;
decorations.push(details);
}
continue;
if (cfg.compact) {
const isEmptyOrWhitespace = this.document.lineAt(line).isEmptyOrWhitespace;
previousLine = isEmptyOrWhitespace ? undefined : l.sha;
}
compacted = false;
previousSha = l.sha;
gutter = Annotations.gutter(commit, cfg.format, options, renderOptions);
if (cfg.heatmap.enabled) {
Annotations.applyHeatmap(gutter, commit.date, now);
}
const endIndex = document.lineAt(line).firstNonWhitespaceCharacterIndex;
gutter.range = new Range(line, 0, line, endIndex);
const firstNonWhitespace = this.editor.document.lineAt(line).firstNonWhitespaceCharacterIndex;
gutter.range = this.editor.document.validateRange(new Range(line, 0, line, firstNonWhitespace));
decorations.push(gutter);
if (cfg.hover.details) {
details = Annotations.detailsHover(commit, dateFormat);
const details = Annotations.detailsHover(commit);
details.range = cfg.hover.wholeLine
? document.validateRange(new Range(line, 0, line, endOfLineIndex))
? this.editor.document.validateRange(new Range(line, 0, line, endOfLineIndex))
: gutter.range;
decorations.push(details);
}
}
if (decorations.length) {
this.editor.setDecorations(this.decoration!, decorations);
this.editor.setDecorations(this.decoration, decorations);
}
// console.timeEnd('Computing blame annotations...');
this.selection(shaOrLine, blame);
return true;
}

View File

@@ -1,9 +1,8 @@
'use strict';
import { DecorationOptions, Range } from 'vscode';
import { FileAnnotationType } from './annotationController';
import { Annotations, endOfLineIndex } from './annotations';
import { BlameAnnotationProviderBase } from './blameAnnotationProvider';
import { GitBlameCommit } from '../gitService';
import { Annotations, endOfLineIndex } from './annotations';
import { FileAnnotationType } from '../configuration';
import * as moment from 'moment';
export class HoverBlameAnnotationProvider extends BlameAnnotationProviderBase {
@@ -14,36 +13,24 @@ export class HoverBlameAnnotationProvider extends BlameAnnotationProviderBase {
const blame = await this.getBlame(this._config.annotations.file.hover.heatmap.enabled);
if (blame === undefined) return false;
// console.time('Computing blame annotations...');
const cfg = this._config.annotations.file.hover;
const now = moment();
const offset = this.uri.offset;
const renderOptions = Annotations.hoverRenderOptions(this._config.theme, cfg.heatmap);
const dateFormat = this._config.defaultDateFormat;
const decorations: DecorationOptions[] = [];
const document = this.document;
let commit: GitBlameCommit | undefined;
let hover: DecorationOptions | undefined;
for (const l of blame.lines) {
commit = blame.commits.get(l.sha);
const commit = blame.commits.get(l.sha);
if (commit === undefined) continue;
const line = l.line + offset;
hover = Annotations.hover(commit, renderOptions, cfg.heatmap.enabled, dateFormat);
const hover = Annotations.hover(commit, renderOptions, cfg.heatmap.enabled);
if (cfg.wholeLine) {
hover.range = document.validateRange(new Range(line, 0, line, endOfLineIndex));
}
else {
const endIndex = document.lineAt(line).firstNonWhitespaceCharacterIndex;
hover.range = new Range(line, 0, line, endIndex);
}
const endIndex = cfg.wholeLine ? endOfLineIndex : this.editor.document.lineAt(line).firstNonWhitespaceCharacterIndex;
hover.range = this.editor.document.validateRange(new Range(line, 0, line, endIndex));
if (cfg.heatmap.enabled) {
Annotations.applyHeatmap(hover, commit.date, now);
@@ -53,11 +40,9 @@ export class HoverBlameAnnotationProvider extends BlameAnnotationProviderBase {
}
if (decorations.length) {
this.editor.setDecorations(this.decoration!, decorations);
this.editor.setDecorations(this.decoration, decorations);
}
// console.timeEnd('Computing blame annotations...');
this.selection(shaOrLine, blame);
return true;
}

View File

@@ -1,74 +0,0 @@
'use strict';
import { DecorationOptions, ExtensionContext, Position, Range, TextEditor, TextEditorDecorationType } from 'vscode';
import { Annotations, endOfLineIndex } from './annotations';
import { FileAnnotationType } from './annotationController';
import { AnnotationProviderBase } from './annotationProvider';
import { GitService, GitUri } from '../gitService';
export class RecentChangesAnnotationProvider extends AnnotationProviderBase {
constructor(context: ExtensionContext, editor: TextEditor, decoration: TextEditorDecorationType | undefined, highlightDecoration: TextEditorDecorationType | undefined, private git: GitService, private uri: GitUri) {
super(context, editor, decoration, highlightDecoration, undefined);
}
async provideAnnotation(shaOrLine?: string | number): Promise<boolean> {
this.annotationType = FileAnnotationType.RecentChanges;
const commit = await this.git.getLogCommit(this.uri.repoPath, this.uri.fsPath, { previous: true });
if (commit === undefined) return false;
const diff = await this.git.getDiffForFile(this.uri, commit.previousSha);
if (diff === undefined) return false;
const cfg = this._config.annotations.file.recentChanges;
const dateFormat = this._config.defaultDateFormat;
const decorators: DecorationOptions[] = [];
for (const chunk of diff.chunks) {
let count = chunk.currentPosition.start - 2;
for (const line of chunk.lines) {
if (line.line === undefined) continue;
count++;
if (line.state === 'unchanged') continue;
let endingIndex = 0;
if (cfg.hover.details || cfg.hover.changes) {
endingIndex = cfg.hover.wholeLine ? endOfLineIndex : this.editor.document.lineAt(count).firstNonWhitespaceCharacterIndex;
}
const range = this.editor.document.validateRange(new Range(new Position(count, 0), new Position(count, endingIndex)));
if (cfg.hover.details) {
decorators.push({
hoverMessage: Annotations.getHoverMessage(commit, dateFormat),
range: range
} as DecorationOptions);
}
let message: string | undefined = undefined;
if (cfg.hover.changes) {
message = Annotations.getHoverDiffMessage(commit, line);
}
decorators.push({
hoverMessage: message,
range: range
} as DecorationOptions);
}
}
this.editor.setDecorations(this.highlightDecoration!, decorators);
return true;
}
async selection(shaOrLine?: string | number): Promise<void> {
}
async validate(): Promise<boolean> {
return true;
}
}

View File

@@ -1,7 +1,8 @@
'use strict';
export * from './commands/common';
export * from './commands/clearFileAnnotations';
export * from './commands/keyboard';
export * from './commands/closeUnchangedFiles';
export * from './commands/copyMessageToClipboard';
export * from './commands/copyShaToClipboard';
@@ -11,7 +12,6 @@ export * from './commands/diffLineWithWorking';
export * from './commands/diffWithBranch';
export * from './commands/diffWithNext';
export * from './commands/diffWithPrevious';
export * from './commands/diffWithRevision';
export * from './commands/diffWithWorking';
export * from './commands/openChangedFiles';
export * from './commands/openBranchInRemote';
@@ -19,18 +19,17 @@ export * from './commands/openCommitInRemote';
export * from './commands/openFileInRemote';
export * from './commands/openInRemote';
export * from './commands/openRepoInRemote';
export * from './commands/resetSuppressedWarnings';
export * from './commands/showBlameHistory';
export * from './commands/showCommitSearch';
export * from './commands/showFileBlame';
export * from './commands/showFileHistory';
export * from './commands/showLastQuickPick';
export * from './commands/showLineBlame';
export * from './commands/showQuickBranchHistory';
export * from './commands/showQuickCommitDetails';
export * from './commands/showQuickCommitFileDetails';
export * from './commands/showQuickCurrentBranchHistory';
export * from './commands/showCommitSearch';
export * from './commands/showQuickFileHistory';
export * from './commands/showQuickBranchHistory';
export * from './commands/showQuickCurrentBranchHistory';
export * from './commands/showQuickRepoStatus';
export * from './commands/showQuickStashList';
export * from './commands/stashApply';
@@ -38,5 +37,4 @@ export * from './commands/stashDelete';
export * from './commands/stashSave';
export * from './commands/toggleCodeLens';
export * from './commands/toggleFileBlame';
export * from './commands/toggleFileRecentChanges';
export * from './commands/toggleLineBlame';

View File

@@ -1,24 +0,0 @@
'use strict';
import { TextEditor, TextEditorEdit, Uri, window } from 'vscode';
import { AnnotationController } from '../annotations/annotationController';
import { Commands, EditorCommand } from './common';
import { Logger } from '../logger';
export class ClearFileAnnotationsCommand extends EditorCommand {
constructor(private annotationController: AnnotationController) {
super(Commands.ClearFileAnnotations);
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri): Promise<any> {
if (editor === undefined || editor.document === undefined || editor.document.isDirty) return undefined;
try {
return this.annotationController.clear(editor.viewColumn || -1);
}
catch (ex) {
Logger.error(ex, 'ClearFileAnnotationsCommand');
return window.showErrorMessage(`Unable to clear file annotations. See output channel for more details`);
}
}
}

View File

@@ -1,87 +1,71 @@
'use strict';
import { commands, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorTracker } from '../activeEditorTracker';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { TextEditorComparer, UriComparer } from '../comparers';
import { BuiltInCommands } from '../constants';
import { GitService } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
export interface CloseUnchangedFilesCommandArgs {
uris?: Uri[];
}
export class CloseUnchangedFilesCommand extends ActiveEditorCommand {
constructor(private git: GitService) {
super(Commands.CloseUnchangedFiles);
}
async execute(editor?: TextEditor, uri?: Uri, args: CloseUnchangedFilesCommandArgs = {}) {
uri = getCommandUri(uri, editor);
try {
if (args.uris === undefined) {
args = { ...args };
const repoPath = await this.git.getRepoPathFromUri(uri);
if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to close unchanged files`);
const status = await this.git.getStatusForRepo(repoPath);
if (status === undefined) return window.showWarningMessage(`Unable to close unchanged files`);
args.uris = status.files.map(_ => _.Uri);
}
if (args.uris.length === 0) return commands.executeCommand(BuiltInCommands.CloseAllEditors);
const editorTracker = new ActiveEditorTracker();
let count = 0;
let previous = undefined;
let editor = window.activeTextEditor;
while (true) {
if (editor !== undefined) {
if (TextEditorComparer.equals(previous, editor, { useId: true, usePosition: true })) {
break;
}
if (editor.document !== undefined &&
(editor.document.isDirty || args.uris.some(_ => UriComparer.equals(_, editor!.document && editor!.document.uri)))) {
const lastPrevious = previous;
previous = editor;
editor = await editorTracker.awaitNext(500);
if (TextEditorComparer.equals(lastPrevious, editor, { useId: true, usePosition: true })) {
break;
}
continue;
}
}
previous = editor;
editor = await editorTracker.awaitClose(500);
if (previous === undefined && editor === undefined) {
count++;
// This is such a shitty hack, but I can't figure out any other reliable way to know that we've cycled through all the editors :(
if (count >= 4) {
break;
}
}
else {
count = 0;
}
}
editorTracker.dispose();
return undefined;
}
catch (ex) {
Logger.error(ex, 'CloseUnchangedFilesCommand');
return window.showErrorMessage(`Unable to close unchanged files. See output channel for more details`);
}
}
'use strict';
import { TextEditor, Uri, window } from 'vscode';
import { ActiveEditorTracker } from '../activeEditorTracker';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { TextEditorComparer, UriComparer } from '../comparers';
import { GitService } from '../gitService';
import { Logger } from '../logger';
export interface CloseUnchangedFilesCommandArgs {
uris?: Uri[];
}
export class CloseUnchangedFilesCommand extends ActiveEditorCommand {
constructor(private git: GitService) {
super(Commands.CloseUnchangedFiles);
}
async execute(editor: TextEditor, uri?: Uri, args: CloseUnchangedFilesCommandArgs = {}) {
uri = getCommandUri(uri, editor);
try {
if (args.uris === undefined) {
const repoPath = await this.git.getRepoPathFromUri(uri);
if (!repoPath) return window.showWarningMessage(`Unable to close unchanged files`);
const status = await this.git.getStatusForRepo(repoPath);
if (status === undefined) return window.showWarningMessage(`Unable to close unchanged files`);
args.uris = status.files.map(_ => _.Uri);
}
const editorTracker = new ActiveEditorTracker();
let active = window.activeTextEditor;
let editor = active;
do {
if (editor !== undefined) {
if ((editor.document !== undefined && editor.document.isDirty) ||
args.uris.some(_ => UriComparer.equals(_, editor!.document && editor!.document.uri))) {
// If we didn't start with a valid editor, set one once we find it
if (active === undefined) {
active = editor;
}
editor = await editorTracker.awaitNext(500);
}
else {
if (active === editor) {
active = undefined;
}
editor = await editorTracker.awaitClose(500);
}
}
else {
if (active === editor) {
active = undefined;
}
editor = await editorTracker.awaitClose(500);
}
} while ((active === undefined && editor === undefined) || !TextEditorComparer.equals(active, editor, { useId: true, usePosition: true }));
editorTracker.dispose();
return undefined;
}
catch (ex) {
Logger.error(ex, 'CloseUnchangedFilesCommand');
return window.showErrorMessage(`Unable to close unchanged files. See output channel for more details`);
}
}
}

View File

@@ -1,51 +1,20 @@
'use strict';
import { commands, Disposable, SourceControlResourceGroup, SourceControlResourceState, TextDocumentShowOptions, TextEditor, TextEditorEdit, Uri, window, workspace } from 'vscode';
import { ExplorerNode } from '../views/explorerNodes';
import { commands, Disposable, TextDocumentShowOptions, TextEditor, TextEditorEdit, Uri, window, workspace } from 'vscode';
import { BuiltInCommands } from '../constants';
import { Logger } from '../logger';
import { Telemetry } from '../telemetry';
export type Commands =
'gitlens.clearFileAnnotations' |
'gitlens.closeUnchangedFiles' |
'gitlens.copyMessageToClipboard' |
'gitlens.copyShaToClipboard' |
'gitlens.diffDirectory' |
'gitlens.diffWithBranch' |
'gitlens.diffWithNext' |
'gitlens.diffWithPrevious' |
'gitlens.diffLineWithPrevious' |
'gitlens.diffWithRevision' |
'gitlens.diffWithWorking' |
'gitlens.diffLineWithWorking' |
'gitlens.openChangedFiles' |
'gitlens.openBranchInRemote' |
'gitlens.openCommitInRemote' |
'gitlens.openFileInRemote' |
'gitlens.openInRemote' |
'gitlens.openRepoInRemote' |
'gitlens.resetSuppressedWarnings' |
'gitlens.showBlameHistory' |
'gitlens.showCommitSearch' |
'gitlens.showFileBlame' |
'gitlens.showFileHistory' |
'gitlens.showLastQuickPick' |
'gitlens.showLineBlame' |
'gitlens.showQuickBranchHistory' |
'gitlens.showQuickCommitDetails' |
'gitlens.showQuickCommitFileDetails' |
'gitlens.showQuickFileHistory' |
'gitlens.showQuickRepoHistory' |
'gitlens.showQuickRepoStatus' |
'gitlens.showQuickStashList' |
'gitlens.stashApply' |
'gitlens.stashDelete' |
'gitlens.stashSave' |
'gitlens.toggleCodeLens' |
'gitlens.toggleFileBlame' |
'gitlens.toggleFileRecentChanges' |
'gitlens.toggleLineBlame';
export type Commands = 'gitlens.closeUnchangedFiles' | 'gitlens.copyMessageToClipboard' | 'gitlens.copyShaToClipboard' |
'gitlens.diffDirectory' | 'gitlens.diffWithBranch' | 'gitlens.diffWithNext' | 'gitlens.diffWithPrevious' | 'gitlens.diffLineWithPrevious' | 'gitlens.diffWithWorking' | 'gitlens.diffLineWithWorking' |
'gitlens.openChangedFiles' | 'gitlens.openBranchInRemote' | 'gitlens.openCommitInRemote' | 'gitlens.openFileInRemote' | 'gitlens.openInRemote' | 'gitlens.openRepoInRemote' |
'gitlens.showBlameHistory' | 'gitlens.showCommitSearch' | 'gitlens.showFileBlame' | 'gitlens.showFileHistory' |
'gitlens.showLastQuickPick' | 'gitlens.showLineBlame' | 'gitlens.showQuickBranchHistory' |
'gitlens.showQuickCommitDetails' | 'gitlens.showQuickCommitFileDetails' |
'gitlens.showQuickFileHistory' | 'gitlens.showQuickRepoHistory' |
'gitlens.showQuickRepoStatus' | 'gitlens.showQuickStashList' |
'gitlens.stashApply' | 'gitlens.stashDelete' | 'gitlens.stashSave' |
'gitlens.toggleCodeLens' | 'gitlens.toggleFileBlame' | 'gitlens.toggleLineBlame';
export const Commands = {
ClearFileAnnotations: 'gitlens.clearFileAnnotations' as Commands,
CloseUnchangedFiles: 'gitlens.closeUnchangedFiles' as Commands,
CopyMessageToClipboard: 'gitlens.copyMessageToClipboard' as Commands,
CopyShaToClipboard: 'gitlens.copyShaToClipboard' as Commands,
@@ -54,7 +23,6 @@ export const Commands = {
DiffWithNext: 'gitlens.diffWithNext' as Commands,
DiffWithPrevious: 'gitlens.diffWithPrevious' as Commands,
DiffLineWithPrevious: 'gitlens.diffLineWithPrevious' as Commands,
DiffWithRevision: 'gitlens.diffWithRevision' as Commands,
DiffWithWorking: 'gitlens.diffWithWorking' as Commands,
DiffLineWithWorking: 'gitlens.diffLineWithWorking' as Commands,
OpenChangedFiles: 'gitlens.openChangedFiles' as Commands,
@@ -63,13 +31,12 @@ export const Commands = {
OpenFileInRemote: 'gitlens.openFileInRemote' as Commands,
OpenInRemote: 'gitlens.openInRemote' as Commands,
OpenRepoInRemote: 'gitlens.openRepoInRemote' as Commands,
ResetSuppressedWarnings: 'gitlens.resetSuppressedWarnings' as Commands,
ShowFileBlame: 'gitlens.showFileBlame' as Commands,
ShowLineBlame: 'gitlens.showLineBlame' as Commands,
ShowBlameHistory: 'gitlens.showBlameHistory' as Commands,
ShowCommitSearch: 'gitlens.showCommitSearch' as Commands,
ShowFileBlame: 'gitlens.showFileBlame' as Commands,
ShowFileHistory: 'gitlens.showFileHistory' as Commands,
ShowLastQuickPick: 'gitlens.showLastQuickPick' as Commands,
ShowLineBlame: 'gitlens.showLineBlame' as Commands,
ShowQuickCommitDetails: 'gitlens.showQuickCommitDetails' as Commands,
ShowQuickCommitFileDetails: 'gitlens.showQuickCommitFileDetails' as Commands,
ShowQuickFileHistory: 'gitlens.showQuickFileHistory' as Commands,
@@ -80,10 +47,9 @@ export const Commands = {
StashApply: 'gitlens.stashApply' as Commands,
StashDelete: 'gitlens.stashDelete' as Commands,
StashSave: 'gitlens.stashSave' as Commands,
ToggleCodeLens: 'gitlens.toggleCodeLens' as Commands,
ToggleFileBlame: 'gitlens.toggleFileBlame' as Commands,
ToggleFileRecentChanges: 'gitlens.toggleFileRecentChanges' as Commands,
ToggleLineBlame: 'gitlens.toggleLineBlame' as Commands
ToggleLineBlame: 'gitlens.toggleLineBlame' as Commands,
ToggleCodeLens: 'gitlens.toggleCodeLens' as Commands
};
export function getCommandUri(uri?: Uri, editor?: TextEditor): Uri | undefined {
@@ -92,68 +58,27 @@ export function getCommandUri(uri?: Uri, editor?: TextEditor): Uri | undefined {
return editor.document.uri;
}
export interface CommandContextParsingOptions {
editor: boolean;
uri: boolean;
}
export type CommandContext = 'gitlens:canToggleCodeLens' | 'gitlens:enabled' | 'gitlens:hasRemotes' | 'gitlens:isBlameable' | 'gitlens:isRepository' | 'gitlens:isTracked' | 'gitlens:key';
export const CommandContext = {
CanToggleCodeLens: 'gitlens:canToggleCodeLens' as CommandContext,
Enabled: 'gitlens:enabled' as CommandContext,
HasRemotes: 'gitlens:hasRemotes' as CommandContext,
IsBlameable: 'gitlens:isBlameable' as CommandContext,
IsRepository: 'gitlens:isRepository' as CommandContext,
IsTracked: 'gitlens:isTracked' as CommandContext,
Key: 'gitlens:key' as CommandContext
};
export interface CommandBaseContext {
editor?: TextEditor;
uri?: Uri;
}
export interface CommandScmGroupsContext extends CommandBaseContext {
type: 'scm-groups';
scmResourceGroups: SourceControlResourceGroup[];
}
export interface CommandScmStatesContext extends CommandBaseContext {
type: 'scm-states';
scmResourceStates: SourceControlResourceState[];
}
export interface CommandUnknownContext extends CommandBaseContext {
type: 'unknown';
}
export interface CommandUriContext extends CommandBaseContext {
type: 'uri';
}
export interface CommandViewContext extends CommandBaseContext {
type: 'view';
node: ExplorerNode;
}
export type CommandContext = CommandScmGroupsContext | CommandScmStatesContext | CommandUnknownContext | CommandUriContext | CommandViewContext;
function isScmResourceGroup(group: any): group is SourceControlResourceGroup {
if (group === undefined) return false;
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 {
if (state === undefined) return false;
return (state as SourceControlResourceState).resourceUri !== undefined;
}
function isTextEditor(editor: any): editor is TextEditor {
if (editor === undefined) return false;
return editor.id !== undefined && ((editor as TextEditor).edit !== undefined || (editor as TextEditor).document !== undefined);
export function setCommandContext(key: CommandContext | string, value: any) {
return commands.executeCommand(BuiltInCommands.SetContext, key, value);
}
export abstract class Command extends Disposable {
protected readonly contextParsingOptions: CommandContextParsingOptions = { editor: false, uri: false };
private _disposable: Disposable;
constructor(protected command: Commands) {
super(() => this.dispose());
this._disposable = commands.registerCommand(command, this._execute, this);
}
@@ -161,86 +86,46 @@ export abstract class Command extends Disposable {
this._disposable && this._disposable.dispose();
}
protected async preExecute(context: CommandContext, ...args: any[]): Promise<any> {
protected _execute(...args: any[]): any {
Telemetry.trackEvent(this.command);
return this.execute(...args);
}
abstract execute(...args: any[]): any;
}
protected _execute(...args: any[]): any {
export abstract class EditorCommand extends Disposable {
private _disposable: Disposable;
constructor(public readonly command: Commands) {
super(() => this.dispose());
this._disposable = commands.registerTextEditorCommand(command, this._execute, this);
}
dispose() {
this._disposable && this._disposable.dispose();
}
private _execute(editor: TextEditor, edit: TextEditorEdit, ...args: any[]): any {
Telemetry.trackEvent(this.command);
const [context, rest] = Command._parseContext(this.contextParsingOptions, ...args);
return this.preExecute(context, ...rest);
return this.execute(editor, edit, ...args);
}
private static _parseContext(options: CommandContextParsingOptions, ...args: any[]): [CommandContext, any[]] {
let editor: TextEditor | undefined = undefined;
let firstArg = args[0];
if (options.editor && (firstArg === undefined || isTextEditor(firstArg))) {
editor = firstArg;
args = args.slice(1);
firstArg = args[0];
}
if (options.uri && (firstArg === undefined || firstArg instanceof Uri)) {
const [uri, ...rest] = args as [Uri, any];
return [{ type: 'uri', editor: editor, uri: uri }, rest];
}
if (firstArg instanceof ExplorerNode) {
const [node, ...rest] = args as [ExplorerNode, any];
return [{ type: 'view', node: node, uri: node.uri }, rest];
}
if (isScmResourceState(firstArg)) {
const states = [];
let count = 0;
for (const arg of args) {
if (!isScmResourceState(arg)) break;
count++;
states.push(arg);
}
return [{ type: 'scm-states', scmResourceStates: states, uri: states[0].resourceUri }, args.slice(count)];
}
if (isScmResourceGroup(firstArg)) {
const groups = [];
let count = 0;
for (const arg of args) {
if (!isScmResourceGroup(arg)) break;
count++;
groups.push(arg);
}
return [{ type: 'scm-groups', scmResourceGroups: groups }, args.slice(count)];
}
return [{ type: 'unknown', editor: editor }, args];
}
abstract execute(editor: TextEditor, edit: TextEditorEdit, ...args: any[]): any;
}
export abstract class ActiveEditorCommand extends Command {
protected readonly contextParsingOptions: CommandContextParsingOptions = { editor: true, uri: true };
constructor(public readonly command: Commands) {
super(command);
}
protected async preExecute(context: CommandContext, ...args: any[]): Promise<any> {
return this.execute(context.editor, context.uri, ...args);
}
protected _execute(...args: any[]): any {
return super._execute(window.activeTextEditor, ...args);
}
abstract execute(editor?: TextEditor, ...args: any[]): any;
abstract execute(editor: TextEditor, ...args: any[]): any;
}
let lastCommand: { command: string, args: any[] } | undefined = undefined;
@@ -265,27 +150,6 @@ export abstract class ActiveEditorCachedCommand extends ActiveEditorCommand {
abstract execute(editor: TextEditor, ...args: any[]): any;
}
export abstract class EditorCommand extends Disposable {
private _disposable: Disposable;
constructor(public readonly command: Commands) {
super(() => this.dispose());
this._disposable = commands.registerTextEditorCommand(command, this._execute, this);
}
dispose() {
this._disposable && this._disposable.dispose();
}
private _execute(editor: TextEditor, edit: TextEditorEdit, ...args: any[]): any {
Telemetry.trackEvent(this.command);
return this.execute(editor, edit, ...args);
}
abstract execute(editor: TextEditor, edit: TextEditorEdit, ...args: any[]): any;
}
export async function openEditor(uri: Uri, options?: TextDocumentShowOptions): Promise<TextEditor | undefined> {
try {
const defaults: TextDocumentShowOptions = {

View File

@@ -17,12 +17,10 @@ export class CopyMessageToClipboardCommand extends ActiveEditorCommand {
super(Commands.CopyMessageToClipboard);
}
async execute(editor?: TextEditor, uri?: Uri, args: CopyMessageToClipboardCommandArgs = {}): Promise<any> {
async execute(editor: TextEditor, uri?: Uri, args: CopyMessageToClipboardCommandArgs = {}): Promise<any> {
uri = getCommandUri(uri, editor);
try {
args = { ...args };
// If we don't have an editor then get the message of the last commit to the branch
if (uri === undefined) {
if (!this.git.repoPath) return undefined;

View File

@@ -16,12 +16,10 @@ export class CopyShaToClipboardCommand extends ActiveEditorCommand {
super(Commands.CopyShaToClipboard);
}
async execute(editor?: TextEditor, uri?: Uri, args: CopyShaToClipboardCommandArgs = {}): Promise<any> {
async execute(editor: TextEditor, uri?: Uri, args: CopyShaToClipboardCommandArgs = {}): Promise<any> {
uri = getCommandUri(uri, editor);
try {
args = { ...args };
// If we don't have an editor then get the sha of the last commit to the branch
if (uri === undefined) {
if (!this.git.repoPath) return undefined;

View File

@@ -2,10 +2,9 @@
import { Iterables } from '../system';
import { commands, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { BuiltInCommands, GlyphChars } from '../constants';
import { BuiltInCommands } from '../constants';
import { GitService } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
import { BranchesQuickPick, CommandQuickPickItem } from '../quickPicks';
export interface DiffDirectoryCommandCommandArgs {
@@ -19,7 +18,7 @@ export class DiffDirectoryCommand extends ActiveEditorCommand {
super(Commands.DiffDirectory);
}
async execute(editor?: TextEditor, uri?: Uri, args: DiffDirectoryCommandCommandArgs = {}): Promise<any> {
async execute(editor: TextEditor, uri?: Uri, args: DiffDirectoryCommandCommandArgs = {}): Promise<any> {
const diffTool = await this.git.getConfig('diff.tool');
if (!diffTool) {
const result = await window.showWarningMessage(`Unable to open directory compare because there is no Git diff tool configured`, 'View Git Docs');
@@ -32,16 +31,14 @@ export class DiffDirectoryCommand extends ActiveEditorCommand {
try {
const repoPath = await this.git.getRepoPathFromUri(uri);
if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to open directory compare`);
if (!repoPath) return window.showWarningMessage(`Unable to open directory compare`);
if (!args.shaOrBranch1) {
args = { ...args };
const branches = await this.git.getBranches(repoPath);
const current = Iterables.find(branches, _ => _.current);
if (current == null) return window.showWarningMessage(`Unable to open directory compare`);
const pick = await BranchesQuickPick.show(branches, `Compare ${current.name} to ${GlyphChars.Ellipsis}`);
const pick = await BranchesQuickPick.show(branches, `Compare ${current.name} to \u2026`);
if (pick === undefined) return undefined;
if (pick instanceof CommandQuickPickItem) return pick.execute();

View File

@@ -1,12 +1,11 @@
'use strict';
import { commands, Range, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
import { commands, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { BuiltInCommands, GlyphChars } from '../constants';
import { BuiltInCommands } from '../constants';
import { DiffWithPreviousCommandArgs } from './diffWithPrevious';
import { DiffWithWorkingCommandArgs } from './diffWithWorking';
import { GitCommit, GitService, GitUri } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
import * as path from 'path';
export interface DiffLineWithPreviousCommandArgs {
@@ -21,16 +20,12 @@ export class DiffLineWithPreviousCommand extends ActiveEditorCommand {
super(Commands.DiffLineWithPrevious);
}
async execute(editor?: TextEditor, uri?: Uri, args: DiffLineWithPreviousCommandArgs = {}): Promise<any> {
async execute(editor: TextEditor, uri?: Uri, args: DiffLineWithPreviousCommandArgs = {}): Promise<any> {
uri = getCommandUri(uri, editor);
if (uri === undefined) return undefined;
const gitUri = await GitUri.fromUri(uri, this.git);
args = { ...args };
if (args.line === undefined) {
args.line = editor === undefined ? gitUri.offset : editor.selection.active.line;
}
args.line = args.line || (editor === undefined ? gitUri.offset : editor.selection.active.line);
if (args.commit === undefined || GitService.isUncommitted(args.commit.sha)) {
if (editor !== undefined && editor.document !== undefined && editor.document.isDirty) return undefined;
@@ -40,7 +35,7 @@ export class DiffLineWithPreviousCommand extends ActiveEditorCommand {
try {
const blame = await this.git.getBlameForLine(gitUri, blameline);
if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare');
if (blame === undefined) return window.showWarningMessage(`Unable to open compare. File is probably not under source control`);
args.commit = blame.commit;
@@ -77,18 +72,14 @@ export class DiffLineWithPreviousCommand extends ActiveEditorCommand {
this.git.getVersionedFile(args.commit.repoPath, args.commit.uri.fsPath, args.commit.sha)
]);
if (args.line !== undefined && args.line !== 0) {
if (args.showOptions === undefined) {
args.showOptions = {};
}
args.showOptions.selection = new Range(args.line, 0, args.line, 0);
}
await commands.executeCommand(BuiltInCommands.Diff,
Uri.file(lhs),
Uri.file(rhs),
`${path.basename(args.commit.uri.fsPath)} (${args.commit.shortSha}) ${GlyphChars.ArrowLeftRight} ${path.basename(gitUri.fsPath)} (${gitUri.shortSha})`,
`${path.basename(args.commit.uri.fsPath)} (${args.commit.shortSha}) \u2194 ${path.basename(gitUri.fsPath)} (${gitUri.shortSha})`,
args.showOptions);
// TODO: Figure out how to focus the left pane
return await commands.executeCommand(BuiltInCommands.RevealLine, { lineNumber: args.line, at: 'center' });
}
catch (ex) {
Logger.error(ex, 'DiffWithPreviousLineCommand', 'getVersionedFile');

View File

@@ -3,7 +3,6 @@ import { commands, TextDocumentShowOptions, TextEditor, Uri, window } from 'vsco
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { DiffWithWorkingCommandArgs } from './diffWithWorking';
import { GitCommit, GitService, GitUri } from '../gitService';
import { Messages } from '../messages';
import { Logger } from '../logger';
export interface DiffLineWithWorkingCommandArgs {
@@ -18,16 +17,12 @@ export class DiffLineWithWorkingCommand extends ActiveEditorCommand {
super(Commands.DiffLineWithWorking);
}
async execute(editor?: TextEditor, uri?: Uri, args: DiffLineWithWorkingCommandArgs = {}): Promise<any> {
async execute(editor: TextEditor, uri?: Uri, args: DiffLineWithWorkingCommandArgs = {}): Promise<any> {
uri = getCommandUri(uri, editor);
if (uri === undefined) return undefined;
const gitUri = await GitUri.fromUri(uri, this.git);
args = { ...args };
if (args.line === undefined) {
args.line = editor === undefined ? gitUri.offset : editor.selection.active.line;
}
args.line = args.line || (editor === undefined ? gitUri.offset : editor.selection.active.line);
if (args.commit === undefined || GitService.isUncommitted(args.commit.sha)) {
if (editor !== undefined && editor.document !== undefined && editor.document.isDirty) return undefined;
@@ -37,7 +32,7 @@ export class DiffLineWithWorkingCommand extends ActiveEditorCommand {
try {
const blame = await this.git.getBlameForLine(gitUri, blameline);
if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare');
if (blame === undefined) return window.showWarningMessage(`Unable to open compare. File is probably not under source control`);
args.commit = blame.commit;
// If the line is uncommitted, find the previous commit

View File

@@ -1,66 +1,58 @@
'use strict';
import { commands, Range, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { BuiltInCommands, GlyphChars } from '../constants';
import { GitService, GitUri } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
import { BranchesQuickPick, CommandQuickPickItem } from '../quickPicks';
import * as path from 'path';
export interface DiffWithBranchCommandArgs {
line?: number;
showOptions?: TextDocumentShowOptions;
goBackCommand?: CommandQuickPickItem;
}
export class DiffWithBranchCommand extends ActiveEditorCommand {
constructor(private git: GitService) {
super(Commands.DiffWithBranch);
}
async execute(editor?: TextEditor, uri?: Uri, args: DiffWithBranchCommandArgs = {}): Promise<any> {
uri = getCommandUri(uri, editor);
if (uri === undefined) return undefined;
args = { ...args };
if (args.line === undefined) {
args.line = editor === undefined ? 0 : editor.selection.active.line;
}
const gitUri = await GitUri.fromUri(uri, this.git);
if (!gitUri.repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to open branch compare`);
const branches = await this.git.getBranches(gitUri.repoPath);
const pick = await BranchesQuickPick.show(branches, `Compare ${path.basename(gitUri.fsPath)} to ${GlyphChars.Ellipsis}`, args.goBackCommand);
if (pick === undefined) return undefined;
if (pick instanceof CommandQuickPickItem) return pick.execute();
const branch = pick.branch.name;
if (branch === undefined) return undefined;
try {
const compare = await this.git.getVersionedFile(gitUri.repoPath, gitUri.fsPath, branch);
if (args.line !== undefined && args.line !== 0) {
if (args.showOptions === undefined) {
args.showOptions = {};
}
args.showOptions.selection = new Range(args.line, 0, args.line, 0);
}
await commands.executeCommand(BuiltInCommands.Diff,
Uri.file(compare),
gitUri.fileUri(),
`${path.basename(gitUri.fsPath)} (${branch}) ${GlyphChars.ArrowLeftRight} ${path.basename(gitUri.fsPath)}`,
args.showOptions);
}
catch (ex) {
Logger.error(ex, 'DiffWithBranchCommand', 'getVersionedFile');
return window.showErrorMessage(`Unable to open branch compare. See output channel for more details`);
}
}
'use strict';
import { commands, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { BuiltInCommands } from '../constants';
import { GitService, GitUri } from '../gitService';
import { Logger } from '../logger';
import { BranchesQuickPick, CommandQuickPickItem } from '../quickPicks';
import * as path from 'path';
export interface DiffWithBranchCommandArgs {
line?: number;
showOptions?: TextDocumentShowOptions;
goBackCommand?: CommandQuickPickItem;
}
export class DiffWithBranchCommand extends ActiveEditorCommand {
constructor(private git: GitService) {
super(Commands.DiffWithBranch);
}
async execute(editor: TextEditor, uri?: Uri, args: DiffWithBranchCommandArgs = {}): Promise<any> {
uri = getCommandUri(uri, editor);
if (uri === undefined) return undefined;
args.line = args.line || (editor === undefined ? 0 : editor.selection.active.line);
const gitUri = await GitUri.fromUri(uri, this.git);
if (!gitUri.repoPath) return window.showWarningMessage(`Unable to open branch compare`);
const branches = await this.git.getBranches(gitUri.repoPath);
const pick = await BranchesQuickPick.show(branches, `Compare ${path.basename(gitUri.fsPath)} to \u2026`, args.goBackCommand);
if (pick === undefined) return undefined;
if (pick instanceof CommandQuickPickItem) return pick.execute();
const branch = pick.branch.name;
if (branch === undefined) return undefined;
try {
const compare = await this.git.getVersionedFile(gitUri.repoPath, gitUri.fsPath, branch);
await commands.executeCommand(BuiltInCommands.Diff,
Uri.file(compare),
gitUri.fileUri(),
`${path.basename(gitUri.fsPath)} (${branch}) \u2194 ${path.basename(gitUri.fsPath)}`,
args.showOptions);
// TODO: Figure out how to focus the left pane
return await commands.executeCommand(BuiltInCommands.RevealLine, { lineNumber: args.line, at: 'center' });
}
catch (ex) {
Logger.error(ex, 'DiffWithBranchCommand', 'getVersionedFile');
return window.showErrorMessage(`Unable to open branch compare. See output channel for more details`);
}
}
}

View File

@@ -2,10 +2,9 @@
import { Iterables } from '../system';
import { commands, Range, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { BuiltInCommands, GlyphChars } from '../constants';
import { BuiltInCommands } from '../constants';
import { GitLogCommit, GitService, GitUri } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
import * as path from 'path';
export interface DiffWithNextCommandArgs {
@@ -21,14 +20,11 @@ export class DiffWithNextCommand extends ActiveEditorCommand {
super(Commands.DiffWithNext);
}
async execute(editor?: TextEditor, uri?: Uri, args: DiffWithNextCommandArgs = {}): Promise<any> {
async execute(editor: TextEditor, uri?: Uri, args: DiffWithNextCommandArgs = {}): Promise<any> {
uri = getCommandUri(uri, editor);
if (uri === undefined) return undefined;
args = { ...args };
if (args.line === undefined) {
args.line = editor === undefined ? 0 : editor.selection.active.line;
}
args.line = args.line || (editor === undefined ? 0 : editor.selection.active.line);
if (args.commit === undefined || !(args.commit instanceof GitLogCommit) || args.range !== undefined) {
const gitUri = await GitUri.fromUri(uri, this.git);
@@ -41,8 +37,8 @@ export class DiffWithNextCommand extends ActiveEditorCommand {
const sha = args.commit === undefined ? gitUri.sha : args.commit.sha;
const log = await this.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, undefined, { maxCount: sha !== undefined ? undefined : 2, range: args.range! });
if (log === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare');
const log = await this.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, undefined, sha ? undefined : 2, args.range!);
if (log === undefined) return window.showWarningMessage(`Unable to open compare. File is probably not under source control`);
args.commit = (sha && log.commits.get(sha)) || Iterables.first(log.commits.values());
}
@@ -60,18 +56,14 @@ export class DiffWithNextCommand extends ActiveEditorCommand {
this.git.getVersionedFile(args.commit.repoPath, args.commit.uri.fsPath, args.commit.sha)
]);
if (args.line !== undefined && args.line !== 0) {
if (args.showOptions === undefined) {
args.showOptions = {};
}
args.showOptions.selection = new Range(args.line, 0, args.line, 0);
}
await commands.executeCommand(BuiltInCommands.Diff,
Uri.file(lhs),
Uri.file(rhs),
`${path.basename(args.commit.uri.fsPath)} (${args.commit.shortSha}) ${GlyphChars.ArrowLeftRight} ${path.basename(args.commit.nextUri.fsPath)} (${args.commit.nextShortSha})`,
`${path.basename(args.commit.uri.fsPath)} (${args.commit.shortSha}) \u2194 ${path.basename(args.commit.nextUri.fsPath)} (${args.commit.nextShortSha})`,
args.showOptions);
// TODO: Figure out how to focus the left pane
return await commands.executeCommand(BuiltInCommands.RevealLine, { lineNumber: args.line, at: 'center' });
}
catch (ex) {
Logger.error(ex, 'DiffWithNextCommand', 'getVersionedFile');

View File

@@ -2,11 +2,11 @@
import { Iterables } from '../system';
import { commands, Range, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { BuiltInCommands, GlyphChars } from '../constants';
import { BuiltInCommands } from '../constants';
import { DiffWithWorkingCommandArgs } from './diffWithWorking';
import { GitCommit, GitService, GitUri } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
import * as moment from 'moment';
import * as path from 'path';
export interface DiffWithPreviousCommandArgs {
@@ -22,28 +22,25 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand {
super(Commands.DiffWithPrevious);
}
async execute(editor?: TextEditor, uri?: Uri, args: DiffWithPreviousCommandArgs = {}): Promise<any> {
async execute(editor: TextEditor, uri?: Uri, args: DiffWithPreviousCommandArgs = {}): Promise<any> {
uri = getCommandUri(uri, editor);
if (uri === undefined) return undefined;
args = { ...args };
if (args.line === undefined) {
args.line = editor === undefined ? 0 : editor.selection.active.line;
}
args.line = args.line || (editor === undefined ? 0 : editor.selection.active.line);
if (args.commit === undefined || args.commit.type !== 'file' || args.range !== undefined) {
if (args.commit === undefined || (args.commit.type !== 'file') || args.range !== undefined) {
const gitUri = await GitUri.fromUri(uri, this.git);
try {
const sha = args.commit === undefined ? gitUri.sha : args.commit.sha;
const log = await this.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, sha, { maxCount: 2, range: args.range!, skipMerges: true });
if (log === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare');
const log = await this.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, undefined, sha ? undefined : 2, args.range!);
if (log === undefined) return window.showWarningMessage(`Unable to open compare. File is probably not under source control`);
args.commit = (sha && log.commits.get(sha)) || Iterables.first(log.commits.values());
// If the sha is missing and the file is uncommitted, then treat it as a DiffWithWorking
if (gitUri.sha === undefined && await this.git.isFileUncommitted(gitUri)) return commands.executeCommand(Commands.DiffWithWorking, uri, { commit: args.commit, showOptions: args.showOptions } as DiffWithWorkingCommandArgs);
// If the sha is missing, treat it as a DiffWithWorking
if (gitUri.sha === undefined) return commands.executeCommand(Commands.DiffWithWorking, uri, { commit: args.commit, showOptions: args.showOptions } as DiffWithWorkingCommandArgs);
}
catch (ex) {
Logger.error(ex, 'DiffWithPreviousCommand', `getLogForFile(${gitUri.repoPath}, ${gitUri.fsPath})`);
@@ -51,7 +48,7 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand {
}
}
if (args.commit.previousSha === undefined) return Messages.showCommitHasNoPreviousCommitWarningMessage(args.commit);
if (args.commit.previousSha === undefined) return window.showInformationMessage(`Commit ${args.commit.shortSha} (${args.commit.author}, ${moment(args.commit.date).fromNow()}) has no previous commit`);
try {
const [rhs, lhs] = await Promise.all([
@@ -59,18 +56,14 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand {
this.git.getVersionedFile(args.commit.repoPath, args.commit.previousUri.fsPath, args.commit.previousSha)
]);
if (args.line !== undefined && args.line !== 0) {
if (args.showOptions === undefined) {
args.showOptions = {};
}
args.showOptions.selection = new Range(args.line, 0, args.line, 0);
}
await commands.executeCommand(BuiltInCommands.Diff,
Uri.file(lhs),
Uri.file(rhs),
`${path.basename(args.commit.previousUri.fsPath)} (${args.commit.previousShortSha}) ${GlyphChars.ArrowLeftRight} ${path.basename(args.commit.uri.fsPath)} (${args.commit.shortSha})`,
`${path.basename(args.commit.previousUri.fsPath)} (${args.commit.previousShortSha}) \u2194 ${path.basename(args.commit.uri.fsPath)} (${args.commit.shortSha})`,
args.showOptions);
// TODO: Figure out how to focus the left pane
return await commands.executeCommand(BuiltInCommands.RevealLine, { lineNumber: args.line, at: 'center' });
}
catch (ex) {
Logger.error(ex, 'DiffWithPreviousCommand', 'getVersionedFile');

View File

@@ -1,69 +0,0 @@
'use strict';
import { commands, Range, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { BuiltInCommands, GlyphChars } from '../constants';
import { GitService, GitUri } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
import { CommandQuickPickItem, FileHistoryQuickPick } from '../quickPicks';
import * as path from 'path';
export interface DiffWithRevisionCommandArgs {
line?: number;
maxCount?: number;
showOptions?: TextDocumentShowOptions;
}
export class DiffWithRevisionCommand extends ActiveEditorCommand {
constructor(private git: GitService) {
super(Commands.DiffWithRevision);
}
async execute(editor?: TextEditor, uri?: Uri, args: DiffWithRevisionCommandArgs = {}): Promise<any> {
uri = getCommandUri(uri, editor);
if (uri === undefined) return undefined;
args = { ...args };
if (args.line === undefined) {
args.line = editor === undefined ? 0 : editor.selection.active.line;
}
const gitUri = await GitUri.fromUri(uri, this.git);
if (args.maxCount == null) {
args.maxCount = this.git.config.advanced.maxQuickHistory;
}
const progressCancellation = FileHistoryQuickPick.showProgress(gitUri);
try {
const log = await this.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, gitUri.sha, { maxCount: args.maxCount });
if (log === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open history compare');
if (progressCancellation.token.isCancellationRequested) return undefined;
const pick = await FileHistoryQuickPick.show(this.git, log, gitUri, progressCancellation, { pickerOnly: true });
if (pick === undefined) return undefined;
if (pick instanceof CommandQuickPickItem) return pick.execute();
const compare = await this.git.getVersionedFile(gitUri.repoPath, gitUri.fsPath, pick.commit.sha);
if (args.line !== undefined && args.line !== 0) {
if (args.showOptions === undefined) {
args.showOptions = {};
}
args.showOptions.selection = new Range(args.line, 0, args.line, 0);
}
await commands.executeCommand(BuiltInCommands.Diff,
Uri.file(compare),
gitUri.fileUri(),
`${path.basename(gitUri.fsPath)} (${pick.commit.shortSha}) ${GlyphChars.ArrowLeftRight} ${path.basename(gitUri.fsPath)}`,
args.showOptions);
}
catch (ex) {
Logger.error(ex, 'DiffWithRevisionCommand', 'getVersionedFile');
return window.showErrorMessage(`Unable to open history compare. See output channel for more details`);
}
}
}

View File

@@ -1,10 +1,9 @@
'use strict';
import { commands, Range, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
import { commands, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { BuiltInCommands, GlyphChars } from '../constants';
import { BuiltInCommands } from '../constants';
import { GitCommit, GitService, GitUri } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
import * as path from 'path';
export interface DiffWithWorkingCommandArgs {
@@ -19,14 +18,11 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand {
super(Commands.DiffWithWorking);
}
async execute(editor?: TextEditor, uri?: Uri, args: DiffWithWorkingCommandArgs = {}): Promise<any> {
async execute(editor: TextEditor, uri?: Uri, args: DiffWithWorkingCommandArgs = {}): Promise<any> {
uri = getCommandUri(uri, editor);
if (uri === undefined) return undefined;
args = { ...args };
if (args.line === undefined) {
args.line = editor === undefined ? 0 : editor.selection.active.line;
}
args.line = args.line || (editor === undefined ? 0 : editor.selection.active.line);
if (args.commit === undefined || GitService.isUncommitted(args.commit.sha)) {
const gitUri = await GitUri.fromUri(uri, this.git);
@@ -35,7 +31,7 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand {
try {
args.commit = await this.git.getLogCommit(gitUri.repoPath, gitUri.fsPath, gitUri.sha, { firstIfMissing: true });
if (args.commit === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare');
if (args.commit === undefined) return window.showWarningMessage(`Unable to open compare. File is probably not under source control`);
}
catch (ex) {
Logger.error(ex, 'DiffWithWorkingCommand', `getLogCommit(${gitUri.repoPath}, ${gitUri.fsPath}, ${gitUri.sha})`);
@@ -51,18 +47,14 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand {
try {
const compare = await this.git.getVersionedFile(args.commit.repoPath, args.commit.uri.fsPath, args.commit.sha);
if (args.line !== undefined && args.line !== 0) {
if (args.showOptions === undefined) {
args.showOptions = {};
}
args.showOptions.selection = new Range(args.line, 0, args.line, 0);
}
await commands.executeCommand(BuiltInCommands.Diff,
Uri.file(compare),
Uri.file(path.resolve(gitUri.repoPath, workingFileName)),
`${path.basename(args.commit.uri.fsPath)} (${args.commit.shortSha}) ${GlyphChars.ArrowLeftRight} ${path.basename(workingFileName)}`,
`${path.basename(args.commit.uri.fsPath)} (${args.commit.shortSha}) \u2194 ${path.basename(workingFileName)}`,
args.showOptions);
// TODO: Figure out how to focus the left pane
return await commands.executeCommand(BuiltInCommands.RevealLine, { lineNumber: args.line, at: 'center' });
}
catch (ex) {
Logger.error(ex, 'DiffWithWorkingCommand', 'getVersionedFile');

View File

@@ -1,143 +1,140 @@
'use strict';
import { commands, Disposable } from 'vscode';
import { CommandContext, ExtensionKey, setCommandContext } from './constants';
import { Logger } from './logger';
export declare interface KeyCommand {
onDidPressKey?(key: Keys): Promise<{} | undefined>;
}
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 declare interface KeyMapping {
[id: string]: (KeyCommand | (() => Promise<KeyCommand>) | undefined);
}
const mappings: KeyMapping[] = [];
let _instance: Keyboard;
export class KeyboardScope extends Disposable {
constructor(private mapping: KeyMapping) {
super(() => this.dispose());
for (const key in mapping) {
mapping[key] = mapping[key] || keyNoopCommand;
}
}
async dispose() {
const index = mappings.indexOf(this.mapping);
Logger.log('KeyboardScope.dispose', mappings.length, index);
if (index === (mappings.length - 1)) {
mappings.pop();
await this.updateKeyCommandsContext(mappings[mappings.length - 1]);
}
else {
mappings.splice(index, 1);
}
}
async begin() {
mappings.push(this.mapping);
await this.updateKeyCommandsContext(this.mapping);
return this;
}
async clearKeyCommand(key: Keys) {
const mapping = mappings[mappings.length - 1];
if (mapping !== this.mapping || !mapping[key]) return;
Logger.log('KeyboardScope.clearKeyCommand', mappings.length, key);
mapping[key] = undefined;
await setCommandContext(`${CommandContext.Key}:${key}`, false);
}
async setKeyCommand(key: Keys, command: KeyCommand | (() => Promise<KeyCommand>)) {
const mapping = mappings[mappings.length - 1];
if (mapping !== this.mapping) return;
Logger.log('KeyboardScope.setKeyCommand', mappings.length, key, !!mapping[key]);
if (!mapping[key]) {
mapping[key] = command;
await setCommandContext(`${CommandContext.Key}:${key}`, true);
}
else {
mapping[key] = command;
}
}
private async updateKeyCommandsContext(mapping: KeyMapping) {
const promises = [];
for (const key of keys) {
promises.push(setCommandContext(`${CommandContext.Key}:${key}`, !!(mapping && mapping[key])));
}
await Promise.all(promises);
}
}
export class Keyboard extends Disposable {
static get instance(): Keyboard {
return _instance;
}
private _disposable: Disposable;
constructor() {
super(() => this.dispose());
const subscriptions: Disposable[] = [];
for (const key of keys) {
subscriptions.push(commands.registerCommand(`${ExtensionKey}.key.${key}`, () => this.execute(key), this));
}
this._disposable = Disposable.from(...subscriptions);
_instance = this;
}
dispose() {
this._disposable && this._disposable.dispose();
}
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();
}
async execute(key: Keys): Promise<{} | undefined> {
if (!mappings.length) return undefined;
try {
const mapping = mappings[mappings.length - 1];
let command = mapping[key] as KeyCommand | (() => Promise<KeyCommand>);
if (typeof command === 'function') {
command = await command();
}
if (!command || typeof command.onDidPressKey !== 'function') return undefined;
Logger.log('Keyboard.execute', key);
return await command.onDidPressKey(key);
}
catch (ex) {
Logger.error(ex, 'Keyboard.execute');
return undefined;
}
}
'use strict';
import { commands, Disposable } from 'vscode';
import { CommandContext, setCommandContext } from './common';
import { ExtensionKey } from '../constants';
import { QuickPickItem } from '../quickPicks';
import { Logger } from '../logger';
const keyNoopCommand = Object.create(null) as QuickPickItem;
export { keyNoopCommand as KeyNoopCommand };
export declare type Keys = 'left' | 'right' | ',' | '.';
export const keys: Keys[] = [
'left',
'right',
',',
'.'
];
export declare interface KeyMapping {
[id: string]: (QuickPickItem | (() => Promise<QuickPickItem>) | undefined);
}
const mappings: KeyMapping[] = [];
let _instance: Keyboard;
export class KeyboardScope extends Disposable {
constructor(private mapping: KeyMapping) {
super(() => this.dispose());
for (const key in mapping) {
mapping[key] = mapping[key] || keyNoopCommand;
}
}
async dispose() {
const index = mappings.indexOf(this.mapping);
Logger.log('KeyboardScope.dispose', mappings.length, index);
if (index === (mappings.length - 1)) {
mappings.pop();
await this.updateKeyCommandsContext(mappings[mappings.length - 1]);
}
else {
mappings.splice(index, 1);
}
}
async begin() {
mappings.push(this.mapping);
await this.updateKeyCommandsContext(this.mapping);
return this;
}
async clearKeyCommand(key: Keys) {
const mapping = mappings[mappings.length - 1];
if (mapping !== this.mapping || !mapping[key]) return;
Logger.log('KeyboardScope.clearKeyCommand', mappings.length, key);
mapping[key] = undefined;
await setCommandContext(`${CommandContext.Key}:${key}`, false);
}
async setKeyCommand(key: Keys, command: QuickPickItem | (() => Promise<QuickPickItem>)) {
const mapping = mappings[mappings.length - 1];
if (mapping !== this.mapping) return;
Logger.log('KeyboardScope.setKeyCommand', mappings.length, key, !!mapping[key]);
if (!mapping[key]) {
mapping[key] = command;
await setCommandContext(`${CommandContext.Key}:${key}`, true);
}
else {
mapping[key] = command;
}
}
private async updateKeyCommandsContext(mapping: KeyMapping) {
const promises = [];
for (const key of keys) {
promises.push(setCommandContext(`${CommandContext.Key}:${key}`, !!(mapping && mapping[key])));
}
await Promise.all(promises);
}
}
export class Keyboard extends Disposable {
static get instance(): Keyboard {
return _instance;
}
private _disposable: Disposable;
constructor() {
super(() => this.dispose());
const subscriptions: Disposable[] = [];
for (const key of keys) {
subscriptions.push(commands.registerCommand(`${ExtensionKey}.key.${key}`, () => this.execute(key), this));
}
this._disposable = Disposable.from(...subscriptions);
_instance = this;
}
dispose() {
this._disposable && this._disposable.dispose();
}
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();
}
async execute(key: Keys): Promise<{} | undefined> {
if (!mappings.length) return undefined;
try {
const mapping = mappings[mappings.length - 1];
let command = mapping[key] as QuickPickItem | (() => Promise<QuickPickItem>);
if (typeof command === 'function') {
command = await command();
}
if (!command || typeof command.onDidPressKey !== 'function') return undefined;
Logger.log('Keyboard.execute', key);
return await command.onDidPressKey(key);
}
catch (ex) {
Logger.error(ex, 'Keyboard.execute');
return undefined;
}
}
}

View File

@@ -1,8 +1,7 @@
'use strict';
import { Arrays } from '../system';
import { commands, TextEditor, Uri, window } from 'vscode';
import { commands, TextEditor, TextEditorEdit, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { GlyphChars } from '../constants';
import { GitService, GitUri } from '../gitService';
import { Logger } from '../logger';
import { BranchesQuickPick, CommandQuickPickItem } from '../quickPicks';
@@ -18,7 +17,7 @@ export class OpenBranchInRemoteCommand extends ActiveEditorCommand {
super(Commands.OpenBranchInRemote);
}
async execute(editor?: TextEditor, uri?: Uri, args: OpenBranchInRemoteCommandArgs = {}) {
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, args: OpenBranchInRemoteCommandArgs = {}) {
uri = getCommandUri(uri, editor);
const gitUri = uri && await GitUri.fromUri(uri, this.git);
@@ -28,11 +27,9 @@ export class OpenBranchInRemoteCommand extends ActiveEditorCommand {
try {
if (args.branch === undefined) {
args = { ...args };
const branches = await this.git.getBranches(repoPath);
const pick = await BranchesQuickPick.show(branches, `Show history for branch${GlyphChars.Ellipsis}`);
const pick = await BranchesQuickPick.show(branches, `Show history for branch\u2026`);
if (pick === undefined) return undefined;
if (pick instanceof CommandQuickPickItem) return undefined;

View File

@@ -3,7 +3,6 @@ import { TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri, openEditor } from './common';
import { GitService } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
export interface OpenChangedFilesCommandArgs {
uris?: Uri[];
@@ -15,15 +14,13 @@ export class OpenChangedFilesCommand extends ActiveEditorCommand {
super(Commands.OpenChangedFiles);
}
async execute(editor?: TextEditor, uri?: Uri, args: OpenChangedFilesCommandArgs = {}) {
async execute(editor: TextEditor, uri?: Uri, args: OpenChangedFilesCommandArgs = {}) {
uri = getCommandUri(uri, editor);
try {
if (args.uris === undefined) {
args = { ...args };
const repoPath = await this.git.getRepoPathFromUri(uri);
if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to open changed files`);
if (!repoPath) return window.showWarningMessage(`Unable to open changed files`);
const status = await this.git.getStatusForRepo(repoPath);
if (status === undefined) return window.showWarningMessage(`Unable to open changed files`);

View File

@@ -1,16 +1,10 @@
'use strict';
import { Arrays } from '../system';
import { commands, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, CommandContext, Commands, getCommandUri } from './common';
import { GitBlameCommit, GitService, GitUri } from '../gitService';
import { commands, TextEditor, TextEditorEdit, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { GitCommit, GitService, GitUri } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
import { OpenInRemoteCommandArgs } from './openInRemote';
import { CommitNode } from '../views/explorerNodes';
export interface OpenCommitInRemoteCommandArgs {
sha?: string;
}
export class OpenCommitInRemoteCommand extends ActiveEditorCommand {
@@ -18,17 +12,7 @@ export class OpenCommitInRemoteCommand extends ActiveEditorCommand {
super(Commands.OpenCommitInRemote);
}
protected async preExecute(context: CommandContext, args: OpenCommitInRemoteCommandArgs = {}): Promise<any> {
if (context.type === 'view' && context.node instanceof CommitNode) {
args = { ...args };
args.sha = context.node.commit.sha;
return this.execute(context.editor, context.node.commit.uri, args);
}
return this.execute(context.editor, context.uri, args);
}
async execute(editor?: TextEditor, uri?: Uri, args: OpenCommitInRemoteCommandArgs = {}) {
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri) {
uri = getCommandUri(uri, editor);
if (uri === undefined) return undefined;
if (editor !== undefined && editor.document !== undefined && editor.document.isDirty) return undefined;
@@ -36,29 +20,26 @@ export class OpenCommitInRemoteCommand extends ActiveEditorCommand {
const gitUri = await GitUri.fromUri(uri, this.git);
if (!gitUri.repoPath) return undefined;
const line = editor === undefined ? gitUri.offset : editor.selection.active.line;
try {
if (args.sha === undefined) {
const line = editor === undefined ? gitUri.offset : editor.selection.active.line;
const blameline = line - gitUri.offset;
if (blameline < 0) return undefined;
const blameline = line - gitUri.offset;
if (blameline < 0) return undefined;
const blame = await this.git.getBlameForLine(gitUri, blameline);
if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open commit in remote provider');
const blame = await this.git.getBlameForLine(gitUri, blameline);
if (blame === undefined) return window.showWarningMessage(`Unable to open commit in remote provider. File is probably not under source control`);
let commit = blame.commit;
// If the line is uncommitted, find the previous commit
if (commit.isUncommitted) {
commit = new GitBlameCommit(commit.repoPath, commit.previousSha!, commit.previousFileName!, commit.author, commit.date, commit.message, []);
}
args.sha = commit.sha;
let commit = blame.commit;
// If the line is uncommitted, find the previous commit
if (commit.isUncommitted) {
commit = new GitCommit(commit.type, commit.repoPath, commit.previousSha!, commit.previousFileName!, commit.author, commit.date, commit.message);
}
const remotes = Arrays.uniqueBy(await this.git.getRemotes(gitUri.repoPath), _ => _.url, _ => !!_.provider);
return commands.executeCommand(Commands.OpenInRemote, uri, {
resource: {
type: 'commit',
sha: args.sha
sha: commit.sha
},
remotes
} as OpenInRemoteCommandArgs);

View File

@@ -1,6 +1,6 @@
'use strict';
import { Arrays } from '../system';
import { commands, Range, TextEditor, Uri, window } from 'vscode';
import { commands, Range, TextEditor, TextEditorEdit, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { GitService, GitUri } from '../gitService';
import { Logger } from '../logger';
@@ -12,7 +12,7 @@ export class OpenFileInRemoteCommand extends ActiveEditorCommand {
super(Commands.OpenFileInRemote);
}
async execute(editor?: TextEditor, uri?: Uri) {
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri) {
uri = getCommandUri(uri, editor);
if (uri === undefined) return undefined;

View File

@@ -1,8 +1,6 @@
'use strict';
import { Strings } from '../system';
import { TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { GlyphChars } from '../constants';
import { GitLogCommit, GitRemote, RemoteResource } from '../gitService';
import { Logger } from '../logger';
import { CommandQuickPickItem, OpenRemoteCommandQuickPickItem, RemotesQuickPick } from '../quickPicks';
@@ -23,10 +21,9 @@ export class OpenInRemoteCommand extends ActiveEditorCommand {
async execute(editor: TextEditor, uri?: Uri, args: OpenInRemoteCommandArgs = {}) {
uri = getCommandUri(uri, editor);
args = { ...args };
if (args.remotes === undefined || args.resource === undefined) return undefined;
try {
if (args.remotes === undefined || args.resource === undefined) return undefined;
if (args.remotes.length === 1) {
const command = new OpenRemoteCommandQuickPickItem(args.remotes[0], args.resource);
return command.execute();
@@ -45,35 +42,35 @@ export class OpenInRemoteCommand extends ActiveEditorCommand {
args.remotes = [remote];
}
}
placeHolder = `open ${args.resource.branch} branch in${GlyphChars.Ellipsis}`;
placeHolder = `open ${args.resource.branch} branch in\u2026`;
break;
case 'commit':
const shortSha = args.resource.sha.substring(0, 8);
placeHolder = `open commit ${shortSha} in${GlyphChars.Ellipsis}`;
placeHolder = `open commit ${shortSha} in\u2026`;
break;
case 'file':
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} \u00a0\u2022\u00a0 ${args.resource.commit.previousShortSha} in\u2026`;
}
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} \u00a0\u2022\u00a0 ${args.resource.commit.shortSha} in\u2026`;
}
}
else {
const shortFileSha = args.resource.sha === undefined ? '' : args.resource.sha.substring(0, 8);
const shaSuffix = shortFileSha ? ` ${Strings.pad(GlyphChars.Dot, 1, 1)} ${shortFileSha}` : '';
const shaSuffix = shortFileSha ? ` \u00a0\u2022\u00a0 ${shortFileSha}` : '';
placeHolder = `open ${args.resource.fileName}${shaSuffix} in${GlyphChars.Ellipsis}`;
placeHolder = `open ${args.resource.fileName}${shaSuffix} in\u2026`;
}
break;
case 'working-file':
placeHolder = `open ${args.resource.fileName} in${GlyphChars.Ellipsis}`;
placeHolder = `open ${args.resource.fileName} in\u2026`;
break;
}

View File

@@ -1,6 +1,6 @@
'use strict';
import { Arrays } from '../system';
import { commands, TextEditor, Uri, window } from 'vscode';
import { commands, TextEditor, TextEditorEdit, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { GitService, GitUri } from '../gitService';
import { Logger } from '../logger';
@@ -12,7 +12,7 @@ export class OpenRepoInRemoteCommand extends ActiveEditorCommand {
super(Commands.OpenRepoInRemote);
}
async execute(editor?: TextEditor, uri?: Uri) {
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri) {
uri = getCommandUri(uri, editor);
const gitUri = uri && await GitUri.fromUri(uri, this.git);

View File

@@ -1,18 +0,0 @@
'use strict';
import { Objects } from '../system';
import { ExtensionContext } from 'vscode';
import { Command, Commands } from './common';
import { SuppressedKeys } from '../messages';
export class ResetSuppressedWarningsCommand extends Command {
constructor(private context: ExtensionContext) {
super(Commands.ResetSuppressedWarnings);
}
async execute() {
for (const key of Objects.values<string>(SuppressedKeys)) {
await this.context.globalState.update(key, false);
}
}
}

View File

@@ -3,7 +3,6 @@ import { commands, Position, Range, TextEditor, TextEditorEdit, Uri, window } fr
import { Commands, EditorCommand, getCommandUri } from './common';
import { BuiltInCommands } from '../constants';
import { GitService, GitUri } from '../gitService';
import { Messages } from '../messages';
import { Logger } from '../logger';
export interface ShowBlameHistoryCommandArgs {
@@ -24,8 +23,6 @@ export class ShowBlameHistoryCommand extends EditorCommand {
if (uri === undefined) return undefined;
if (args.range == null || args.position == null) {
args = { ...args };
// If the command is executed manually -- treat it as a click on the root lens (i.e. show blame for the whole file)
args.range = editor.document.validateRange(new Range(0, 0, 1000000, 1000000));
args.position = editor.document.validateRange(new Range(0, 0, 0, 1000000)).start;
@@ -35,7 +32,7 @@ export class ShowBlameHistoryCommand extends EditorCommand {
try {
const locations = await this.git.getBlameLocations(gitUri, args.range, args.sha, args.line);
if (locations === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show blame history');
if (locations === undefined) return window.showWarningMessage(`Unable to show blame history. File is probably not under source control`);
return commands.executeCommand(BuiltInCommands.ShowReferences, uri, args.position, locations);
}

View File

@@ -1,11 +1,8 @@
'use strict';
import { Strings } from '../system';
import { commands, InputBoxOptions, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common';
import { GlyphChars } from '../constants';
import { GitRepoSearchBy, GitService, GitUri } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
import { CommandQuickPickItem, CommitsQuickPick } from '../quickPicks';
import { ShowQuickCommitDetailsCommandArgs } from './showQuickCommitDetails';
import { paste } from 'copy-paste';
@@ -30,15 +27,14 @@ export class ShowCommitSearchCommand extends ActiveEditorCachedCommand {
super(Commands.ShowCommitSearch);
}
async execute(editor?: TextEditor, uri?: Uri, args: ShowCommitSearchCommandArgs = {}) {
async execute(editor: TextEditor, uri?: Uri, args: ShowCommitSearchCommandArgs = {}) {
uri = getCommandUri(uri, editor);
const gitUri = uri === undefined ? undefined : await GitUri.fromUri(uri, this.git);
const repoPath = gitUri === undefined ? this.git.repoPath : gitUri.repoPath;
if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to show commit search`);
if (!repoPath) return window.showWarningMessage(`Unable to show commit search`);
args = { ...args };
if (!args.search || args.searchBy == null) {
try {
if (!args.search) {
@@ -96,17 +92,14 @@ export class ShowCommitSearchCommand extends ActiveEditorCachedCommand {
originalSearch = `@${args.search}`;
placeHolder = `commits with author matching '${args.search}'`;
break;
case GitRepoSearchBy.Files:
originalSearch = `:${args.search}`;
placeHolder = `commits with files matching '${args.search}'`;
break;
case GitRepoSearchBy.Message:
originalSearch = args.search;
placeHolder = `commits with message matching '${args.search}'`;
break;
case GitRepoSearchBy.Sha:
originalSearch = `#${args.search}`;
placeHolder = `commits with id matching '${args.search}'`;
@@ -115,8 +108,8 @@ export class ShowCommitSearchCommand extends ActiveEditorCachedCommand {
// 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 commit search`
label: `go back \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to commit search`
}, Commands.ShowCommitSearch, [
uri,
{
@@ -136,8 +129,8 @@ export class ShowCommitSearchCommand extends ActiveEditorCachedCommand {
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 ${placeHolder}`
label: `go back \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to search for ${placeHolder}`
}, Commands.ShowCommitSearch, [
uri,
args

View File

@@ -1,8 +1,8 @@
'use strict';
import { TextEditor, TextEditorEdit, Uri, window, workspace } from 'vscode';
import { AnnotationController, FileAnnotationType } from '../annotations/annotationController';
import { AnnotationController } from '../annotations/annotationController';
import { Commands, EditorCommand } from './common';
import { ExtensionKey, IConfig } from '../configuration';
import { ExtensionKey, FileAnnotationType, IConfig } from '../configuration';
import { Logger } from '../logger';
export interface ShowFileBlameCommandArgs {
@@ -17,12 +17,10 @@ export class ShowFileBlameCommand extends EditorCommand {
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, args: ShowFileBlameCommandArgs = {}): Promise<any> {
if (editor === undefined || editor.document === undefined || editor.document.isDirty) return undefined;
if (editor !== undefined && editor.document !== undefined && editor.document.isDirty) return undefined;
try {
if (args.type === undefined) {
args = { ...args };
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
args.type = cfg.blame.file.annotationType;
}

View File

@@ -2,9 +2,7 @@
import { commands, Position, Range, TextEditor, TextEditorEdit, Uri, window } from 'vscode';
import { Commands, EditorCommand, getCommandUri } from './common';
import { BuiltInCommands } from '../constants';
import { GitExplorer } from '../views/gitExplorer';
import { GitService, GitUri } from '../gitService';
import { Messages } from '../messages';
import { Logger } from '../logger';
export interface ShowFileHistoryCommandArgs {
@@ -15,7 +13,7 @@ export interface ShowFileHistoryCommandArgs {
export class ShowFileHistoryCommand extends EditorCommand {
constructor(private git: GitService, private explorer?: GitExplorer) {
constructor(private git: GitService) {
super(Commands.ShowFileHistory);
}
@@ -24,8 +22,6 @@ export class ShowFileHistoryCommand extends EditorCommand {
if (uri === undefined) return undefined;
if (args.position == null) {
args = { ...args };
// If the command is executed manually -- treat it as a click on the root lens (i.e. show blame for the whole file)
args.position = editor.document.validateRange(new Range(0, 0, 0, 1000000)).start;
}
@@ -33,13 +29,8 @@ export class ShowFileHistoryCommand extends EditorCommand {
const gitUri = await GitUri.fromUri(uri, this.git);
try {
if (this.explorer !== undefined) {
this.explorer.addHistory(gitUri);
return undefined;
}
const locations = await this.git.getLogLocations(gitUri, args.sha, args.line);
if (locations === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show file history');
if (locations === undefined) return window.showWarningMessage(`Unable to show file history. File is probably not under source control`);
return commands.executeCommand(BuiltInCommands.ShowReferences, uri, args.position, locations);
}

View File

@@ -11,7 +11,7 @@ export class ShowLastQuickPickCommand extends Command {
async execute() {
const command = getLastCommand();
if (command === undefined) return undefined;
if (!command) return undefined;
try {
return commands.executeCommand(command.command, ...command.args);

View File

@@ -1,8 +1,8 @@
'use strict';
import { TextEditor, TextEditorEdit, Uri, window, workspace } from 'vscode';
import { CurrentLineController, LineAnnotationType } from '../currentLineController';
import { CurrentLineController } from '../currentLineController';
import { Commands, EditorCommand } from './common';
import { ExtensionKey, IConfig } from '../configuration';
import { ExtensionKey, IConfig, LineAnnotationType } from '../configuration';
import { Logger } from '../logger';
export interface ShowLineBlameCommandArgs {
@@ -16,12 +16,10 @@ export class ShowLineBlameCommand extends EditorCommand {
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, args: ShowLineBlameCommandArgs = {}): Promise<any> {
if (editor === undefined || editor.document === undefined || editor.document.isDirty) return undefined;
if (editor !== undefined && editor.document !== undefined && editor.document.isDirty) return undefined;
try {
if (args.type === undefined) {
args = { ...args };
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
args.type = cfg.blame.line.annotationType;
}

View File

@@ -1,17 +1,14 @@
'use strict';
import { Strings } from '../system';
import { commands, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common';
import { GlyphChars } from '../constants';
import { GitLog, GitService, GitUri } from '../gitService';
import { GitService, GitUri, IGitLog } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
import { BranchesQuickPick, BranchHistoryQuickPick, CommandQuickPickItem } from '../quickPicks';
import { ShowQuickCommitDetailsCommandArgs } from './showQuickCommitDetails';
export interface ShowQuickBranchHistoryCommandArgs {
branch?: string;
log?: GitLog;
log?: IGitLog;
maxCount?: number;
goBackCommand?: CommandQuickPickItem;
@@ -24,12 +21,11 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand {
super(Commands.ShowQuickBranchHistory);
}
async execute(editor?: TextEditor, uri?: Uri, args: ShowQuickBranchHistoryCommandArgs = {}) {
async execute(editor: TextEditor, uri?: Uri, args: ShowQuickBranchHistoryCommandArgs = {}) {
uri = getCommandUri(uri, editor);
const gitUri = uri && await GitUri.fromUri(uri, this.git);
args = { ...args };
if (args.maxCount == null) {
args.maxCount = this.git.config.advanced.maxQuickHistory;
}
@@ -37,12 +33,12 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand {
let progressCancellation = args.branch === undefined ? undefined : BranchHistoryQuickPick.showProgress(args.branch);
try {
const repoPath = gitUri === undefined ? this.git.repoPath : gitUri.repoPath;
if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to show branch history`);
if (!repoPath) return window.showWarningMessage(`Unable to show branch history`);
if (args.branch === undefined) {
const branches = await this.git.getBranches(repoPath);
const pick = await BranchesQuickPick.show(branches, `Show history for branch${GlyphChars.Ellipsis}`);
const pick = await BranchesQuickPick.show(branches, `Show history for branch\u2026`);
if (pick === undefined) return undefined;
if (pick instanceof CommandQuickPickItem) return pick.execute();
@@ -67,8 +63,8 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand {
// 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`
label: `go back \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to \u00a0$(git-branch) ${args.branch} history`
}, Commands.ShowQuickBranchHistory, [
uri,
args

View File

@@ -1,19 +1,16 @@
'use strict';
import { Strings } from '../system';
import { commands, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common';
import { GlyphChars } from '../constants';
import { GitCommit, GitLog, GitLogCommit, GitService, GitUri } from '../gitService';
import { GitCommit, GitLogCommit, GitService, GitUri, IGitLog } from '../gitService';
import { Logger } from '../logger';
import { CommandQuickPickItem, CommitDetailsQuickPick, CommitWithFileStatusQuickPickItem } from '../quickPicks';
import { ShowQuickCommitFileDetailsCommandArgs } from './showQuickCommitFileDetails';
import { Messages } from '../messages';
import * as path from 'path';
export interface ShowQuickCommitDetailsCommandArgs {
sha?: string;
commit?: GitCommit | GitLogCommit;
repoLog?: GitLog;
repoLog?: IGitLog;
goBackCommand?: CommandQuickPickItem;
}
@@ -24,7 +21,7 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand {
super(Commands.ShowQuickCommitDetails);
}
async execute(editor?: TextEditor, uri?: Uri, args: ShowQuickCommitDetailsCommandArgs = {}) {
async execute(editor: TextEditor, uri?: Uri, args: ShowQuickCommitDetailsCommandArgs = {}) {
uri = getCommandUri(uri, editor);
if (uri === undefined) return undefined;
@@ -33,7 +30,6 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand {
let repoPath = gitUri.repoPath;
let workingFileName = path.relative(repoPath || '', gitUri.fsPath);
args = { ...args };
if (args.sha === undefined) {
if (editor === undefined) return undefined;
@@ -42,12 +38,9 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand {
try {
const blame = await this.git.getBlameForLine(gitUri, blameline);
if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show commit details');
if (blame === undefined) return window.showWarningMessage(`Unable to show commit details. File is probably not under source control`);
// Because the previous sha of an uncommitted file isn't trust worthy we just have to kick out
if (blame.commit.isUncommitted) return Messages.showLineUncommittedWarningMessage('Unable to show commit details');
args.sha = blame.commit.sha;
args.sha = blame.commit.isUncommitted ? blame.commit.previousSha : blame.commit.sha;
repoPath = blame.commit.repoPath;
workingFileName = blame.commit.fileName;
@@ -71,13 +64,13 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand {
if (args.repoLog === undefined) {
const log = await this.git.getLogForRepo(repoPath!, args.sha, 2);
if (log === undefined) return Messages.showCommitNotFoundWarningMessage(`Unable to show commit details`);
if (log === undefined) return window.showWarningMessage(`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 window.showWarningMessage(`Unable to show commit details`);
if (args.commit.workingFileName === undefined) {
args.commit.workingFileName = workingFileName;
@@ -86,8 +79,8 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand {
if (args.goBackCommand === 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 history`
label: `go back \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to branch history`
}, Commands.ShowQuickCurrentBranchHistory, [
new GitUri(args.commit.uri, args.commit)
]);
@@ -95,8 +88,8 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand {
// 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}`
label: `go back \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to details of \u00a0$(git-commit) ${args.commit.shortSha}`
}, Commands.ShowQuickCommitDetails, [
new GitUri(args.commit.uri, args.commit),
args

View File

@@ -1,19 +1,16 @@
'use strict';
import { Strings } from '../system';
import { TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common';
import { GlyphChars } from '../constants';
import { GitCommit, GitLog, GitLogCommit, GitService, GitUri } from '../gitService';
import { GitCommit, GitLogCommit, GitService, GitUri, IGitLog } from '../gitService';
import { Logger } from '../logger';
import { CommandQuickPickItem, CommitFileDetailsQuickPick } from '../quickPicks';
import { ShowQuickCommitDetailsCommandArgs } from './showQuickCommitDetails';
import { Messages } from '../messages';
import * as path from 'path';
export interface ShowQuickCommitFileDetailsCommandArgs {
sha?: string;
commit?: GitCommit | GitLogCommit;
fileLog?: GitLog;
fileLog?: IGitLog;
goBackCommand?: CommandQuickPickItem;
}
@@ -24,7 +21,7 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCachedCommand
super(Commands.ShowQuickCommitFileDetails);
}
async execute(editor?: TextEditor, uri?: Uri, args: ShowQuickCommitFileDetailsCommandArgs = {}) {
async execute(editor: TextEditor, uri?: Uri, args: ShowQuickCommitFileDetailsCommandArgs = {}) {
uri = getCommandUri(uri, editor);
if (uri === undefined) return undefined;
@@ -32,7 +29,6 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCachedCommand
const gitUri = await GitUri.fromUri(uri, this.git);
args = { ...args };
if (args.sha === undefined) {
if (editor === undefined) return undefined;
@@ -41,12 +37,9 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCachedCommand
try {
const blame = await this.git.getBlameForLine(gitUri, blameline);
if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show commit file details');
if (blame === undefined) return window.showWarningMessage(`Unable to show commit file details. File is probably not under source control`);
// Because the previous sha of an uncommitted file isn't trust worthy we just have to kick out
if (blame.commit.isUncommitted) return Messages.showLineUncommittedWarningMessage('Unable to show commit file details');
args.sha = blame.commit.sha;
args.sha = blame.commit.isUncommitted ? blame.commit.previousSha : blame.commit.sha;
args.commit = blame.commit;
workingFileName = path.relative(args.commit.repoPath, gitUri.fsPath);
@@ -72,12 +65,12 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCachedCommand
}
if (args.fileLog === undefined) {
args.commit = await this.git.getLogCommit(args.commit === undefined ? gitUri.repoPath : args.commit.repoPath, gitUri.fsPath, args.sha, { previous: true });
if (args.commit === undefined) return Messages.showCommitNotFoundWarningMessage(`Unable to show commit file details`);
args.commit = await this.git.getLogCommit(args.commit ? args.commit.repoPath : gitUri.repoPath, gitUri.fsPath, args.sha, { previous: true });
if (args.commit === undefined) return window.showWarningMessage(`Unable to show commit file details`);
}
}
if (args.commit === undefined) return Messages.showCommitNotFoundWarningMessage(`Unable to show commit file details`);
if (args.commit === undefined) return window.showWarningMessage(`Unable to show commit file details`);
// Attempt to the most recent commit -- so that we can find the real working filename if there was a rename
args.commit.workingFileName = workingFileName;
@@ -88,8 +81,8 @@ 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}`
label: `go back \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to details of \u00a0$(git-commit) ${shortSha}`
}, Commands.ShowQuickCommitDetails, [
new GitUri(args.commit.uri, args.commit),
{
@@ -101,8 +94,8 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCachedCommand
// 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}`
label: `go back \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to details of \u00a0$(file-text) ${path.basename(args.commit.fileName)} in \u00a0$(git-commit) ${shortSha}`
}, Commands.ShowQuickCommitFileDetails, [
new GitUri(args.commit.uri, args.commit),
args

View File

@@ -4,7 +4,6 @@ import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common';
import { ShowQuickBranchHistoryCommandArgs } from './showQuickBranchHistory';
import { GitService } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
import { CommandQuickPickItem } from '../quickPicks';
export interface ShowQuickCurrentBranchHistoryCommandArgs {
@@ -17,12 +16,12 @@ export class ShowQuickCurrentBranchHistoryCommand extends ActiveEditorCachedComm
super(Commands.ShowQuickCurrentBranchHistory);
}
async execute(editor?: TextEditor, uri?: Uri, args: ShowQuickCurrentBranchHistoryCommandArgs = {}) {
async execute(editor: TextEditor, uri?: Uri, args: ShowQuickCurrentBranchHistoryCommandArgs = {}) {
uri = getCommandUri(uri, editor);
try {
const repoPath = await this.git.getRepoPathFromUri(uri);
if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to show branch history`);
if (!repoPath) return window.showWarningMessage(`Unable to show branch history`);
const branch = await this.git.getBranch(repoPath);
if (branch === undefined) return undefined;

View File

@@ -1,79 +1,75 @@
'use strict';
import { Strings } from '../system';
import { commands, Range, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common';
import { GlyphChars } from '../constants';
import { GitLog, GitService, GitUri } from '../gitService';
import { Logger } from '../logger';
import { CommandQuickPickItem, FileHistoryQuickPick } from '../quickPicks';
import { ShowQuickCommitFileDetailsCommandArgs } from './showQuickCommitFileDetails';
import { Messages } from '../messages';
import * as path from 'path';
export interface ShowQuickFileHistoryCommandArgs {
log?: GitLog;
maxCount?: number;
range?: Range;
goBackCommand?: CommandQuickPickItem;
nextPageCommand?: CommandQuickPickItem;
}
export class ShowQuickFileHistoryCommand extends ActiveEditorCachedCommand {
constructor(private git: GitService) {
super(Commands.ShowQuickFileHistory);
}
async execute(editor?: TextEditor, uri?: Uri, args: ShowQuickFileHistoryCommandArgs = {}) {
uri = getCommandUri(uri, editor);
if (uri === undefined) return commands.executeCommand(Commands.ShowQuickCurrentBranchHistory);
const gitUri = await GitUri.fromUri(uri, this.git);
args = { ...args };
if (args.maxCount == null) {
args.maxCount = this.git.config.advanced.maxQuickHistory;
}
const progressCancellation = FileHistoryQuickPick.showProgress(gitUri);
try {
if (args.log === undefined) {
args.log = await this.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, gitUri.sha, { maxCount: args.maxCount, range: args.range });
if (args.log === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show file history');
}
if (progressCancellation.token.isCancellationRequested) return undefined;
const pick = await FileHistoryQuickPick.show(this.git, args.log, gitUri, progressCancellation, { goBackCommand: args.goBackCommand, nextPageCommand: args.nextPageCommand });
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,
new GitUri(pick.commit.uri, pick.commit),
{
commit: pick.commit,
fileLog: args.log,
sha: pick.commit.sha,
goBackCommand: currentCommand
} as ShowQuickCommitFileDetailsCommandArgs);
}
catch (ex) {
Logger.error(ex, 'ShowQuickFileHistoryCommand');
return window.showErrorMessage(`Unable to show file history. See output channel for more details`);
}
finally {
progressCancellation.dispose();
}
}
'use strict';
import { commands, Range, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common';
import { GitService, GitUri, IGitLog } from '../gitService';
import { Logger } from '../logger';
import { CommandQuickPickItem, FileHistoryQuickPick } from '../quickPicks';
import { ShowQuickCommitFileDetailsCommandArgs } from './showQuickCommitFileDetails';
import * as path from 'path';
export interface ShowQuickFileHistoryCommandArgs {
log?: IGitLog;
maxCount?: number;
range?: Range;
goBackCommand?: CommandQuickPickItem;
nextPageCommand?: CommandQuickPickItem;
}
export class ShowQuickFileHistoryCommand extends ActiveEditorCachedCommand {
constructor(private git: GitService) {
super(Commands.ShowQuickFileHistory);
}
async execute(editor: TextEditor, uri?: Uri, args: ShowQuickFileHistoryCommandArgs = {}) {
uri = getCommandUri(uri, editor);
if (uri === undefined) return commands.executeCommand(Commands.ShowQuickCurrentBranchHistory);
const gitUri = await GitUri.fromUri(uri, this.git);
if (args.maxCount == null) {
args.maxCount = this.git.config.advanced.maxQuickHistory;
}
const progressCancellation = FileHistoryQuickPick.showProgress(gitUri);
try {
if (args.log === undefined) {
args.log = await this.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, gitUri.sha, args.maxCount, args.range);
if (args.log === undefined) return window.showWarningMessage(`Unable to show file history. File is probably not under source control`);
}
if (progressCancellation.token.isCancellationRequested) return undefined;
const pick = await FileHistoryQuickPick.show(this.git, args.log, gitUri, progressCancellation, args.goBackCommand, args.nextPageCommand);
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 \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to history of \u00a0$(file-text) ${path.basename(pick.commit.fileName)}${gitUri.sha ? ` from \u00a0$(git-commit) ${gitUri.shortSha}` : ''}`
}, Commands.ShowQuickFileHistory, [
uri,
args
]);
return commands.executeCommand(Commands.ShowQuickCommitFileDetails,
new GitUri(pick.commit.uri, pick.commit),
{
commit: pick.commit,
fileLog: args.log,
sha: pick.commit.sha,
goBackCommand: currentCommand
} as ShowQuickCommitFileDetailsCommandArgs);
}
catch (ex) {
Logger.error(ex, 'ShowQuickFileHistoryCommand');
return window.showErrorMessage(`Unable to show file history. See output channel for more details`);
}
finally {
progressCancellation.dispose();
}
}
}

View File

@@ -3,7 +3,6 @@ import { TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common';
import { GitService } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
import { CommandQuickPickItem, RepoStatusQuickPick } from '../quickPicks';
export interface ShowQuickRepoStatusCommandArgs {
@@ -16,12 +15,12 @@ export class ShowQuickRepoStatusCommand extends ActiveEditorCachedCommand {
super(Commands.ShowQuickRepoStatus);
}
async execute(editor?: TextEditor, uri?: Uri, args: ShowQuickRepoStatusCommandArgs = {}) {
async execute(editor: TextEditor, uri?: Uri, args: ShowQuickRepoStatusCommandArgs = {}) {
uri = getCommandUri(uri, editor);
try {
const repoPath = await this.git.getRepoPathFromUri(uri);
if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to show repository status`);
if (!repoPath) return window.showWarningMessage(`Unable to show repository status`);
const status = await this.git.getStatusForRepo(repoPath);
if (status === undefined) return window.showWarningMessage(`Unable to show repository status`);

View File

@@ -1,11 +1,8 @@
'use strict';
import { Strings } from '../system';
import { commands, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common';
import { GlyphChars } from '../constants';
import { GitService, GitUri } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
import { CommandQuickPickItem, StashListQuickPick } from '../quickPicks';
import { ShowQuickCommitDetailsCommandArgs } from './showQuickCommitDetails';
@@ -19,20 +16,20 @@ export class ShowQuickStashListCommand extends ActiveEditorCachedCommand {
super(Commands.ShowQuickStashList);
}
async execute(editor?: TextEditor, uri?: Uri, args: ShowQuickStashListCommandArgs = {}) {
async execute(editor: TextEditor, uri?: Uri, args: ShowQuickStashListCommandArgs = {}) {
uri = getCommandUri(uri, editor);
try {
const repoPath = await this.git.getRepoPathFromUri(uri);
if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to show stashed changes`);
if (!repoPath) return window.showWarningMessage(`Unable to show stashed changes`);
const stash = await this.git.getStashList(repoPath);
if (stash === undefined) return window.showWarningMessage(`Unable to show stashed changes`);
// 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`
label: `go back \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to stashed changes`
}, Commands.ShowQuickStashList, [
uri,
{

View File

@@ -1,13 +1,10 @@
'use strict';
import { Strings } from '../system';
import { MessageItem, window } from 'vscode';
import { GitService, GitStashCommit } from '../gitService';
import { Command, CommandContext, Commands } from './common';
import { GlyphChars } from '../constants';
import { Command, Commands } from './common';
import { CommitQuickPickItem, StashListQuickPick } from '../quickPicks';
import { Logger } from '../logger';
import { CommandQuickPickItem } from '../quickPicks';
import { StashCommitNode } from '../views/stashCommitNode';
export interface StashApplyCommandArgs {
confirm?: boolean;
@@ -23,30 +20,16 @@ export class StashApplyCommand extends Command {
super(Commands.StashApply);
}
protected async preExecute(context: CommandContext, args: StashApplyCommandArgs = { confirm: true, deleteAfter: false }) {
if (context.type === 'view' && context.node instanceof StashCommitNode) {
args = { ...args };
const stash = context.node.commit;
args.stashItem = { stashName: stash.stashName, message: stash.message };
return this.execute(args);
}
return super.preExecute(context, args);
}
async execute(args: StashApplyCommandArgs = { confirm: true, deleteAfter: false }) {
if (!this.git.repoPath) return undefined;
args = { ...args };
if (args.stashItem === undefined || args.stashItem.stashName === undefined) {
const stash = await this.git.getStashList(this.git.repoPath);
if (stash === undefined) return window.showInformationMessage(`There are no stashed changes`);
const currentCommand = new CommandQuickPickItem({
label: `go back ${GlyphChars.ArrowBack}`,
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} to apply stashed changes`
label: `go back \u21A9`,
description: `\u00a0 \u2014 \u00a0\u00a0 to apply stashed changes`
}, Commands.StashApply, [args]);
const pick = await StashListQuickPick.show(this.git, stash, 'apply', args.goBackCommand, currentCommand);
@@ -58,7 +41,7 @@ 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 message = args.stashItem.message.length > 80 ? `${args.stashItem.message.substring(0, 80)}\u2026` : 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();
@@ -70,10 +53,7 @@ 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.`);
}
else if (ex.message.includes('Auto-merging') && ex.message.includes('CONFLICT')) {
return window.showInformationMessage(`Stash applied with conflicts`);
return window.showErrorMessage(`Unable to apply stash. Your working tree changes would be overwritten.`);
}
else {
return window.showErrorMessage(`Unable to apply stash. See output channel for more details`);

View File

@@ -1,11 +1,9 @@
'use strict';
import { MessageItem, window } from 'vscode';
import { Command, CommandContext, Commands } from './common';
import { GlyphChars } from '../constants';
import { GitService } from '../gitService';
import { Command, Commands } from './common';
import { Logger } from '../logger';
import { CommandQuickPickItem } from '../quickPicks';
import { StashCommitNode } from '../views/stashCommitNode';
export interface StashDeleteCommandArgs {
confirm?: boolean;
@@ -20,23 +18,9 @@ export class StashDeleteCommand extends Command {
super(Commands.StashDelete);
}
protected async preExecute(context: CommandContext, args: StashDeleteCommandArgs = { confirm: true }) {
if (context.type === 'view' && context.node instanceof StashCommitNode) {
args = { ...args };
const stash = context.node.commit;
args.stashItem = { stashName: stash.stashName, message: stash.message };
return this.execute(args);
}
return super.preExecute(context, args);
}
async execute(args: StashDeleteCommandArgs = { confirm: true }) {
if (!this.git.repoPath) return undefined;
args = { ...args };
if (args.stashItem === undefined || args.stashItem.stashName === undefined) return undefined;
if (args.confirm === undefined) {
@@ -45,7 +29,7 @@ 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 message = args.stashItem.message.length > 80 ? `${args.stashItem.message.substring(0, 80)}\u2026` : 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();
}

View File

@@ -18,10 +18,9 @@ export class StashSaveCommand extends Command {
super(Commands.StashSave);
}
async execute(args: StashSaveCommandArgs = { unstagedOnly: false }) {
async execute(args: StashSaveCommandArgs = { unstagedOnly : false }) {
if (!this.git.repoPath) return undefined;
args = { ...args };
if (args.unstagedOnly === undefined) {
args.unstagedOnly = false;
}

View File

@@ -1,8 +1,8 @@
'use strict';
import { TextEditor, TextEditorEdit, Uri, window, workspace } from 'vscode';
import { AnnotationController, FileAnnotationType } from '../annotations/annotationController';
import { AnnotationController } from '../annotations/annotationController';
import { Commands, EditorCommand } from './common';
import { ExtensionKey, IConfig } from '../configuration';
import { ExtensionKey, FileAnnotationType, IConfig } from '../configuration';
import { Logger } from '../logger';
export interface ToggleFileBlameCommandArgs {
@@ -17,12 +17,10 @@ export class ToggleFileBlameCommand extends EditorCommand {
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, args: ToggleFileBlameCommandArgs = {}): Promise<any> {
if (editor === undefined || editor.document === undefined || editor.document.isDirty) return undefined;
if (editor !== undefined && editor.document !== undefined && editor.document.isDirty) return undefined;
try {
if (args.type === undefined) {
args = { ...args };
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
args.type = cfg.blame.file.annotationType;
}

View File

@@ -1,24 +0,0 @@
'use strict';
import { TextEditor, TextEditorEdit, Uri, window } from 'vscode';
import { AnnotationController, FileAnnotationType } from '../annotations/annotationController';
import { Commands, EditorCommand } from './common';
import { Logger } from '../logger';
export class ToggleFileRecentChangesCommand extends EditorCommand {
constructor(private annotationController: AnnotationController) {
super(Commands.ToggleFileRecentChanges);
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri): Promise<any> {
if (editor === undefined || editor.document === undefined || editor.document.isDirty) return undefined;
try {
return this.annotationController.toggleAnnotations(editor, FileAnnotationType.RecentChanges);
}
catch (ex) {
Logger.error(ex, 'ToggleFileRecentChangesCommand');
return window.showErrorMessage(`Unable to toggle recent file changes annotations. See output channel for more details`);
}
}
}

View File

@@ -1,8 +1,8 @@
'use strict';
import { TextEditor, TextEditorEdit, Uri, window, workspace } from 'vscode';
import { CurrentLineController, LineAnnotationType } from '../currentLineController';
import { CurrentLineController } from '../currentLineController';
import { Commands, EditorCommand } from './common';
import { ExtensionKey, IConfig } from '../configuration';
import { ExtensionKey, IConfig, LineAnnotationType } from '../configuration';
import { Logger } from '../logger';
export interface ToggleLineBlameCommandArgs {
@@ -16,12 +16,10 @@ export class ToggleLineBlameCommand extends EditorCommand {
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri, args: ToggleLineBlameCommandArgs = {}): Promise<any> {
if (editor === undefined || editor.document === undefined || editor.document.isDirty) return undefined;
if (editor !== undefined && editor.document !== undefined && editor.document.isDirty) return undefined;
try {
if (args.type === undefined) {
args = { ...args };
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
args.type = cfg.blame.line.annotationType;
}

View File

@@ -1,19 +1,17 @@
'use strict';
import { FileAnnotationType } from './annotations/annotationController';
import { Commands } from './commands';
import { LineAnnotationType } from './currentLineController';
import { OutputLevel } from './logger';
export { ExtensionKey } from './constants';
export type CodeLensCommand = 'gitlens.toggleFileBlame' |
'gitlens.showBlameHistory' |
'gitlens.showFileHistory' |
'gitlens.diffWithPrevious' |
'gitlens.showQuickCommitDetails' |
'gitlens.showQuickCommitFileDetails' |
'gitlens.showQuickFileHistory' |
'gitlens.showQuickRepoHistory';
export type BlameLineHighlightLocations = 'gutter' | 'line' | 'overviewRuler';
export const BlameLineHighlightLocations = {
Gutter: 'gutter' as BlameLineHighlightLocations,
Line: 'line' as BlameLineHighlightLocations,
OverviewRuler: 'overviewRuler' as BlameLineHighlightLocations
};
export type CodeLensCommand = 'gitlens.toggleFileBlame' | 'gitlens.showBlameHistory' | 'gitlens.showFileHistory' | 'gitlens.diffWithPrevious' | 'gitlens.showQuickCommitDetails' | 'gitlens.showQuickCommitFileDetails' | 'gitlens.showQuickFileHistory' | 'gitlens.showQuickRepoHistory';
export const CodeLensCommand = {
BlameAnnotate: Commands.ToggleFileBlame as CodeLensCommand,
ShowBlameHistory: Commands.ShowBlameHistory as CodeLensCommand,
@@ -33,23 +31,19 @@ export const CodeLensLocations = {
Custom: 'custom' as CodeLensLocations
};
export type LineHighlightLocations = 'gutter' | 'line' | 'overviewRuler';
export const LineHighlightLocations = {
Gutter: 'gutter' as LineHighlightLocations,
Line: 'line' as LineHighlightLocations,
OverviewRuler: 'overviewRuler' as LineHighlightLocations
export type FileAnnotationType = 'gutter' | 'hover';
export const FileAnnotationType = {
Gutter: 'gutter' as FileAnnotationType,
Hover: 'hover' as FileAnnotationType
};
export type StatusBarCommand = 'gitlens.toggleFileBlame' |
'gitlens.showBlameHistory' |
'gitlens.showFileHistory' |
'gitlens.toggleCodeLens' |
'gitlens.diffWithPrevious' |
'gitlens.diffWithWorking' |
'gitlens.showQuickCommitDetails' |
'gitlens.showQuickCommitFileDetails' |
'gitlens.showQuickFileHistory' |
'gitlens.showQuickRepoHistory';
export type LineAnnotationType = 'trailing' | 'hover';
export const LineAnnotationType = {
Trailing: 'trailing' as LineAnnotationType,
Hover: 'hover' as LineAnnotationType
};
export type StatusBarCommand = 'gitlens.toggleFileBlame' | 'gitlens.showBlameHistory' | 'gitlens.showFileHistory' | 'gitlens.toggleCodeLens' | 'gitlens.diffWithPrevious' | 'gitlens.diffWithWorking' | 'gitlens.showQuickCommitDetails' | 'gitlens.showQuickCommitFileDetails' | 'gitlens.showQuickFileHistory' | 'gitlens.showQuickRepoHistory';
export const StatusBarCommand = {
BlameAnnotate: Commands.ToggleFileBlame as StatusBarCommand,
ShowBlameHistory: Commands.ShowBlameHistory as StatusBarCommand,
@@ -104,9 +98,6 @@ export interface IAdvancedConfig {
quickPick: {
closeOnFocusOut: boolean;
};
telemetry: {
enabled: boolean;
};
toggleWhitespace: {
enabled: boolean;
};
@@ -134,6 +125,10 @@ export interface IThemeConfig {
uncommittedForegroundColor: string | null;
};
};
hover: {
separateLines: boolean;
};
};
line: {
@@ -177,6 +172,9 @@ export const themeDefaults: IThemeConfig = {
foregroundColor: 'rgb(116, 116, 116)',
uncommittedForegroundColor: null
}
},
hover: {
separateLines: false
}
},
line: {
@@ -209,7 +207,7 @@ export interface IConfig {
file: {
gutter: {
format: string;
dateFormat: string | null;
dateFormat: string;
compact: boolean;
heatmap: {
enabled: boolean;
@@ -227,14 +225,6 @@ export interface IConfig {
};
wholeLine: boolean;
};
recentChanges: {
hover: {
details: boolean;
changes: boolean;
wholeLine: boolean;
};
};
};
line: {
@@ -245,7 +235,7 @@ export interface IConfig {
trailing: {
format: string;
dateFormat: string | null;
dateFormat: string;
hover: {
changes: boolean;
details: boolean;
@@ -260,7 +250,7 @@ export interface IConfig {
annotationType: FileAnnotationType;
lineHighlight: {
enabled: boolean;
locations: LineHighlightLocations[];
locations: BlameLineHighlightLocations[];
};
};
@@ -270,14 +260,6 @@ export interface IConfig {
};
};
recentChanges: {
file: {
lineHighlight: {
locations: LineHighlightLocations[];
};
}
};
codeLens: {
enabled: boolean;
recentChange: {
@@ -294,38 +276,12 @@ export interface IConfig {
debug: boolean;
};
defaultDateFormat: string | null;
gitExplorer: {
enabled: boolean;
commitFormat: string;
commitFileFormat: string;
// dateFormat: string | null;
};
stashExplorer: {
enabled: boolean;
stashFormat: string;
stashFileFormat: string;
// dateFormat: string | null;
};
statusBar: {
enabled: boolean;
alignment: 'left' | 'right';
command: StatusBarCommand;
format: string;
dateFormat: string | null;
};
strings: {
codeLens: {
unsavedChanges: {
recentChangeAndAuthors: string;
recentChangeOnly: string;
authorsOnly: string;
};
};
dateFormat: string;
};
theme: IThemeConfig;

Some files were not shown because too many files have changed in this diff Show More