From 76067831326768a4589e94a9eb0fa2bad25e29a7 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Sun, 30 Sep 2018 03:47:06 -0400 Subject: [PATCH] Renames explorer to view --- CHANGELOG.md | 30 +- README.md | 180 ++--- package.json | 1073 ++++++++++++++--------------- src/commands.ts | 6 +- src/commands/common.ts | 54 +- src/commands/diffBranchWithBranch.ts | 2 +- src/commands/diffDirectory.ts | 10 +- src/commands/showCommitSearch.ts | 4 +- src/commands/showExplorer.ts | 33 - src/commands/showQuickCommitDetails.ts | 2 +- src/commands/showQuickFileHistory.ts | 4 +- src/commands/showView.ts | 33 + src/configuration.ts | 9 +- src/constants.ts | 22 +- src/container.ts | 104 +-- src/extension.ts | 105 ++- src/quickpicks/commitsQuickPick.ts | 6 +- src/quickpicks/commonQuickPicks.ts | 10 +- src/quickpicks/fileHistoryQuickPick.ts | 6 +- src/ui/config.ts | 38 +- src/ui/settings/index.html | 174 ++--- src/ui/welcome/index.html | 16 +- src/views/explorer.ts | 178 ----- src/views/explorerCommands.ts | 550 --------------- src/views/fileHistoryExplorer.ts | 98 --- src/views/fileHistoryView.ts | 98 +++ src/views/lineHistoryExplorer.ts | 97 --- src/views/lineHistoryView.ts | 97 +++ src/views/nodes.ts | 2 +- src/views/nodes/branchNode.ts | 26 +- src/views/nodes/branchOrTagFolderNode.ts | 14 +- src/views/nodes/branchesNode.ts | 32 +- src/views/nodes/commitFileNode.ts | 16 +- src/views/nodes/commitNode.ts | 32 +- src/views/nodes/common.ts | 43 +- src/views/nodes/explorerNode.ts | 185 ----- src/views/nodes/fileHistoryNode.ts | 24 +- src/views/nodes/fileHistoryTrackerNode.ts | 16 +- src/views/nodes/folderNode.ts | 42 +- src/views/nodes/helpers.ts | 8 +- src/views/nodes/lineHistoryNode.ts | 26 +- src/views/nodes/lineHistoryTrackerNode.ts | 16 +- src/views/nodes/remoteNode.ts | 22 +- src/views/nodes/remotesNode.ts | 14 +- src/views/nodes/repositoriesNode.ts | 26 +- src/views/nodes/repositoryNode.ts | 52 +- src/views/nodes/resultsCommitNode.ts | 12 +- src/views/nodes/resultsCommitsNode.ts | 16 +- src/views/nodes/resultsComparisonNode.ts | 16 +- src/views/nodes/resultsFileNode.ts | 12 +- src/views/nodes/resultsFilesNode.ts | 31 +- src/views/nodes/resultsNode.ts | 22 +- src/views/nodes/stashFileNode.ts | 12 +- src/views/nodes/stashNode.ts | 16 +- src/views/nodes/stashesNode.ts | 14 +- src/views/nodes/statusFileNode.ts | 18 +- src/views/nodes/statusFilesNode.ts | 30 +- src/views/nodes/statusUpstreamNode.ts | 20 +- src/views/nodes/tagNode.ts | 24 +- src/views/nodes/tagsNode.ts | 22 +- src/views/nodes/viewNode.ts | 181 +++++ src/views/repositoriesExplorer.ts | 148 ---- src/views/repositoriesView.ts | 148 ++++ src/views/resultsExplorer.ts | 225 ------ src/views/resultsView.ts | 225 ++++++ src/views/viewBase.ts | 178 +++++ src/views/viewCommands.ts | 546 +++++++++++++++ 67 files changed, 2794 insertions(+), 2757 deletions(-) delete mode 100644 src/commands/showExplorer.ts create mode 100644 src/commands/showView.ts delete mode 100644 src/views/explorer.ts delete mode 100644 src/views/explorerCommands.ts delete mode 100644 src/views/fileHistoryExplorer.ts create mode 100644 src/views/fileHistoryView.ts delete mode 100644 src/views/lineHistoryExplorer.ts create mode 100644 src/views/lineHistoryView.ts delete mode 100644 src/views/nodes/explorerNode.ts create mode 100644 src/views/nodes/viewNode.ts delete mode 100644 src/views/repositoriesExplorer.ts create mode 100644 src/views/repositoriesView.ts delete mode 100644 src/views/resultsExplorer.ts create mode 100644 src/views/resultsView.ts create mode 100644 src/views/viewBase.ts create mode 100644 src/views/viewCommands.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index f3952fb..b9f96b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -222,7 +222,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Adds the ability to control where the _GitLens_, _GitLens File History_, and _GitLens Results_ explorers are shown 🎉 — closes [#213](https://github.com/eamodio/vscode-gitlens/issues/213), [#377](https://github.com/eamodio/vscode-gitlens/issues/377) - Adds `gitlens.gitExplorer.location` setting to the interactive settings editor to specify where the _GitLens_ explorer is shown — either in the _Explorer_ or _Source Control_ view - Adds `gitlens.historyExplorer.location` setting to the interactive settings editor to specify where the _GitLens File History_ explorer is shown — either in the _Explorer_ or _Source Control_ view - - Adds `gitlens.resultsExplorer.location` setting to the interactive settings editor to specify where the _GitLens Results_ explorer is shown — either in the _Explorer_ or _Source Control_ view + - Adds `gitlens.resultsView.location` setting to the interactive settings editor to specify where the _GitLens Results_ explorer is shown — either in the _Explorer_ or _Source Control_ view ### Changed @@ -270,7 +270,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Adds a tree layout option to tags in the _GitLens_ explorer — closes [#358](https://github.com/eamodio/vscode-gitlens/issues/358) - Adds _Show GitLens Explorer_ (`gitlens.showGitExplorer`) command — shows/expands the _GitLens_ explorer - Adds _Show File History Explorer_ (`gitlens.showHistoryExplorer`) command — shows/expands the _GitLens File History_ explorer -- Adds _Show Results Explorer_ (`gitlens.showResultsExplorer`) command — shows/expands the _GitLens Results_ explorer +- Adds _Show Results Explorer_ (`gitlens.showResultsView`) command — shows/expands the _GitLens Results_ explorer ### Changed @@ -501,9 +501,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Renames _Show Files in Automatic View_ (`gitlens.gitExplorer.setFilesLayoutToAuto`) command to _Automatic Layout_ - Renames _Show Files in List View_ (`gitlens.gitExplorer.setFilesLayoutToList`) command to _List Layout_ - Renames _Show Files in Tree View_ (`gitlens.gitExplorer.setFilesLayoutToTree`) command to _Tree Layout_ -- Renames _Show Files in Automatic View_ (`gitlens.resultsExplorer.setFilesLayoutToAuto`) command to _Automatic Layout_ -- Renames _Show Files in List View_ (`gitlens.resultsExplorer.setFilesLayoutToAuto`) command to _List Layout_ -- Renames _Show Files in Tree View_ (`gitlens.resultsExplorer.setFilesLayoutToAuto`) command to _Tree Layout_ +- Renames _Show Files in Automatic View_ (`gitlens.resultsView.setFilesLayoutToAuto`) command to _Automatic Layout_ +- Renames _Show Files in List View_ (`gitlens.resultsView.setFilesLayoutToAuto`) command to _List Layout_ +- Renames _Show Files in Tree View_ (`gitlens.resultsView.setFilesLayoutToAuto`) command to _Tree Layout_ - Overhauls GitLens' settings for better clarity and ease-of-use - Renames `gitlens.annotations.file.gutter.gravatars` setting to `gitlens.blame.avatars` - Renames `gitlens.annotations.file.gutter.compact` setting to `gitlens.blame.compact` @@ -539,13 +539,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Removes `gitlens.codeLens.debug` setting, use `gitlens.debug` instead - Removes `gitlens.blame.file.annotationType` setting, use `gitlens.hovers.annotations.enabled` - Removes `gitlens.blame.line.annotationType` setting, use `gitlens.currentLine.enabled` or `gitlens.hovers.currentLine.enabled` instead -- Removes `gitlens.resultsExplorer.gravatars` setting, use `gitlens.explorers.avatars` instead -- Removes `gitlens.resultsExplorer.commitFileFormat` setting, use `gitlens.explorers.commitFileFormat` instead -- Removes `gitlens.resultsExplorer.commitFormat` setting, use `gitlens.explorers.commitFormat` instead -- Removes `gitlens.resultsExplorer.showTrackingBranch` setting -- Removes `gitlens.resultsExplorer.stashFileFormat` setting, use `gitlens.explorers.stashFileFormat` instead -- Removes `gitlens.resultsExplorer.stashFormat` setting, use `gitlens.explorers.stashFormat` instead -- Removes `gitlens.resultsExplorer.statusFileFormat` setting, use `gitlens.explorers.statusFileFormat` instead +- Removes `gitlens.resultsView.gravatars` setting, use `gitlens.explorers.avatars` instead +- Removes `gitlens.resultsView.commitFileFormat` setting, use `gitlens.explorers.commitFileFormat` instead +- Removes `gitlens.resultsView.commitFormat` setting, use `gitlens.explorers.commitFormat` instead +- Removes `gitlens.resultsView.showTrackingBranch` setting +- Removes `gitlens.resultsView.stashFileFormat` setting, use `gitlens.explorers.stashFileFormat` instead +- Removes `gitlens.resultsView.stashFormat` setting, use `gitlens.explorers.stashFormat` instead +- Removes `gitlens.resultsView.statusFileFormat` setting, use `gitlens.explorers.statusFileFormat` instead - Removes `gitlens.annotations.file.hover.changes` setting, use `gitlens.hovers.annotations.changes` instead - Removes `gitlens.annotations.file.hover.details` setting, use `gitlens.hovers.annotations.details` instead - Removes `gitlens.annotations.file.hover.heatmap.enabled` setting @@ -669,7 +669,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Renames _Compare Line Revision with Working_ command (`gitlens.diffLineWithWorking`) to _Compare Line Revision with Working File_ - Renames _Open Changes with Working Tree_ command (`gitlens.openChangesWithWorking`) to _Open Changes with Working File_ - Deprecates `gitlens.gitExplorer.gravatarsDefault` setting, replaced by `gitlens.defaultGravatarsStyle` -- Deprecates `gitlens.resultsExplorer.gravatarsDefault` setting, replaced by `gitlens.defaultGravatarsStyle` +- Deprecates `gitlens.resultsView.gravatarsDefault` setting, replaced by `gitlens.defaultGravatarsStyle` ### Fixed @@ -750,8 +750,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Adds `gitlens.gitExplorer.gravatars` setting to specify whether to show gravatar images instead of commit (or status) icons in the _GitLens_ explorer - Adds `gitlens.gitExplorer.gravatarsDefault` setting to specify the style of the gravatar default (fallback) images in the _GitLens_ explorer
`identicon` - a geometric pattern
`mm` - (mystery-man) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)
`monsterid` - a monster with different colors, faces, etc
`retro` - 8-bit arcade-style pixelated faces
`robohash` - a robot with different colors, faces, etc
`wavatar` - faces with differing features and backgrounds - - Adds `gitlens.resultsExplorer.gravatars` setting to specify whether to show gravatar images instead of commit (or status) icons in the _GitLens Results_ explorer - - Adds `gitlens.resultsExplorer.gravatarsDefault` setting to specify the style of the gravatar default (fallback) images in the _GitLens Results_ explorer
`identicon` - a geometric pattern
`mm` - (mystery-man) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)
`monsterid` - a monster with different colors, faces, etc
`retro` - 8-bit arcade-style pixelated faces
`robohash` - a robot with different colors, faces, etc
`wavatar` - faces with differing features and backgrounds + - Adds `gitlens.resultsView.gravatars` setting to specify whether to show gravatar images instead of commit (or status) icons in the _GitLens Results_ explorer + - Adds `gitlens.resultsView.gravatarsDefault` setting to specify the style of the gravatar default (fallback) images in the _GitLens Results_ explorer
`identicon` - a geometric pattern
`mm` - (mystery-man) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)
`monsterid` - a monster with different colors, faces, etc
`retro` - 8-bit arcade-style pixelated faces
`robohash` - a robot with different colors, faces, etc
`wavatar` - faces with differing features and backgrounds - Adds _Select for Compare_ command (`gitlens.explorers.selectForCompare`) to branch, remote branch, tag, and revision (commit) nodes in the _GitLens_ explorer to mark the base reference of a comparison - Adds _Compare with Selected_ command (`gitlens.explorers.compareWithSelected`) to branch, remote branch, tag, and revision (commit) nodes in the _GitLens_ explorer once another reference within the same repository has been selected to compare the current selection with the previously selected reference in the _GitLens Results_ explorer diff --git a/README.md b/README.md index 2f70f40..62d1729 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,13 @@


- GitLens Logo + GitLens Logo

> GitLens **supercharges** the Git capabilities built into Visual Studio Code. It helps you to **visualize code authorship** at a glance via Git blame annotations and code lens, **seamlessly navigate and explore** Git repositories, **gain valuable insights** via powerful comparison commands, and so much more.
-https://raw.githubusercontent.com/eamodio/vscode-gitlens/blob/cd90faa526720cb4b07a52b3cf84abaa55a978a0/images/cl-heatmap-cold.png + # What's new in GitLens 9 ## 9.0 — September 2018 @@ -27,10 +27,10 @@ GitLens simply helps you understand code better. Quickly glimpse into whom, why, Here are just some of the features that GitLens provides, -- a [_Repositories_ explorer](#repositories-explorer 'Jump to the Repositories explorer') to visualize, navigate, and explore Git repositories -- a [_File History_ explorer](#file-history-explorer 'Jump to the File History explorer') to visualize, navigate, and explore the revision history of the current file -- a [_Line History_ explorer](#line-history-explorer 'Jump to the Line History explorer') to visualize, navigate, and explore the revision history of the selected lines of current file -- an on-demand [_Results_ explorer](#results-explorer 'Jump to the Results explorer') to navigate and explore commits, histories, and searches, or visualize comparisons between branches, tags, commits, and more +- a [_Repositories_ view](#repositories-view 'Jump to the Repositories view') to visualize, navigate, and explore Git repositories +- a [_File History_ view](#file-history-view 'Jump to the File History view') to visualize, navigate, and explore the revision history of the current file +- a [_Line History_ view](#line-history-view 'Jump to the Line History view') to visualize, navigate, and explore the revision history of the selected lines of current file +- an on-demand [_Results_ view](#results-view 'Jump to the Results view') to navigate and explore commits, histories, and searches, or visualize comparisons between branches, tags, commits, and more - [authorship code lens](#code-lens 'Jump to the Code Lens') showing the most recent commit and # of authors to the top of files and/or on code blocks - an unobtrusive [current line blame](#current-line-blame 'Jump to the Current Line Blame') annotation at the end of the line - on-demand [gutter blame](#gutter-blame 'Jump to the Gutter Blame') annotations, including a heatmap, for the whole file @@ -81,7 +81,7 @@ None yet — could be you! #### Bronze Sponsors ($50+) -- Michael Duffy +None yet — could be you! ## Configuration @@ -95,22 +95,22 @@ For more advanced customizations, refer to the [settings documentation](#gitlens ## Features -### Repositories Explorer +### Repositories view

- Repositories Explorer + Repositories view

-A [customizable](#repositories-explorer-settings 'Jump to the Repositories explorer settings') explorer to visualize, navigate, and explore Git repositories. +A [customizable](#repositories-view-settings 'Jump to the Repositories view settings') view to visualize, navigate, and explore Git repositories. - A toolbar provides _Search Commits_, and _Refresh_ commands - A context menu provides _Automatic Layout_, _List Layout_, _Tree Layout_, and _Enable Automatic Refresh_ or _Disable Automatic Refresh_ commands -The repositories explorer provides the following features, +The repositories view provides the following features, - **Repository Status** - - Provides the name of the current branch, [optionally](#repositories-explorer-settings 'Jump to the Repositories explorer settings') its working tree status, and its upstream tracking branch and status (if available) + - Provides the name of the current branch, [optionally](#repositories-view-settings 'Jump to the Repositories view settings') its working tree status, and its upstream tracking branch and status (if available) - Provides indicator dots on the repository icon which denote the following: - _None_ — up-to-date with the upstream - _Green_ — ahead of the upstream @@ -121,13 +121,13 @@ The repositories explorer provides the following features, - is ahead of the upstream — quickly see and explore the specific commits ahead of the upstream (i.e. commits that haven't been pushed) - A context menu provides _Open Repository on Remote_, and _Refresh_ commands - **Changed Files** — lists all the "working" changes - - Expands to a file-based view of all changed files in the working tree ([optionally](#repositories-explorer-settings 'Jump to the Repositories explorer settings')) and/or all files in all commits ahead of the upstream + - Expands to a file-based view of all changed files in the working tree ([optionally](#repositories-view-settings 'Jump to the Repositories view settings')) and/or all files in all commits ahead of the upstream - **History (current-branch)** — lists the revision (commit) history of the current branch - See the _Branches expand_ section under **Branches** below for more details - **Branches** — lists the local branches - - Indicates which branch is the current branch and [optionally](#repositories-explorer-settings 'Jump to the Repositories explorer settings') shows the remote tracking branch + - Indicates which branch is the current branch and [optionally](#repositories-view-settings 'Jump to the Repositories view settings') shows the remote tracking branch - A context menu provides _Open Branches on Remote_, and _Refresh_ commands - Branches expand to show its revision (commit) history - Provides indicator dots on each branch icon which denote the following: @@ -173,18 +173,18 @@ The repositories explorer provides the following features, --- -### File History Explorer +### File History view

- File History Explorer + File History view

-A [customizable](#file-history-explorer-settings 'Jump to the File History explorer settings') explorer to visualize, navigate, and explore the revision history of the current file. +A [customizable](#file-history-view-settings 'Jump to the File History view settings') view to visualize, navigate, and explore the revision history of the current file. - A toolbar provides a _Refresh_ command - A context menu provides a _Follow Renames_ or _Don't Follow Renames_ command -The file history explorer provides the following features, +The file history view provides the following features, - Automatically updates to track the current editor - A context menu provides _Open File_, _Open File on Remote_ (if available), _Copy Remote File Url to Clipboard_ (if available), and _Refresh_ commands @@ -194,13 +194,13 @@ The file history explorer provides the following features, --- -### Line History Explorer +### Line History view

- Line History Explorer + Line History view

-A [customizable](#line-history-explorer-settings 'Jump to the Line History explorer settings') explorer to visualize, navigate, and explore the revision history of the selected lines of current file. +A [customizable](#line-history-view-settings 'Jump to the Line History view settings') view to visualize, navigate, and explore the revision history of the selected lines of current file. - A toolbar provides a _Refresh_ command - A context menu provides a _Follow Renames_ or _Don't Follow Renames_ command @@ -215,18 +215,18 @@ The line history explorer provides the following features, --- -### Results Explorer +### Results view

- Results explorer + Results view

-An on-demand, [customizable](#results-explorer-settings 'Jump to the Results explorer settings') explorer to navigate and explore commits, histories, and searches, or visualize comparisons between branches, tags, commits, and more +An on-demand, [customizable](#results-view-settings 'Jump to the Results view settings') view to navigate and explore commits, histories, and searches, or visualize comparisons between branches, tags, commits, and more - A toolbar provides _Search Commits_, _Keep Results_, and _Refresh_ commands - A context menu provides _Automatic Layout_, _List Layout_, _Tree Layout_, and _Close_ commands -The results explorer provides the following features, +The results view provides the following features, #### Explore @@ -248,11 +248,11 @@ The results explorer provides the following features, - Provides a semi-persistent results view for comparison operations - Accessible via the following commands - - _Compare with Remote_ command (`gitlens.explorers.compareWithRemote`) - - _Compare with HEAD_ command (`gitlens.explorers.compareWithHead`) - - _Compare with Working Tree_ command (`gitlens.explorers.compareWithWorking`) - - _Compare with Selected_ command (`gitlens.explorers.compareWithSelected`) - - _Compare Ancestry with Working Tree_ command (`gitlens.explorers.compareAncestryWithWorking`) + - _Compare with Remote_ command (`gitlens.views.compareWithRemote`) + - _Compare with HEAD_ command (`gitlens.views.compareWithHead`) + - _Compare with Working Tree_ command (`gitlens.views.compareWithWorking`) + - _Compare with Selected_ command (`gitlens.views.compareWithSelected`) + - _Compare Ancestry with Working Tree_ command (`gitlens.views.compareAncestryWithWorking`) - An inline toolbar provides _Swap Comparision_, and _Clear Results_ commands - A context menu provides _Clear Results_, _Swap Comparision_, _Open Directory Compare_, and _Refresh_ commands @@ -454,7 +454,7 @@ The results explorer provides the following features, - Use `#` to search for a commit with id of `` — See [Git docs](https://git-scm.com/docs/git-log 'Open Git docs') - Use `~` to search for commits with differences whose patch text contains added/removed lines that match `` — See [Git docs](https://git-scm.com/docs/git-log#git-log--Gltregexgt 'Open Git docs') - Use `=` to search for commits with differences that change the number of occurrences of the specified string (i.e. addition/deletion) in a file — See [Git docs](https://git-scm.com/docs/git-log#git-log--Sltstringgt 'Open Git docs') - - Provides a _Show in Results_ option to show the search results in the _Results_ explorer + - Provides a _Show in Results_ option to show the search results in the _Results_ view --- @@ -635,65 +635,65 @@ GitLens is highly customizable and provides many configuration settings to allow | `gitlens.settings.mode` | Specifies the display mode of the interactive settings editor
`simple` - only displays common settings
`advanced` - displays all settings | | `gitlens.showWhatsNewAfterUpgrades` | Specifies whether to show What's New after upgrading to new feature releases | -### Repositories Explorer Settings - -See also [Explorer Settings](#explorer-settings 'Jump to the Explorer settings') - -| Name | Description | -| ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `gitlens.repositoriesExplorer.autoRefresh` | Specifies whether to automatically refresh the _Repositories_ explorer when the repository or the file system changes | -| `gitlens.repositoriesExplorer.autoReveal` | Specifies whether to automatically reveal repositories in the _Repositories_ explorer when opening files | -| `gitlens.repositoriesExplorer.branches.layout` | Specifies how the _Repositories_ explorer will display branches
`list` - displays branches as a list
`tree` - displays branches as a tree when branch names contain slashes `/` | -| `gitlens.repositoriesExplorer.enabled` | Specifies whether to show the _Repositories_ explorer | -| `gitlens.repositoriesExplorer.files.compact` | Specifies whether to compact (flatten) unnecessary file nesting in the _Repositories_ explorer
Only applies when `gitlens.repositoriesExplorer.files.layout` is set to `tree` or `auto` | -| `gitlens.repositoriesExplorer.files.layout` | Specifies how the _Repositories_ explorer will display files
`auto` - automatically switches between displaying files as a `tree` or `list` based on the `gitlens.repositoriesExplorer.files.threshold` value and the number of files at each nesting level
`list` - displays files as a list
`tree` - displays files as a tree | -| `gitlens.repositoriesExplorer.files.threshold` | Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the _Repositories_ explorer
Only applies when `gitlens.repositoriesExplorer.files.layout` is set to `auto` | -| `gitlens.repositoriesExplorer.includeWorkingTree` | Specifies whether to include working tree files inside the `Repository Status` node of the _Repositories_ explorer | -| `gitlens.repositoriesExplorer.location` | Specifies where to show the _Repositories_ explorer
`gitlens` - adds to the GitLens view
`explorer` - adds to the Explorer view
`scm` - adds to the Source Control view | -| `gitlens.repositoriesExplorer.showTrackingBranch` | Specifies whether to show the tracking branch when displaying local branches in the _Repositories_ explorer | - -### File History Explorer Settings - -See also [Explorer Settings](#explorer-settings 'Jump to the Explorer settings') - -| Name | Description | -| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `gitlens.fileHistoryExplorer.avatars` | Specifies whether to show avatar images instead of status icons in the _File History_ explorer | -| `gitlens.fileHistoryExplorer.enabled` | Specifies whether to show the _File History_ explorer | -| `gitlens.fileHistoryExplorer.location` | Specifies where to show the _File History_ explorer
`gitlens` - adds to the GitLens view
`explorer` - adds to the Explorer view
`scm` - adds to the Source Control view | - -### Line History Explorer Settings - -See also [Explorer Settings](#explorer-settings 'Jump to the Explorer settings') - -| Name | Description | -| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `gitlens.lineHistoryExplorer.avatars` | Specifies whether to show avatar images instead of status icons in the _Line History_ explorer | -| `gitlens.lineHistoryExplorer.enabled` | Specifies whether to show the _Line History_ explorer | -| `gitlens.lineHistoryExplorer.location` | Specifies where to show the _Line History_ explorer
`gitlens` - adds to the GitLens view
`explorer` - adds to the Explorer view
`scm` - adds to the Source Control view | - -### Results Explorer Settings - -See also [Explorer Settings](#explorer-settings 'Jump to the Explorer settings') - -| Name | Description | -| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `gitlens.resultsExplorer.files.compact` | Specifies whether to compact (flatten) unnecessary file nesting in the _Results_ explorer
Only applies when `gitlens.resultsExplorer.files.layout` is set to `tree` or `auto` | -| `gitlens.resultsExplorer.files.layout` | Specifies how the _Results_ explorer will display files
`auto` - automatically switches between displaying files as a `tree` or `list` based on the `gitlens.resultsExplorer.files.threshold` value and the number of files at each nesting level
`list` - displays files as a list
`tree` - displays files as a tree | -| `gitlens.resultsExplorer.files.threshold` | Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the _Results_ explorer
Only applies when `gitlens.resultsExplorer.files.layout` is set to `auto` | -| `gitlens.resultsExplorer.location` | Specifies where to show the _Results_ explorer
`gitlens` - adds to the GitLens view
`explorer` - adds to the Explorer view
`scm` - adds to the Source Control view | - -### Explorer Settings - -| Name | Description | -| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `gitlens.explorers.avatars` | Specifies whether to show avatar images instead of commit (or status) icons in the _Repositories_ and _Results_ explorers | -| `gitlens.explorers.commitFileFormat` | Specifies the format of a committed file in the _Repositories_ and _Results_ explorers
Available tokens
${directory} - directory name
${file} - file name
${filePath} - formatted file name and path
${path} - full file path | -| `gitlens.explorers.commitFormat` | Specifies the format of committed changes in the _Repositories_ and _Results_ explorers
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`)
${agoOrDate} - commit date specified by `gitlens.defaultDateStyle`
${authorAgo} - commit author, relative commit date
${authorAgoOrDate} - commit author, commit date specified by `gitlens.defaultDateStyle`
See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting | -| `gitlens.explorers.defaultItemLimit` | Specifies the default number of items to show in an explorer list. Use 0 to specify no limit | -| `gitlens.explorers.stashFileFormat` | Specifies the format of a stashed file in the _Repositories_ and _Results_ explorers
Available tokens
${directory} - directory name
${file} - file name
${filePath} - formatted file name and path
${path} - full file path | -| `gitlens.explorers.stashFormat` | Specifies the format of stashed changes in the _Repositories_ and _Results_ explorers
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`)
${agoOrDate} - commit date specified by `gitlens.defaultDateStyle`
${authorAgo} - commit author, relative commit date
${authorAgoOrDate} - commit author, commit date specified by `gitlens.defaultDateStyle`
See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting | -| `gitlens.explorers.statusFileFormat` | Specifies the format of the status of a working or committed file in the _Repositories_ explorer
Available tokens
${directory} - directory name
${file} - file name
${filePath} - formatted file name and path
${path} - full file path
${working} - optional indicator if the file is uncommitted | +### Repositories View Settings + +See also [View Settings](#view-settings 'Jump to the View settings') + +| Name | Description | +| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `gitlens.views.repositories.autoRefresh` | Specifies whether to automatically refresh the _Repositories_ view when the repository or the file system changes | +| `gitlens.views.repositories.autoReveal` | Specifies whether to automatically reveal repositories in the _Repositories_ view when opening files | +| `gitlens.views.repositories.branches.layout` | Specifies how the _Repositories_ view will display branches
`list` - displays branches as a list
`tree` - displays branches as a tree when branch names contain slashes `/` | +| `gitlens.views.repositories.enabled` | Specifies whether to show the _Repositories_ view | +| `gitlens.views.repositories.files.compact` | Specifies whether to compact (flatten) unnecessary file nesting in the _Repositories_ view
Only applies when `gitlens.views.repositories.files.layout` is set to `tree` or `auto` | +| `gitlens.views.repositories.files.layout` | Specifies how the _Repositories_ view will display files
`auto` - automatically switches between displaying files as a `tree` or `list` based on the `gitlens.views.repositories.files.threshold` value and the number of files at each nesting level
`list` - displays files as a list
`tree` - displays files as a tree | +| `gitlens.views.repositories.files.threshold` | Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the _Repositories_ view
Only applies when `gitlens.views.repositories.files.layout` is set to `auto` | +| `gitlens.views.repositories.includeWorkingTree` | Specifies whether to include working tree files inside the `Repository Status` node of the _Repositories_ view | +| `gitlens.views.repositories.location` | Specifies where to show the _Repositories_ view
`gitlens` - adds to the GitLens view
`explorer` - adds to the Explorer view
`scm` - adds to the Source Control view | +| `gitlens.views.repositories.showTrackingBranch` | Specifies whether to show the tracking branch when displaying local branches in the _Repositories_ view | + +### File History View Settings + +See also [View Settings](#view-settings 'Jump to the View settings') + +| Name | Description | +| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `gitlens.views.fileHistory.avatars` | Specifies whether to show avatar images instead of status icons in the _File History_ view | +| `gitlens.views.fileHistory.enabled` | Specifies whether to show the _File History_ view | +| `gitlens.views.fileHistory.location` | Specifies where to show the _File History_ view
`gitlens` - adds to the GitLens view
`explorer` - adds to the Explorer view
`scm` - adds to the Source Control view | + +### Line History View Settings + +See also [View Settings](#view-settings 'Jump to the View settings') + +| Name | Description | +| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `gitlens.views.lineHistory.avatars` | Specifies whether to show avatar images instead of status icons in the _Line History_ view | +| `gitlens.views.lineHistory.enabled` | Specifies whether to show the _Line History_ view | +| `gitlens.views.lineHistory.location` | Specifies where to show the _Line History_ view
`gitlens` - adds to the GitLens view
`explorer` - adds to the Explorer view
`scm` - adds to the Source Control view | + +### Results View Settings + +See also [View Settings](#view-settings 'Jump to the View settings') + +| Name | Description | +| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `gitlens.views.results.files.compact` | Specifies whether to compact (flatten) unnecessary file nesting in the _Results_ view
Only applies when `gitlens.views.results.files.layout` is set to `tree` or `auto` | +| `gitlens.views.results.files.layout` | Specifies how the _Results_ view will display files
`auto` - automatically switches between displaying files as a `tree` or `list` based on the `gitlens.views.results.files.threshold` value and the number of files at each nesting level
`list` - displays files as a list
`tree` - displays files as a tree | +| `gitlens.views.results.files.threshold` | Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the _Results_ view
Only applies when `gitlens.views.results.files.layout` is set to `auto` | +| `gitlens.views.results.location` | Specifies where to show the _Results_ view
`gitlens` - adds to the GitLens view
`explorer` - adds to the Explorer view
`scm` - adds to the Source Control view | + +### View Settings + +| Name | Description | +| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `gitlens.views.avatars` | Specifies whether to show avatar images instead of commit (or status) icons in the _Repositories_ and _Results_ views | +| `gitlens.views.commitFileFormat` | Specifies the format of a committed file in the _Repositories_ and _Results_ views
Available tokens
${directory} - directory name
${file} - file name
${filePath} - formatted file name and path
${path} - full file path | +| `gitlens.views.commitFormat` | Specifies the format of committed changes in the _Repositories_ and _Results_ views
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`)
${agoOrDate} - commit date specified by `gitlens.defaultDateStyle`
${authorAgo} - commit author, relative commit date
${authorAgoOrDate} - commit author, commit date specified by `gitlens.defaultDateStyle`
See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting | +| `gitlens.views.defaultItemLimit` | Specifies the default number of items to show in a view list. Use 0 to specify no limit | +| `gitlens.views.stashFileFormat` | Specifies the format of a stashed file in the _Repositories_ and _Results_ views
Available tokens
${directory} - directory name
${file} - file name
${filePath} - formatted file name and path
${path} - full file path | +| `gitlens.views.stashFormat` | Specifies the format of stashed changes in the _Repositories_ and _Results_ views
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`)
${agoOrDate} - commit date specified by `gitlens.defaultDateStyle`
${authorAgo} - commit author, relative commit date
${authorAgoOrDate} - commit author, commit date specified by `gitlens.defaultDateStyle`
See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting | +| `gitlens.views.statusFileFormat` | Specifies the format of the status of a working or committed file in the _Repositories_ view
Available tokens
${directory} - directory name
${file} - file name
${filePath} - formatted file name and path
${path} - full file path
${working} - optional indicator if the file is uncommitted | ### Code Lens Settings diff --git a/package.json b/package.json index b5bab29..963577b 100644 --- a/package.json +++ b/package.json @@ -437,136 +437,6 @@ "description": "Specifies the style of the gravatar default (fallback) images", "scope": "window" }, - "gitlens.explorers.avatars": { - "type": "boolean", - "default": true, - "description": "Specifies whether to show avatar images instead of commit (or status) icons in the `Repositories` and `Results` explorers", - "scope": "window" - }, - "gitlens.explorers.commitFileFormat": { - "type": "string", - "default": "${filePath}", - "description": "Specifies the format of a committed file in the `Repositories` and `Results` explorers\nAvailable tokens\n ${directory} - directory name\n ${file} - file name\n ${filePath} - formatted file name and path\n ${path} - full file path", - "scope": "window" - }, - "gitlens.explorers.commitFormat": { - "type": "string", - "default": "${message} • ${authorAgoOrDate}${ • changes}${ (id)}", - "description": "Specifies the format of committed changes in the `Repositories` and `Results` explorers\nAvailable tokens\n ${id} - commit id\n ${author} - commit author\n ${message} - commit message\n ${ago} - relative commit date (e.g. 1 day ago)\n ${date} - formatted commit date (format specified by `gitlens.defaultDateFormat`)\\n ${agoOrDate} - commit date specified by `gitlens.defaultDateStyle`\n ${authorAgo} - commit author, relative commit date\n ${authorAgoOrDate} - commit author, commit date specified by `gitlens.defaultDateStyle`\nSee https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting", - "scope": "window" - }, - "gitlens.explorers.defaultItemLimit": { - "type": "number", - "default": 10, - "description": "Specifies the default number of items to show in an explorer list. Use 0 to specify no limit", - "scope": "window" - }, - "gitlens.explorers.stashFileFormat": { - "type": "string", - "default": "${filePath}", - "description": "Specifies the format of a stashed file in the `Repositories` and `Results` explorers\nAvailable tokens\n ${directory} - directory name\n ${file} - file name\n ${filePath} - formatted file name and path\n ${path} - full file path", - "scope": "window" - }, - "gitlens.explorers.stashFormat": { - "type": "string", - "default": "${message}", - "description": "Specifies the format of stashed changes in the `Repositories` and `Results` explorers\nAvailable tokens\n ${id} - commit id\n ${author} - commit author\n ${message} - commit message\n ${ago} - relative commit date (e.g. 1 day ago)\n ${date} - formatted commit date (format specified by `gitlens.statusBar.dateFormat`)\n ${agoOrDate} - commit date specified by `gitlens.defaultDateStyle`\n ${authorAgo} - commit author, relative commit date\n ${authorAgoOrDate} - commit author, commit date specified by `gitlens.defaultDateStyle`\nSee https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting", - "scope": "window" - }, - "gitlens.explorers.statusFileFormat": { - "type": "string", - "default": "${working }${filePath}", - "description": "Specifies the format of the status of a working or committed file in the `Repositories` explorer\nAvailable tokens\n ${directory} - directory name\n ${file} - file name\n ${filePath} - formatted file name and path\n ${path} - full file path\n ${working} - optional indicator if the file is uncommitted", - "scope": "window" - }, - "gitlens.repositoriesExplorer.autoRefresh": { - "type": "boolean", - "default": true, - "description": "Specifies whether to automatically refresh the `Repositories` explorer when the repository or the file system changes", - "scope": "window" - }, - "gitlens.repositoriesExplorer.autoReveal": { - "type": "boolean", - "default": true, - "description": "Specifies whether to automatically reveal repositories in the `Repositories` explorer when opening files", - "scope": "window" - }, - "gitlens.repositoriesExplorer.branches.layout": { - "type": "string", - "default": "tree", - "enum": [ - "list", - "tree" - ], - "enumDescriptions": [ - "Displays branches as a list", - "Displays branches as a tree when branch names contain slashes `/`" - ], - "description": "Specifies how the `Repositories` explorer will display branches", - "scope": "window" - }, - "gitlens.repositoriesExplorer.enabled": { - "type": "boolean", - "default": true, - "description": "Specifies whether to show the `Repositories` explorer", - "scope": "window" - }, - "gitlens.repositoriesExplorer.files.compact": { - "type": "boolean", - "default": true, - "description": "Specifies whether to compact (flatten) unnecessary file nesting in the `Repositories` explorer\nOnly applies when `#gitlens.repositoriesExplorer.files.layout#` is set to `tree` or `auto`", - "scope": "window" - }, - "gitlens.repositoriesExplorer.files.layout": { - "type": "string", - "default": "auto", - "enum": [ - "auto", - "list", - "tree" - ], - "enumDescriptions": [ - "Automatically switches between displaying files as a `tree` or `list` based on the `#gitlens.repositoriesExplorer.files.threshold#` value and the number of files at each nesting level", - "Displays files as a list", - "Displays files as a tree" - ], - "description": "Specifies how the `Repositories` explorer will display files", - "scope": "window" - }, - "gitlens.repositoriesExplorer.files.threshold": { - "type": "number", - "default": 5, - "description": "Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the `Repositories` explorer\nOnly applies when `#gitlens.repositoriesExplorer.files.layout#` is set to `auto`", - "scope": "window" - }, - "gitlens.repositoriesExplorer.includeWorkingTree": { - "type": "boolean", - "default": true, - "description": "Specifies whether to include working tree files inside the `Repository Status` node of the `Repositories` explorer", - "scope": "window" - }, - "gitlens.repositoriesExplorer.location": { - "type": "string", - "default": "gitlens", - "enum": [ - "gitlens", - "explorer", - "scm" - ], - "enumDescriptions": [ - "Adds to the GitLens view", - "Adds to the Explorer view", - "Adds to the Source Control view" - ], - "description": "Specifies where to show the `Repositories` explorer", - "scope": "window" - }, - "gitlens.repositoriesExplorer.showTrackingBranch": { - "type": "boolean", - "default": true, - "description": "Specifies whether to show the tracking branch when displaying local branches in the `Repositories` explorer", - "scope": "window" - }, "gitlens.heatmap.ageThreshold": { "type": "string", "default": "90", @@ -599,34 +469,6 @@ "description": "Specifies how the gutter heatmap annotations will be toggled", "scope": "window" }, - "gitlens.fileHistoryExplorer.avatars": { - "type": "boolean", - "default": true, - "description": "Specifies whether to show avatar images instead of status icons in the `File History` explorer", - "scope": "window" - }, - "gitlens.fileHistoryExplorer.enabled": { - "type": "boolean", - "default": true, - "description": "Specifies whether to show the `File History` explorer", - "scope": "window" - }, - "gitlens.fileHistoryExplorer.location": { - "type": "string", - "default": "gitlens", - "enum": [ - "gitlens", - "explorer", - "scm" - ], - "enumDescriptions": [ - "Adds to the GitLens view", - "Adds to the Explorer view", - "Adds to the Source Control view" - ], - "description": "Specifies where to show the `File History` explorer", - "scope": "window" - }, "gitlens.hovers.annotations.changes": { "type": "boolean", "default": true, @@ -725,34 +567,6 @@ "description": "Specifies the keymap to use for GitLens shortcut keys", "scope": "window" }, - "gitlens.lineHistoryExplorer.avatars": { - "type": "boolean", - "default": true, - "description": "Specifies whether to show avatar images instead of status icons in the `Line History` explorer", - "scope": "window" - }, - "gitlens.lineHistoryExplorer.enabled": { - "type": "boolean", - "default": true, - "description": "Specifies whether to show the `Line History` explorer", - "scope": "window" - }, - "gitlens.lineHistoryExplorer.location": { - "type": "string", - "default": "gitlens", - "enum": [ - "gitlens", - "explorer", - "scm" - ], - "enumDescriptions": [ - "Adds to the GitLens view", - "Adds to the Explorer view", - "Adds to the Source Control view" - ], - "description": "Specifies where to show the `Line History` explorer", - "scope": "window" - }, "gitlens.menus": { "anyOf": [ { @@ -948,14 +762,14 @@ "currentLine": { "type": "boolean" }, - "explorers": { - "type": "boolean" - }, "hovers": { "type": "boolean" }, "statusBar": { "type": "boolean" + }, + "views": { + "type": "boolean" } } }, @@ -980,14 +794,14 @@ "currentLine": { "type": "boolean" }, - "explorers": { - "type": "boolean" - }, "hovers": { "type": "boolean" }, "statusBar": { "type": "boolean" + }, + "views": { + "type": "boolean" } } } @@ -1013,14 +827,14 @@ "currentLine": { "type": "boolean" }, - "explorers": { - "type": "boolean" - }, "hovers": { "type": "boolean" }, "statusBar": { "type": "boolean" + }, + "views": { + "type": "boolean" } } }, @@ -1191,50 +1005,6 @@ "description": "Specifies user-defined remote (code-hosting) services or custom domains for built-in remote services", "scope": "resource" }, - "gitlens.resultsExplorer.files.compact": { - "type": "boolean", - "default": true, - "description": "Specifies whether to compact (flatten) unnecessary file nesting in the `Results` explorer\nOnly applies when `#gitlens.resultsExplorer.files.layout#` is set to `tree` or `auto`", - "scope": "window" - }, - "gitlens.resultsExplorer.files.layout": { - "type": "string", - "default": "auto", - "enum": [ - "auto", - "list", - "tree" - ], - "enumDescriptions": [ - "Automatically switches between displaying files as a `tree` or `list` based on the `#gitlens.repositoriesExplorer.files.threshold#` value and the number of files at each nesting level", - "Displays files as a list", - "Displays files as a tree" - ], - "description": "Specifies how the `Results` explorer will display files", - "scope": "window" - }, - "gitlens.resultsExplorer.files.threshold": { - "type": "number", - "default": 5, - "description": "Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the `Results` explorer\nOnly applies when `#gitlens.resultsExplorer.files.layout#` is set to `auto`", - "scope": "window" - }, - "gitlens.resultsExplorer.location": { - "type": "string", - "default": "gitlens", - "enum": [ - "gitlens", - "explorer", - "scm" - ], - "enumDescriptions": [ - "Adds to the GitLens view", - "Adds to the Explorer view", - "Adds to the Source Control view" - ], - "description": "Specifies where to show the `Results` explorer", - "scope": "window" - }, "gitlens.settings.mode": { "type": "string", "default": "simple", @@ -1337,6 +1107,236 @@ "description": "Specifies the string to be shown in place of the `authors` code lens when there are unsaved changes", "scope": "window" }, + "gitlens.views.avatars": { + "type": "boolean", + "default": true, + "description": "Specifies whether to show avatar images instead of commit (or status) icons in the `Repositories` and `Results` views", + "scope": "window" + }, + "gitlens.views.commitFileFormat": { + "type": "string", + "default": "${filePath}", + "description": "Specifies the format of a committed file in the `Repositories` and `Results` views\nAvailable tokens\n ${directory} - directory name\n ${file} - file name\n ${filePath} - formatted file name and path\n ${path} - full file path", + "scope": "window" + }, + "gitlens.views.commitFormat": { + "type": "string", + "default": "${message} • ${authorAgoOrDate}${ • changes}${ (id)}", + "description": "Specifies the format of committed changes in the `Repositories` and `Results` views\nAvailable tokens\n ${id} - commit id\n ${author} - commit author\n ${message} - commit message\n ${ago} - relative commit date (e.g. 1 day ago)\n ${date} - formatted commit date (format specified by `gitlens.defaultDateFormat`)\\n ${agoOrDate} - commit date specified by `gitlens.defaultDateStyle`\n ${authorAgo} - commit author, relative commit date\n ${authorAgoOrDate} - commit author, commit date specified by `gitlens.defaultDateStyle`\nSee https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting", + "scope": "window" + }, + "gitlens.views.defaultItemLimit": { + "type": "number", + "default": 10, + "description": "Specifies the default number of items to show in a view list. Use 0 to specify no limit", + "scope": "window" + }, + "gitlens.views.fileHistory.avatars": { + "type": "boolean", + "default": true, + "description": "Specifies whether to show avatar images instead of status icons in the `File History` view", + "scope": "window" + }, + "gitlens.views.fileHistory.enabled": { + "type": "boolean", + "default": true, + "description": "Specifies whether to show the `File History` view", + "scope": "window" + }, + "gitlens.views.fileHistory.location": { + "type": "string", + "default": "gitlens", + "enum": [ + "gitlens", + "explorer", + "scm" + ], + "enumDescriptions": [ + "Adds to the GitLens view", + "Adds to the Explorer view", + "Adds to the Source Control view" + ], + "description": "Specifies where to show the `File History` view", + "scope": "window" + }, + "gitlens.views.lineHistory.avatars": { + "type": "boolean", + "default": true, + "description": "Specifies whether to show avatar images instead of status icons in the `Line History` view", + "scope": "window" + }, + "gitlens.views.lineHistory.enabled": { + "type": "boolean", + "default": true, + "description": "Specifies whether to show the `Line History` view", + "scope": "window" + }, + "gitlens.views.lineHistory.location": { + "type": "string", + "default": "gitlens", + "enum": [ + "gitlens", + "explorer", + "scm" + ], + "enumDescriptions": [ + "Adds to the GitLens view", + "Adds to the Explorer view", + "Adds to the Source Control view" + ], + "description": "Specifies where to show the `Line History` view", + "scope": "window" + }, + "gitlens.views.repositories.autoRefresh": { + "type": "boolean", + "default": true, + "description": "Specifies whether to automatically refresh the `Repositories` view when the repository or the file system changes", + "scope": "window" + }, + "gitlens.views.repositories.autoReveal": { + "type": "boolean", + "default": true, + "description": "Specifies whether to automatically reveal repositories in the `Repositories` view when opening files", + "scope": "window" + }, + "gitlens.views.repositories.branches.layout": { + "type": "string", + "default": "tree", + "enum": [ + "list", + "tree" + ], + "enumDescriptions": [ + "Displays branches as a list", + "Displays branches as a tree when branch names contain slashes `/`" + ], + "description": "Specifies how the `Repositories` view will display branches", + "scope": "window" + }, + "gitlens.views.repositories.enabled": { + "type": "boolean", + "default": true, + "description": "Specifies whether to show the `Repositories` view", + "scope": "window" + }, + "gitlens.views.repositories.files.compact": { + "type": "boolean", + "default": true, + "description": "Specifies whether to compact (flatten) unnecessary file nesting in the `Repositories` view\nOnly applies when `#gitlens.views.repositories.files.layout#` is set to `tree` or `auto`", + "scope": "window" + }, + "gitlens.views.repositories.files.layout": { + "type": "string", + "default": "auto", + "enum": [ + "auto", + "list", + "tree" + ], + "enumDescriptions": [ + "Automatically switches between displaying files as a `tree` or `list` based on the `#gitlens.views.repositories.files.threshold#` value and the number of files at each nesting level", + "Displays files as a list", + "Displays files as a tree" + ], + "description": "Specifies how the `Repositories` view will display files", + "scope": "window" + }, + "gitlens.views.repositories.files.threshold": { + "type": "number", + "default": 5, + "description": "Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the `Repositories` view\nOnly applies when `#gitlens.views.repositories.files.layout#` is set to `auto`", + "scope": "window" + }, + "gitlens.views.repositories.includeWorkingTree": { + "type": "boolean", + "default": true, + "description": "Specifies whether to include working tree files inside the `Repository Status` node of the `Repositories` view", + "scope": "window" + }, + "gitlens.views.repositories.location": { + "type": "string", + "default": "gitlens", + "enum": [ + "gitlens", + "explorer", + "scm" + ], + "enumDescriptions": [ + "Adds to the GitLens view", + "Adds to the Explorer view", + "Adds to the Source Control view" + ], + "description": "Specifies where to show the `Repositories` view", + "scope": "window" + }, + "gitlens.views.repositories.showTrackingBranch": { + "type": "boolean", + "default": true, + "description": "Specifies whether to show the tracking branch when displaying local branches in the `Repositories` view", + "scope": "window" + }, + "gitlens.views.results.files.compact": { + "type": "boolean", + "default": true, + "description": "Specifies whether to compact (flatten) unnecessary file nesting in the `Results` view\nOnly applies when `#gitlens.views.results.files.layout#` is set to `tree` or `auto`", + "scope": "window" + }, + "gitlens.views.results.files.layout": { + "type": "string", + "default": "auto", + "enum": [ + "auto", + "list", + "tree" + ], + "enumDescriptions": [ + "Automatically switches between displaying files as a `tree` or `list` based on the `#gitlens.views.repositories.files.threshold#` value and the number of files at each nesting level", + "Displays files as a list", + "Displays files as a tree" + ], + "description": "Specifies how the `Results` view will display files", + "scope": "window" + }, + "gitlens.views.results.files.threshold": { + "type": "number", + "default": 5, + "description": "Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the `Results` view\nOnly applies when `#gitlens.views.results.files.layout#` is set to `auto`", + "scope": "window" + }, + "gitlens.views.results.location": { + "type": "string", + "default": "gitlens", + "enum": [ + "gitlens", + "explorer", + "scm" + ], + "enumDescriptions": [ + "Adds to the GitLens view", + "Adds to the Explorer view", + "Adds to the Source Control view" + ], + "description": "Specifies where to show the `Results` view", + "scope": "window" + }, + "gitlens.views.stashFileFormat": { + "type": "string", + "default": "${filePath}", + "description": "Specifies the format of a stashed file in the `Repositories` and `Results` views\nAvailable tokens\n ${directory} - directory name\n ${file} - file name\n ${filePath} - formatted file name and path\n ${path} - full file path", + "scope": "window" + }, + "gitlens.views.stashFormat": { + "type": "string", + "default": "${message}", + "description": "Specifies the format of stashed changes in the `Repositories` and `Results` views\nAvailable tokens\n ${id} - commit id\n ${author} - commit author\n ${message} - commit message\n ${ago} - relative commit date (e.g. 1 day ago)\n ${date} - formatted commit date (format specified by `gitlens.statusBar.dateFormat`)\n ${agoOrDate} - commit date specified by `gitlens.defaultDateStyle`\n ${authorAgo} - commit author, relative commit date\n ${authorAgoOrDate} - commit author, commit date specified by `gitlens.defaultDateStyle`\nSee https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting", + "scope": "window" + }, + "gitlens.views.statusFileFormat": { + "type": "string", + "default": "${working }${filePath}", + "description": "Specifies the format of the status of a working or committed file in the `Repositories` view\nAvailable tokens\n ${directory} - directory name\n ${file} - file name\n ${filePath} - formatted file name and path\n ${path} - full file path\n ${working} - optional indicator if the file is uncommitted", + "scope": "window" + }, "gitlens.advanced.blame.customArguments": { "type": "array", "default": null, @@ -1522,23 +1522,23 @@ "category": "GitLens" }, { - "command": "gitlens.showFileHistoryExplorer", - "title": "Show File History Explorer", + "command": "gitlens.showFileHistoryView", + "title": "Show File History View", "category": "GitLens" }, { - "command": "gitlens.showLineHistoryExplorer", - "title": "Show Line History Explorer", + "command": "gitlens.showLineHistoryView", + "title": "Show Line History View", "category": "GitLens" }, { - "command": "gitlens.showRepositoriesExplorer", - "title": "Show Repositories Explorer", + "command": "gitlens.showRepositoriesView", + "title": "Show Repositories View", "category": "GitLens" }, { - "command": "gitlens.showResultsExplorer", - "title": "Show Results Explorer", + "command": "gitlens.showResultsView", + "title": "Show Results View", "category": "GitLens" }, { @@ -1853,12 +1853,12 @@ "category": "GitLens" }, { - "command": "gitlens.explorers.exploreRepoRevision", + "command": "gitlens.views.exploreRepoRevision", "title": "Explore the Repository from Here", "category": "GitLens" }, { - "command": "gitlens.repositoriesExplorer.fetchAll", + "command": "gitlens.views.repositories.fetchAll", "title": "Fetch Repositories", "category": "GitLens", "icon": { @@ -1867,7 +1867,7 @@ } }, { - "command": "gitlens.repositoriesExplorer.pullAll", + "command": "gitlens.views.repositories.pullAll", "title": "Pull Repositories", "category": "GitLens", "icon": { @@ -1876,7 +1876,7 @@ } }, { - "command": "gitlens.explorers.fetch", + "command": "gitlens.views.fetch", "title": "Fetch Repository", "category": "GitLens", "icon": { @@ -1885,7 +1885,7 @@ } }, { - "command": "gitlens.explorers.pull", + "command": "gitlens.views.pull", "title": "Pull Repository", "category": "GitLens", "icon": { @@ -1894,7 +1894,7 @@ } }, { - "command": "gitlens.explorers.push", + "command": "gitlens.views.push", "title": "Push Repository", "category": "GitLens", "icon": { @@ -1903,7 +1903,7 @@ } }, { - "command": "gitlens.explorers.stageFile", + "command": "gitlens.views.stageFile", "title": "Stage Changes", "category": "GitLens", "icon": { @@ -1912,7 +1912,7 @@ } }, { - "command": "gitlens.explorers.unstageFile", + "command": "gitlens.views.unstageFile", "title": "Unstage Changes", "category": "GitLens", "icon": { @@ -1921,27 +1921,27 @@ } }, { - "command": "gitlens.explorers.openDirectoryDiff", + "command": "gitlens.views.openDirectoryDiff", "title": "Open Directory Compare", "category": "GitLens" }, { - "command": "gitlens.explorers.openDirectoryDiffWithWorking", + "command": "gitlens.views.openDirectoryDiffWithWorking", "title": "Open Directory Compare with Working Tree", "category": "GitLens" }, { - "command": "gitlens.explorers.openChanges", + "command": "gitlens.views.openChanges", "title": "Open Changes", "category": "GitLens" }, { - "command": "gitlens.explorers.openChangesWithWorking", + "command": "gitlens.views.openChangesWithWorking", "title": "Open Changes with Working File", "category": "GitLens" }, { - "command": "gitlens.explorers.openFile", + "command": "gitlens.views.openFile", "title": "Open File", "category": "GitLens", "icon": { @@ -1950,157 +1950,157 @@ } }, { - "command": "gitlens.explorers.openFileRevision", + "command": "gitlens.views.openFileRevision", "title": "Open Revision", "category": "GitLens" }, { - "command": "gitlens.explorers.openFileRevisionInRemote", + "command": "gitlens.views.openFileRevisionInRemote", "title": "Open Revision on Remote", "category": "GitLens" }, { - "command": "gitlens.explorers.openChangedFiles", + "command": "gitlens.views.openChangedFiles", "title": "Open Files", "category": "GitLens" }, { - "command": "gitlens.explorers.openChangedFileChanges", + "command": "gitlens.views.openChangedFileChanges", "title": "Open All Changes", "category": "GitLens" }, { - "command": "gitlens.explorers.openChangedFileChangesWithWorking", + "command": "gitlens.views.openChangedFileChangesWithWorking", "title": "Open All Changes with Working Tree", "category": "GitLens" }, { - "command": "gitlens.explorers.openChangedFileRevisions", + "command": "gitlens.views.openChangedFileRevisions", "title": "Open Revisions", "category": "GitLens" }, { - "command": "gitlens.explorers.applyChanges", + "command": "gitlens.views.applyChanges", "title": "Apply Changes", "category": "GitLens" }, { - "command": "gitlens.explorers.closeRepository", + "command": "gitlens.views.closeRepository", "title": "Close Repository", "category": "GitLens" }, { - "command": "gitlens.explorers.compareAncestryWithWorking", + "command": "gitlens.views.compareAncestryWithWorking", "title": "Compare Ancestry with Working Tree", "category": "GitLens" }, { - "command": "gitlens.explorers.compareWithHead", + "command": "gitlens.views.compareWithHead", "title": "Compare with HEAD", "category": "GitLens" }, { - "command": "gitlens.explorers.compareWithRemote", + "command": "gitlens.views.compareWithRemote", "title": "Compare with Remote", "category": "GitLens" }, { - "command": "gitlens.explorers.compareWithSelected", + "command": "gitlens.views.compareWithSelected", "title": "Compare with Selected", "category": "GitLens" }, { - "command": "gitlens.explorers.compareWithWorking", + "command": "gitlens.views.compareWithWorking", "title": "Compare with Working Tree", "category": "GitLens" }, { - "command": "gitlens.explorers.selectForCompare", + "command": "gitlens.views.selectForCompare", "title": "Select for Compare", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalCheckoutBranch", + "command": "gitlens.views.terminalCheckoutBranch", "title": "Checkout Branch (via Terminal)", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalCreateBranch", + "command": "gitlens.views.terminalCreateBranch", "title": "Create Branch (via Terminal)...", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalDeleteBranch", + "command": "gitlens.views.terminalDeleteBranch", "title": "Delete Branch (via Terminal)", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalMergeBranch", + "command": "gitlens.views.terminalMergeBranch", "title": "Merge Branch (via Terminal)", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalRebaseBranch", + "command": "gitlens.views.terminalRebaseBranch", "title": "Rebase (Interactive) Branch (via Terminal)", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalRebaseBranchToRemote", + "command": "gitlens.views.terminalRebaseBranchToRemote", "title": "Rebase (Interactive) Branch to Remote (via Terminal)", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalSquashBranchIntoCommit", + "command": "gitlens.views.terminalSquashBranchIntoCommit", "title": "Squash Branch into Commit (via Terminal)", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalCheckoutCommit", + "command": "gitlens.views.terminalCheckoutCommit", "title": "Checkout Commit (via Terminal)", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalCherryPickCommit", + "command": "gitlens.views.terminalCherryPickCommit", "title": "Cherry Pick Commit (via Terminal)", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalPushCommit", + "command": "gitlens.views.terminalPushCommit", "title": "Push to Commit (via Terminal)", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalRebaseCommit", + "command": "gitlens.views.terminalRebaseCommit", "title": "Rebase to Commit (via Terminal)", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalResetCommit", + "command": "gitlens.views.terminalResetCommit", "title": "Reset to Commit (via Terminal)", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalRevertCommit", + "command": "gitlens.views.terminalRevertCommit", "title": "Revert Commit (via Terminal)", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalRemoveRemote", + "command": "gitlens.views.terminalRemoveRemote", "title": "Remove Remote (via Terminal)", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalCreateTag", + "command": "gitlens.views.terminalCreateTag", "title": "Create Tag (via Terminal)...", "category": "GitLens" }, { - "command": "gitlens.explorers.terminalDeleteTag", + "command": "gitlens.views.terminalDeleteTag", "title": "Delete Tag (via Terminal)", "category": "GitLens" }, { - "command": "gitlens.repositoriesExplorer.refresh", + "command": "gitlens.views.repositories.refresh", "title": "Refresh", "category": "GitLens", "icon": { @@ -2109,37 +2109,37 @@ } }, { - "command": "gitlens.repositoriesExplorer.refreshNode", + "command": "gitlens.views.repositories.refreshNode", "title": "Refresh", "category": "GitLens" }, { - "command": "gitlens.repositoriesExplorer.setFilesLayoutToAuto", + "command": "gitlens.views.repositories.setFilesLayoutToAuto", "title": "Automatic Layout", "category": "GitLens" }, { - "command": "gitlens.repositoriesExplorer.setFilesLayoutToList", + "command": "gitlens.views.repositories.setFilesLayoutToList", "title": "List Layout", "category": "GitLens" }, { - "command": "gitlens.repositoriesExplorer.setFilesLayoutToTree", + "command": "gitlens.views.repositories.setFilesLayoutToTree", "title": "Tree Layout", "category": "GitLens" }, { - "command": "gitlens.repositoriesExplorer.setAutoRefreshToOn", + "command": "gitlens.views.repositories.setAutoRefreshToOn", "title": "Enable Automatic Refresh", "category": "GitLens" }, { - "command": "gitlens.repositoriesExplorer.setAutoRefreshToOff", + "command": "gitlens.views.repositories.setAutoRefreshToOff", "title": "Disable Automatic Refresh", "category": "GitLens" }, { - "command": "gitlens.fileHistoryExplorer.refresh", + "command": "gitlens.views.fileHistory.refresh", "title": "Refresh", "category": "GitLens", "icon": { @@ -2148,12 +2148,12 @@ } }, { - "command": "gitlens.fileHistoryExplorer.refreshNode", + "command": "gitlens.views.fileHistory.refreshNode", "title": "Refresh", "category": "GitLens" }, { - "command": "gitlens.fileHistoryExplorer.setEditorFollowingOn", + "command": "gitlens.views.fileHistory.setEditorFollowingOn", "title": "Resume File Tracking", "category": "GitLens", "icon": { @@ -2162,7 +2162,7 @@ } }, { - "command": "gitlens.fileHistoryExplorer.setEditorFollowingOff", + "command": "gitlens.views.fileHistory.setEditorFollowingOff", "title": "Pause File Tracking", "category": "GitLens", "icon": { @@ -2171,17 +2171,17 @@ } }, { - "command": "gitlens.fileHistoryExplorer.setRenameFollowingOn", + "command": "gitlens.views.fileHistory.setRenameFollowingOn", "title": "Follow Renames", "category": "GitLens" }, { - "command": "gitlens.fileHistoryExplorer.setRenameFollowingOff", + "command": "gitlens.views.fileHistory.setRenameFollowingOff", "title": "Don't Follow Renames", "category": "GitLens" }, { - "command": "gitlens.lineHistoryExplorer.refresh", + "command": "gitlens.views.lineHistory.refresh", "title": "Refresh", "category": "GitLens", "icon": { @@ -2190,12 +2190,12 @@ } }, { - "command": "gitlens.lineHistoryExplorer.refreshNode", + "command": "gitlens.views.lineHistory.refreshNode", "title": "Refresh", "category": "GitLens" }, { - "command": "gitlens.lineHistoryExplorer.setEditorFollowingOn", + "command": "gitlens.views.lineHistory.setEditorFollowingOn", "title": "Resume Line Tracking", "category": "GitLens", "icon": { @@ -2204,7 +2204,7 @@ } }, { - "command": "gitlens.lineHistoryExplorer.setEditorFollowingOff", + "command": "gitlens.views.lineHistory.setEditorFollowingOff", "title": "Pause Line Tracking", "category": "GitLens", "icon": { @@ -2213,17 +2213,17 @@ } }, { - "command": "gitlens.lineHistoryExplorer.setRenameFollowingOn", + "command": "gitlens.views.lineHistory.setRenameFollowingOn", "title": "Follow Renames", "category": "GitLens" }, { - "command": "gitlens.lineHistoryExplorer.setRenameFollowingOff", + "command": "gitlens.views.lineHistory.setRenameFollowingOff", "title": "Don't Follow Renames", "category": "GitLens" }, { - "command": "gitlens.resultsExplorer.close", + "command": "gitlens.views.results.close", "title": "Close", "category": "GitLens", "icon": { @@ -2232,7 +2232,7 @@ } }, { - "command": "gitlens.resultsExplorer.dismissNode", + "command": "gitlens.views.results.dismissNode", "title": "Dismiss", "category": "GitLens", "icon": { @@ -2241,7 +2241,7 @@ } }, { - "command": "gitlens.resultsExplorer.refresh", + "command": "gitlens.views.results.refresh", "title": "Refresh", "category": "GitLens", "icon": { @@ -2250,27 +2250,27 @@ } }, { - "command": "gitlens.resultsExplorer.refreshNode", + "command": "gitlens.views.results.refreshNode", "title": "Refresh", "category": "GitLens" }, { - "command": "gitlens.resultsExplorer.setFilesLayoutToAuto", + "command": "gitlens.views.results.setFilesLayoutToAuto", "title": "Automatic Layout", "category": "GitLens" }, { - "command": "gitlens.resultsExplorer.setFilesLayoutToList", + "command": "gitlens.views.results.setFilesLayoutToList", "title": "List Layout", "category": "GitLens" }, { - "command": "gitlens.resultsExplorer.setFilesLayoutToTree", + "command": "gitlens.views.results.setFilesLayoutToTree", "title": "Tree Layout", "category": "GitLens" }, { - "command": "gitlens.resultsExplorer.setKeepResultsToOn", + "command": "gitlens.views.results.setKeepResultsToOn", "title": "Keep Results", "category": "GitLens", "icon": { @@ -2279,7 +2279,7 @@ } }, { - "command": "gitlens.resultsExplorer.setKeepResultsToOff", + "command": "gitlens.views.results.setKeepResultsToOff", "title": "Keep Results", "category": "GitLens", "icon": { @@ -2288,7 +2288,7 @@ } }, { - "command": "gitlens.resultsExplorer.swapComparision", + "command": "gitlens.views.results.swapComparision", "title": "Swap Comparision", "category": "GitLens", "icon": { @@ -2300,21 +2300,20 @@ "menus": { "commandPalette": [ { - "command": "gitlens.showRepositoriesExplorer", - "when": "gitlens:enabled && gitlens:repositoriesExplorer" + "command": "gitlens.showRepositoriesView", + "when": "gitlens:enabled && gitlens:views:repositories" }, { - "command": "gitlens.showFileHistoryExplorer", - "when": "gitlens:enabled && gitlens:fileHistoryExplorer" + "command": "gitlens.showFileHistoryView", + "when": "gitlens:enabled && gitlens:views:fileHistory" }, { - "command": "gitlens.showLineHistoryExplorer", - "title": "Show Line History Explorer", - "when": "gitlens:enabled && gitlens:lineHistoryExplorer" + "command": "gitlens.showLineHistoryView", + "when": "gitlens:enabled && gitlens:views:lineHistory" }, { - "command": "gitlens.showResultsExplorer", - "when": "gitlens:enabled && gitlens:resultsExplorer" + "command": "gitlens.showResultsView", + "when": "gitlens:enabled && gitlens:views:results" }, { "command": "gitlens.diffDirectory", @@ -2521,291 +2520,291 @@ "when": "gitlens:enabled" }, { - "command": "gitlens.explorers.exploreRepoRevision", + "command": "gitlens.views.exploreRepoRevision", "when": "false" }, { - "command": "gitlens.repositoriesExplorer.fetchAll", + "command": "gitlens.views.repositories.fetchAll", "when": "false" }, { - "command": "gitlens.repositoriesExplorer.pullAll", + "command": "gitlens.views.repositories.pullAll", "when": "false" }, { - "command": "gitlens.explorers.fetch", + "command": "gitlens.views.fetch", "when": "false" }, { - "command": "gitlens.explorers.pull", + "command": "gitlens.views.pull", "when": "false" }, { - "command": "gitlens.explorers.push", + "command": "gitlens.views.push", "when": "false" }, { - "command": "gitlens.explorers.stageFile", + "command": "gitlens.views.stageFile", "when": "false" }, { - "command": "gitlens.explorers.unstageFile", + "command": "gitlens.views.unstageFile", "when": "false" }, { - "command": "gitlens.explorers.openChanges", + "command": "gitlens.views.openChanges", "when": "false" }, { - "command": "gitlens.explorers.openDirectoryDiff", + "command": "gitlens.views.openDirectoryDiff", "when": "false" }, { - "command": "gitlens.explorers.openDirectoryDiffWithWorking", + "command": "gitlens.views.openDirectoryDiffWithWorking", "when": "false" }, { - "command": "gitlens.explorers.openChangesWithWorking", + "command": "gitlens.views.openChangesWithWorking", "when": "false" }, { - "command": "gitlens.explorers.openFile", + "command": "gitlens.views.openFile", "when": "false" }, { - "command": "gitlens.explorers.openFileRevision", + "command": "gitlens.views.openFileRevision", "when": "false" }, { - "command": "gitlens.explorers.openFileRevisionInRemote", + "command": "gitlens.views.openFileRevisionInRemote", "when": "false" }, { - "command": "gitlens.explorers.openChangedFiles", + "command": "gitlens.views.openChangedFiles", "when": "false" }, { - "command": "gitlens.explorers.openChangedFileChanges", + "command": "gitlens.views.openChangedFileChanges", "when": "false" }, { - "command": "gitlens.explorers.openChangedFileChangesWithWorking", + "command": "gitlens.views.openChangedFileChangesWithWorking", "when": "false" }, { - "command": "gitlens.explorers.openChangedFileRevisions", + "command": "gitlens.views.openChangedFileRevisions", "when": "false" }, { - "command": "gitlens.explorers.applyChanges", + "command": "gitlens.views.applyChanges", "when": "false" }, { - "command": "gitlens.explorers.closeRepository", + "command": "gitlens.views.closeRepository", "when": "false" }, { - "command": "gitlens.explorers.compareAncestryWithWorking", + "command": "gitlens.views.compareAncestryWithWorking", "when": "false" }, { - "command": "gitlens.explorers.compareWithHead", + "command": "gitlens.views.compareWithHead", "when": "false" }, { - "command": "gitlens.explorers.compareWithRemote", + "command": "gitlens.views.compareWithRemote", "when": "false" }, { - "command": "gitlens.explorers.compareWithSelected", + "command": "gitlens.views.compareWithSelected", "when": "false" }, { - "command": "gitlens.explorers.compareWithWorking", + "command": "gitlens.views.compareWithWorking", "when": "false" }, { - "command": "gitlens.explorers.selectForCompare", + "command": "gitlens.views.selectForCompare", "when": "false" }, { - "command": "gitlens.explorers.terminalCheckoutBranch", + "command": "gitlens.views.terminalCheckoutBranch", "when": "false" }, { - "command": "gitlens.explorers.terminalCreateBranch", + "command": "gitlens.views.terminalCreateBranch", "when": "false" }, { - "command": "gitlens.explorers.terminalDeleteBranch", + "command": "gitlens.views.terminalDeleteBranch", "when": "false" }, { - "command": "gitlens.explorers.terminalMergeBranch", + "command": "gitlens.views.terminalMergeBranch", "when": "false" }, { - "command": "gitlens.explorers.terminalRebaseBranch", + "command": "gitlens.views.terminalRebaseBranch", "when": "false" }, { - "command": "gitlens.explorers.terminalRebaseBranchToRemote", + "command": "gitlens.views.terminalRebaseBranchToRemote", "when": "false" }, { - "command": "gitlens.explorers.terminalSquashBranchIntoCommit", + "command": "gitlens.views.terminalSquashBranchIntoCommit", "when": "false" }, { - "command": "gitlens.explorers.terminalCheckoutCommit", + "command": "gitlens.views.terminalCheckoutCommit", "when": "false" }, { - "command": "gitlens.explorers.terminalCherryPickCommit", + "command": "gitlens.views.terminalCherryPickCommit", "when": "false" }, { - "command": "gitlens.explorers.terminalPushCommit", + "command": "gitlens.views.terminalPushCommit", "when": "false" }, { - "command": "gitlens.explorers.terminalRebaseCommit", + "command": "gitlens.views.terminalRebaseCommit", "when": "false" }, { - "command": "gitlens.explorers.terminalResetCommit", + "command": "gitlens.views.terminalResetCommit", "when": "false" }, { - "command": "gitlens.explorers.terminalRevertCommit", + "command": "gitlens.views.terminalRevertCommit", "when": "false" }, { - "command": "gitlens.explorers.terminalRemoveRemote", + "command": "gitlens.views.terminalRemoveRemote", "when": "false" }, { - "command": "gitlens.explorers.terminalCreateTag", + "command": "gitlens.views.terminalCreateTag", "when": "false" }, { - "command": "gitlens.explorers.terminalDeleteTag", + "command": "gitlens.views.terminalDeleteTag", "when": "false" }, { - "command": "gitlens.repositoriesExplorer.refresh", + "command": "gitlens.views.repositories.refresh", "when": "false" }, { - "command": "gitlens.repositoriesExplorer.refreshNode", + "command": "gitlens.views.repositories.refreshNode", "when": "false" }, { - "command": "gitlens.repositoriesExplorer.setFilesLayoutToAuto", + "command": "gitlens.views.repositories.setFilesLayoutToAuto", "when": "false" }, { - "command": "gitlens.repositoriesExplorer.setFilesLayoutToList", + "command": "gitlens.views.repositories.setFilesLayoutToList", "when": "false" }, { - "command": "gitlens.repositoriesExplorer.setFilesLayoutToTree", + "command": "gitlens.views.repositories.setFilesLayoutToTree", "when": "false" }, { - "command": "gitlens.repositoriesExplorer.setAutoRefreshToOn", + "command": "gitlens.views.repositories.setAutoRefreshToOn", "when": "false" }, { - "command": "gitlens.repositoriesExplorer.setAutoRefreshToOff", + "command": "gitlens.views.repositories.setAutoRefreshToOff", "when": "false" }, { - "command": "gitlens.fileHistoryExplorer.refresh", + "command": "gitlens.views.fileHistory.refresh", "when": "false" }, { - "command": "gitlens.fileHistoryExplorer.refreshNode", + "command": "gitlens.views.fileHistory.refreshNode", "when": "false" }, { - "command": "gitlens.fileHistoryExplorer.setEditorFollowingOn", + "command": "gitlens.views.fileHistory.setEditorFollowingOn", "when": "false" }, { - "command": "gitlens.fileHistoryExplorer.setEditorFollowingOff", + "command": "gitlens.views.fileHistory.setEditorFollowingOff", "when": "false" }, { - "command": "gitlens.fileHistoryExplorer.setRenameFollowingOn", + "command": "gitlens.views.fileHistory.setRenameFollowingOn", "when": "false" }, { - "command": "gitlens.fileHistoryExplorer.setRenameFollowingOff", + "command": "gitlens.views.fileHistory.setRenameFollowingOff", "when": "false" }, { - "command": "gitlens.lineHistoryExplorer.refresh", + "command": "gitlens.views.lineHistory.refresh", "when": "false" }, { - "command": "gitlens.lineHistoryExplorer.refreshNode", + "command": "gitlens.views.lineHistory.refreshNode", "when": "false" }, { - "command": "gitlens.lineHistoryExplorer.setEditorFollowingOn", + "command": "gitlens.views.lineHistory.setEditorFollowingOn", "when": "false" }, { - "command": "gitlens.lineHistoryExplorer.setEditorFollowingOff", + "command": "gitlens.views.lineHistory.setEditorFollowingOff", "when": "false" }, { - "command": "gitlens.lineHistoryExplorer.setRenameFollowingOn", + "command": "gitlens.views.lineHistory.setRenameFollowingOn", "when": "false" }, { - "command": "gitlens.lineHistoryExplorer.setRenameFollowingOff", + "command": "gitlens.views.lineHistory.setRenameFollowingOff", "when": "false" }, { - "command": "gitlens.resultsExplorer.close", + "command": "gitlens.views.results.close", "when": "false" }, { - "command": "gitlens.resultsExplorer.dismissNode", + "command": "gitlens.views.results.dismissNode", "when": "false" }, { - "command": "gitlens.resultsExplorer.refresh", + "command": "gitlens.views.results.refresh", "when": "false" }, { - "command": "gitlens.resultsExplorer.refreshNode", + "command": "gitlens.views.results.refreshNode", "when": "false" }, { - "command": "gitlens.resultsExplorer.setFilesLayoutToAuto", + "command": "gitlens.views.results.setFilesLayoutToAuto", "when": "false" }, { - "command": "gitlens.resultsExplorer.setFilesLayoutToList", + "command": "gitlens.views.results.setFilesLayoutToList", "when": "false" }, { - "command": "gitlens.resultsExplorer.setFilesLayoutToTree", + "command": "gitlens.views.results.setFilesLayoutToTree", "when": "false" }, { - "command": "gitlens.resultsExplorer.setKeepResultsToOn", + "command": "gitlens.views.results.setKeepResultsToOn", "when": "false" }, { - "command": "gitlens.resultsExplorer.setKeepResultsToOff", + "command": "gitlens.views.results.setKeepResultsToOff", "when": "false" }, { - "command": "gitlens.resultsExplorer.swapComparision", + "command": "gitlens.views.results.swapComparision", "when": "false" } ], @@ -3042,137 +3041,137 @@ "view/title": [ { "command": "gitlens.showCommitSearch", - "when": "view =~ /^gitlens.repositoriesExplorer:/", + "when": "view =~ /^gitlens.views.repositories:/", "group": "navigation@1" }, { - "command": "gitlens.repositoriesExplorer.pullAll", - "when": "view =~ /^gitlens.repositoriesExplorer:/", + "command": "gitlens.views.repositories.pullAll", + "when": "view =~ /^gitlens.views.repositories:/", "group": "navigation@7" }, { - "command": "gitlens.repositoriesExplorer.fetchAll", - "when": "view =~ /^gitlens.repositoriesExplorer:/", + "command": "gitlens.views.repositories.fetchAll", + "when": "view =~ /^gitlens.views.repositories:/", "group": "navigation@8" }, { - "command": "gitlens.repositoriesExplorer.refresh", - "when": "view =~ /^gitlens.repositoriesExplorer:/", + "command": "gitlens.views.repositories.refresh", + "when": "view =~ /^gitlens.views.repositories:/", "group": "navigation@9" }, { - "command": "gitlens.repositoriesExplorer.setFilesLayoutToAuto", - "when": "view =~ /^gitlens.repositoriesExplorer:/", + "command": "gitlens.views.repositories.setFilesLayoutToAuto", + "when": "view =~ /^gitlens.views.repositories:/", "group": "1_gitlens" }, { - "command": "gitlens.repositoriesExplorer.setFilesLayoutToList", - "when": "view =~ /^gitlens.repositoriesExplorer:/", + "command": "gitlens.views.repositories.setFilesLayoutToList", + "when": "view =~ /^gitlens.views.repositories:/", "group": "1_gitlens" }, { - "command": "gitlens.repositoriesExplorer.setFilesLayoutToTree", - "when": "view =~ /^gitlens.repositoriesExplorer:/", + "command": "gitlens.views.repositories.setFilesLayoutToTree", + "when": "view =~ /^gitlens.views.repositories:/", "group": "1_gitlens" }, { - "command": "gitlens.repositoriesExplorer.setAutoRefreshToOn", - "when": "view =~ /^gitlens.repositoriesExplorer:/ && config.gitlens.repositoriesExplorer.autoRefresh && !gitlens:repositoriesExplorer:autoRefresh", + "command": "gitlens.views.repositories.setAutoRefreshToOn", + "when": "view =~ /^gitlens.views.repositories:/ && config.gitlens.views.repositories.autoRefresh && !gitlens:views:repositories:autoRefresh", "group": "2_gitlens" }, { - "command": "gitlens.repositoriesExplorer.setAutoRefreshToOff", - "when": "view =~ /^gitlens.repositoriesExplorer:/ && config.gitlens.repositoriesExplorer.autoRefresh && gitlens:repositoriesExplorer:autoRefresh", + "command": "gitlens.views.repositories.setAutoRefreshToOff", + "when": "view =~ /^gitlens.views.repositories:/ && config.gitlens.views.repositories.autoRefresh && gitlens:views:repositories:autoRefresh", "group": "2_gitlens" }, { - "command": "gitlens.fileHistoryExplorer.setEditorFollowingOn", - "when": "view =~ /^gitlens.fileHistoryExplorer:/ && !gitlens:fileHistoryExplorer:editorFollowing", + "command": "gitlens.views.fileHistory.setEditorFollowingOn", + "when": "view =~ /^gitlens.views.fileHistory:/ && !gitlens:views:fileHistory:editorFollowing", "group": "navigation@1" }, { - "command": "gitlens.fileHistoryExplorer.setEditorFollowingOff", - "when": "view =~ /^gitlens.fileHistoryExplorer:/ && gitlens:fileHistoryExplorer:editorFollowing", + "command": "gitlens.views.fileHistory.setEditorFollowingOff", + "when": "view =~ /^gitlens.views.fileHistory:/ && gitlens:views:fileHistory:editorFollowing", "group": "navigation@1" }, { - "command": "gitlens.fileHistoryExplorer.refresh", - "when": "view =~ /^gitlens.fileHistoryExplorer:/", + "command": "gitlens.views.fileHistory.refresh", + "when": "view =~ /^gitlens.views.fileHistory:/", "group": "navigation@2" }, { - "command": "gitlens.fileHistoryExplorer.setRenameFollowingOn", - "when": "view =~ /^gitlens.fileHistoryExplorer:/ && !config.gitlens.advanced.fileHistoryFollowsRenames", + "command": "gitlens.views.fileHistory.setRenameFollowingOn", + "when": "view =~ /^gitlens.views.fileHistory:/ && !config.gitlens.advanced.fileHistoryFollowsRenames", "group": "1_gitlens" }, { - "command": "gitlens.fileHistoryExplorer.setRenameFollowingOff", - "when": "view =~ /^gitlens.fileHistoryExplorer:/ && config.gitlens.advanced.fileHistoryFollowsRenames", + "command": "gitlens.views.fileHistory.setRenameFollowingOff", + "when": "view =~ /^gitlens.views.fileHistory:/ && config.gitlens.advanced.fileHistoryFollowsRenames", "group": "1_gitlens" }, { - "command": "gitlens.lineHistoryExplorer.setEditorFollowingOn", - "when": "view =~ /^gitlens.lineHistoryExplorer:/ && !gitlens:lineHistoryExplorer:editorFollowing", + "command": "gitlens.views.lineHistory.setEditorFollowingOn", + "when": "view =~ /^gitlens.views.lineHistory:/ && !gitlens:views:lineHistory:editorFollowing", "group": "navigation@1" }, { - "command": "gitlens.lineHistoryExplorer.setEditorFollowingOff", - "when": "view =~ /^gitlens.lineHistoryExplorer:/ && gitlens:lineHistoryExplorer:editorFollowing", + "command": "gitlens.views.lineHistory.setEditorFollowingOff", + "when": "view =~ /^gitlens.views.lineHistory:/ && gitlens:views:lineHistory:editorFollowing", "group": "navigation@1" }, { - "command": "gitlens.lineHistoryExplorer.refresh", - "when": "view =~ /^gitlens.lineHistoryExplorer:/", + "command": "gitlens.views.lineHistory.refresh", + "when": "view =~ /^gitlens.views.lineHistory:/", "group": "navigation@2" }, { - "command": "gitlens.lineHistoryExplorer.setRenameFollowingOn", - "when": "view =~ /^gitlens.lineHistoryExplorer:/ && !config.gitlens.advanced.fileHistoryFollowsRenames", + "command": "gitlens.views.lineHistory.setRenameFollowingOn", + "when": "view =~ /^gitlens.views.lineHistory:/ && !config.gitlens.advanced.fileHistoryFollowsRenames", "group": "1_gitlens" }, { - "command": "gitlens.lineHistoryExplorer.setRenameFollowingOff", - "when": "view =~ /^gitlens.lineHistoryExplorer:/ && config.gitlens.advanced.fileHistoryFollowsRenames", + "command": "gitlens.views.lineHistory.setRenameFollowingOff", + "when": "view =~ /^gitlens.views.lineHistory:/ && config.gitlens.advanced.fileHistoryFollowsRenames", "group": "1_gitlens" }, { "command": "gitlens.showCommitSearch", - "when": "view =~ /^gitlens.resultsExplorer:/", + "when": "view =~ /^gitlens.views.results:/", "group": "navigation@1" }, { - "command": "gitlens.resultsExplorer.setKeepResultsToOn", - "when": "view =~ /^gitlens.resultsExplorer:/ && !gitlens:resultsExplorer:keepResults", + "command": "gitlens.views.results.setKeepResultsToOn", + "when": "view =~ /^gitlens.views.results:/ && !gitlens:views:results:keepResults", "group": "navigation@2" }, { - "command": "gitlens.resultsExplorer.setKeepResultsToOff", - "when": "view =~ /^gitlens.resultsExplorer:/ && gitlens:resultsExplorer:keepResults", + "command": "gitlens.views.results.setKeepResultsToOff", + "when": "view =~ /^gitlens.views.results:/ && gitlens:views:results:keepResults", "group": "navigation@2" }, { - "command": "gitlens.resultsExplorer.refresh", - "when": "view =~ /^gitlens.resultsExplorer:/", + "command": "gitlens.views.results.refresh", + "when": "view =~ /^gitlens.views.results:/", "group": "navigation@3" }, { - "command": "gitlens.resultsExplorer.close", - "when": "view =~ /^gitlens.resultsExplorer:/", + "command": "gitlens.views.results.close", + "when": "view =~ /^gitlens.views.results:/", "group": "navigation@9" }, { - "command": "gitlens.resultsExplorer.setFilesLayoutToAuto", - "when": "view =~ /^gitlens.resultsExplorer:/", + "command": "gitlens.views.results.setFilesLayoutToAuto", + "when": "view =~ /^gitlens.views.results:/", "group": "1_gitlens" }, { - "command": "gitlens.resultsExplorer.setFilesLayoutToList", - "when": "view =~ /^gitlens.resultsExplorer:/", + "command": "gitlens.views.results.setFilesLayoutToList", + "when": "view =~ /^gitlens.views.results:/", "group": "1_gitlens" }, { - "command": "gitlens.resultsExplorer.setFilesLayoutToTree", - "when": "view =~ /^gitlens.resultsExplorer:/", + "command": "gitlens.views.results.setFilesLayoutToTree", + "when": "view =~ /^gitlens.views.results:/", "group": "1_gitlens" } ], @@ -3188,77 +3187,77 @@ "group": "1_gitlens@1" }, { - "command": "gitlens.explorers.compareWithRemote", + "command": "gitlens.views.compareWithRemote", "when": "viewItem =~ /gitlens:(branch\\b.*?:tracking)/", "group": "7_gitlens@1" }, { - "command": "gitlens.explorers.compareWithHead", + "command": "gitlens.views.compareWithHead", "when": "viewItem =~ /gitlens:(branch(?!:current)|commit|stash|tag)\\b/", "group": "7_gitlens@2" }, { - "command": "gitlens.explorers.compareWithWorking", + "command": "gitlens.views.compareWithWorking", "when": "viewItem =~ /gitlens:(branch(?!:current)|commit|stash|tag)\\b/", "group": "7_gitlens@3" }, { - "command": "gitlens.explorers.compareAncestryWithWorking", + "command": "gitlens.views.compareAncestryWithWorking", "when": "viewItem =~ /gitlens:branch(?!:current)\\b/", "group": "7_gitlens@4" }, { - "command": "gitlens.explorers.compareWithSelected", - "when": "viewItem =~ /gitlens:(branch|commit|stash|tag|file:)\\b/ && gitlens:explorers:canCompare", + "command": "gitlens.views.compareWithSelected", + "when": "viewItem =~ /gitlens:(branch|commit|stash|tag|file:)\\b/ && gitlens:views:canCompare", "group": "7_gitlens_@1" }, { - "command": "gitlens.explorers.selectForCompare", + "command": "gitlens.views.selectForCompare", "when": "viewItem =~ /gitlens:(branch|commit|stash|tag|file:)\\b/", "group": "7_gitlens_@2" }, { - "command": "gitlens.explorers.openDirectoryDiffWithWorking", + "command": "gitlens.views.openDirectoryDiffWithWorking", "when": "viewItem =~ /gitlens:(branch|tag)\\b/", "group": "7_gitlens_more@2" }, { - "command": "gitlens.explorers.terminalCheckoutBranch", + "command": "gitlens.views.terminalCheckoutBranch", "when": "viewItem =~ /gitlens:(branch\\b(?!:current))/", "group": "8_gitlens@1" }, { - "command": "gitlens.explorers.terminalRebaseBranchToRemote", + "command": "gitlens.views.terminalRebaseBranchToRemote", "when": "viewItem =~ /gitlens:(branch:current:tracking|status:upstream)\\b/", "group": "8_gitlens@1" }, { - "command": "gitlens.explorers.terminalMergeBranch", + "command": "gitlens.views.terminalMergeBranch", "when": "viewItem =~ /gitlens:(branch\\b(?!:current))/", "group": "8_gitlens@2" }, { - "command": "gitlens.explorers.terminalRebaseBranch", + "command": "gitlens.views.terminalRebaseBranch", "when": "viewItem =~ /gitlens:(branch\\b(?!:current))/", "group": "8_gitlens@3" }, { - "command": "gitlens.explorers.terminalSquashBranchIntoCommit", + "command": "gitlens.views.terminalSquashBranchIntoCommit", "when": "viewItem =~ /gitlens:(branch\\b(?!:current))/", "group": "8_gitlens@4" }, { - "command": "gitlens.explorers.terminalCreateBranch", + "command": "gitlens.views.terminalCreateBranch", "when": "viewItem =~ /gitlens:(branch|commit|status:upstream|tag)\\b/", "group": "8_gitlens@5" }, { - "command": "gitlens.explorers.terminalDeleteBranch", + "command": "gitlens.views.terminalDeleteBranch", "when": "viewItem =~ /gitlens:(branch\\b(?!:current))/", "group": "8_gitlens@6" }, { - "command": "gitlens.explorers.terminalCreateTag", + "command": "gitlens.views.terminalCreateTag", "when": "viewItem =~ /gitlens:(branch|commit|status:upstream)\\b/", "group": "8_gitlens@7" }, @@ -3268,22 +3267,22 @@ "group": "1_gitlens@1" }, { - "command": "gitlens.explorers.openChangedFileChanges", + "command": "gitlens.views.openChangedFileChanges", "when": "viewItem =~ /gitlens:(commit|stash)\\b/", "group": "2_gitlens@1" }, { - "command": "gitlens.explorers.openChangedFileChangesWithWorking", + "command": "gitlens.views.openChangedFileChangesWithWorking", "when": "viewItem =~ /gitlens:(commit|stash)\\b/", "group": "2_gitlens@2" }, { - "command": "gitlens.explorers.openChangedFiles", + "command": "gitlens.views.openChangedFiles", "when": "viewItem =~ /gitlens:(commit|stash)\\b/", "group": "3_gitlens@1" }, { - "command": "gitlens.explorers.openChangedFileRevisions", + "command": "gitlens.views.openChangedFileRevisions", "when": "viewItem =~ /gitlens:(commit|stash)\\b/", "group": "3_gitlens@2" }, @@ -3308,57 +3307,57 @@ "group": "5_gitlens_1@2" }, { - "command": "gitlens.explorers.terminalCherryPickCommit", + "command": "gitlens.views.terminalCherryPickCommit", "when": "viewItem == gitlens:commit", "group": "8_gitlens@1" }, { - "command": "gitlens.explorers.terminalPushCommit", + "command": "gitlens.views.terminalPushCommit", "when": "viewItem == gitlens:commit:current", "group": "8_gitlens@2" }, { - "command": "gitlens.explorers.terminalRevertCommit", + "command": "gitlens.views.terminalRevertCommit", "when": "viewItem == gitlens:commit:current", "group": "8_gitlens@3" }, { - "command": "gitlens.explorers.terminalCheckoutCommit", + "command": "gitlens.views.terminalCheckoutCommit", "when": "viewItem =~ /gitlens:commit\\b/", "group": "8_gitlens@4" }, { - "command": "gitlens.explorers.terminalRebaseCommit", + "command": "gitlens.views.terminalRebaseCommit", "when": "viewItem =~ /gitlens:commit\\b/", "group": "8_gitlens@5" }, { - "command": "gitlens.explorers.terminalResetCommit", + "command": "gitlens.views.terminalResetCommit", "when": "viewItem =~ /gitlens:commit\\b/", "group": "8_gitlens@6" }, { - "command": "gitlens.explorers.openFile", + "command": "gitlens.views.openFile", "when": "viewItem =~ /gitlens:(file|history-file|status:file)\\b/", "group": "inline" }, { - "command": "gitlens.explorers.stageFile", + "command": "gitlens.views.stageFile", "when": "viewItem =~ /gitlens:file\\b.*:unstaged\\b/", "group": "inline" }, { - "command": "gitlens.explorers.unstageFile", + "command": "gitlens.views.unstageFile", "when": "viewItem =~ /gitlens:file\\b.*:staged\\b/", "group": "inline" }, { - "command": "gitlens.explorers.stageFile", + "command": "gitlens.views.stageFile", "when": "viewItem =~ /gitlens:file\\b.*:unstaged\\b/", "group": "1_gitlens@1" }, { - "command": "gitlens.explorers.unstageFile", + "command": "gitlens.views.unstageFile", "when": "viewItem =~ /gitlens:file\\b.*:staged\\b/", "group": "1_gitlens@1" }, @@ -3368,7 +3367,7 @@ "group": "1_gitlens@2" }, { - "command": "gitlens.explorers.openChanges", + "command": "gitlens.views.openChanges", "when": "viewItem =~ /gitlens:file\\b/", "group": "2_gitlens@1" }, @@ -3378,17 +3377,17 @@ "group": "2_gitlens@2" }, { - "command": "gitlens.explorers.openChangesWithWorking", + "command": "gitlens.views.openChangesWithWorking", "when": "viewItem =~ /gitlens:file\\b/", "group": "2_gitlens@3" }, { - "command": "gitlens.explorers.openFile", + "command": "gitlens.views.openFile", "when": "viewItem =~ /gitlens:(file|history-file|status:file)\\b/", "group": "3_gitlens@1" }, { - "command": "gitlens.explorers.openFileRevision", + "command": "gitlens.views.openFileRevision", "when": "viewItem =~ /gitlens:file\\b/", "group": "3_gitlens@2" }, @@ -3403,7 +3402,7 @@ "group": "5_gitlens@3" }, { - "command": "gitlens.explorers.openFileRevisionInRemote", + "command": "gitlens.views.openFileRevisionInRemote", "when": "viewItem == gitlens:file:commit && gitlens:hasRemotes", "group": "4_gitlens@2" }, @@ -3418,12 +3417,12 @@ "group": "5_gitlens@3" }, { - "command": "gitlens.explorers.applyChanges", + "command": "gitlens.views.applyChanges", "when": "viewItem =~ /gitlens:file:(commit|results)\\b/", "group": "5_gitlens_1@1" }, { - "command": "gitlens.explorers.applyChanges", + "command": "gitlens.views.applyChanges", "when": "viewItem == gitlens:file:stash", "group": "1_gitlens@1" }, @@ -3458,42 +3457,42 @@ "group": "1_gitlens@2" }, { - "command": "gitlens.explorers.terminalRemoveRemote", + "command": "gitlens.views.terminalRemoveRemote", "when": "viewItem == gitlens:remote", "group": "8_gitlens@1" }, { - "command": "gitlens.explorers.exploreRepoRevision", + "command": "gitlens.views.exploreRepoRevision", "when": "viewItem =~ /gitlens:(branch|commit|file:(commit|results)|stash|tag)\\b/", "group": "7_gitlens_more@1" }, { - "command": "gitlens.explorers.push", + "command": "gitlens.views.push", "when": "viewItem == gitlens:repository && gitlens:hasRemotes", "group": "inline@97" }, { - "command": "gitlens.explorers.pull", + "command": "gitlens.views.pull", "when": "viewItem == gitlens:repository && gitlens:hasRemotes", "group": "inline@98" }, { - "command": "gitlens.explorers.fetch", + "command": "gitlens.views.fetch", "when": "viewItem == gitlens:repository && gitlens:hasRemotes", "group": "inline@99" }, { - "command": "gitlens.explorers.fetch", + "command": "gitlens.views.fetch", "when": "viewItem == gitlens:repository && gitlens:hasRemotes", "group": "1_gitlens@1" }, { - "command": "gitlens.explorers.pull", + "command": "gitlens.views.pull", "when": "viewItem == gitlens:repository && gitlens:hasRemotes", "group": "1_gitlens@2" }, { - "command": "gitlens.explorers.push", + "command": "gitlens.views.push", "when": "viewItem == gitlens:repository && gitlens:hasRemotes", "group": "1_gitlens@3" }, @@ -3518,32 +3517,32 @@ "group": "4_gitlens@1" }, { - "command": "gitlens.explorers.closeRepository", + "command": "gitlens.views.closeRepository", "when": "viewItem == gitlens:repository", "group": "8_gitlens@1" }, { - "command": "gitlens.resultsExplorer.swapComparision", + "command": "gitlens.views.results.swapComparision", "when": "viewItem == gitlens:results:comparison", "group": "inline@1" }, { - "command": "gitlens.resultsExplorer.dismissNode", + "command": "gitlens.views.results.dismissNode", "when": "viewItem =~ /gitlens:results\\b(?!:(commits|files))/", "group": "inline@2" }, { - "command": "gitlens.resultsExplorer.dismissNode", + "command": "gitlens.views.results.dismissNode", "when": "viewItem =~ /gitlens:results\\b(?!:(commits|files))/", "group": "1_gitlens@1" }, { - "command": "gitlens.resultsExplorer.swapComparision", + "command": "gitlens.views.results.swapComparision", "when": "viewItem == gitlens:results:comparison", "group": "2_gitlens@1" }, { - "command": "gitlens.explorers.openDirectoryDiff", + "command": "gitlens.views.openDirectoryDiff", "when": "viewItem == gitlens:results:comparison", "group": "7_gitlens@1" }, @@ -3578,28 +3577,28 @@ "group": "1_gitlens@2" }, { - "command": "gitlens.explorers.terminalDeleteTag", + "command": "gitlens.views.terminalDeleteTag", "when": "viewItem == gitlens:tag", "group": "8_gitlens" }, { - "command": "gitlens.repositoriesExplorer.refreshNode", - "when": "view =~ /^gitlens.repositoriesExplorer:/ && viewItem =~ /gitlens:(?!file\\b)/", + "command": "gitlens.views.repositories.refreshNode", + "when": "view =~ /^gitlens.views.repositories:/ && viewItem =~ /gitlens:(?!file\\b)/", "group": "9_gitlens@1" }, { - "command": "gitlens.resultsExplorer.refreshNode", - "when": "view =~ /^gitlens.resultsExplorer:/ && viewItem =~ /gitlens:(?!file\\b)/", + "command": "gitlens.views.results.refreshNode", + "when": "view =~ /^gitlens.views.results:/ && viewItem =~ /gitlens:(?!file\\b)/", "group": "9_gitlens@1" }, { - "command": "gitlens.fileHistoryExplorer.refreshNode", - "when": "view =~ /^gitlens.fileHistoryExplorer:/ && viewItem =~ /gitlens:(?!file\\b)/", + "command": "gitlens.views.fileHistory.refreshNode", + "when": "view =~ /^gitlens.views.fileHistory:/ && viewItem =~ /gitlens:(?!file\\b)/", "group": "9_gitlens@1" }, { - "command": "gitlens.lineHistoryExplorer.refreshNode", - "when": "view =~ /^gitlens.lineHistoryExplorer:/ && viewItem =~ /gitlens:(?!file\\b)/", + "command": "gitlens.views.lineHistory.refreshNode", + "when": "view =~ /^gitlens.views.lineHistory:/ && viewItem =~ /gitlens:(?!file\\b)/", "group": "9_gitlens@1" } ] @@ -3803,68 +3802,68 @@ "views": { "gitlens": [ { - "id": "gitlens.repositoriesExplorer:gitlens", + "id": "gitlens.views.repositories:gitlens", "name": "Repositories", - "when": "gitlens:enabled && gitlens:repositoriesExplorer == gitlens" + "when": "gitlens:enabled && gitlens:views:repositories == gitlens" }, { - "id": "gitlens.fileHistoryExplorer:gitlens", + "id": "gitlens.views.fileHistory:gitlens", "name": "File History", - "when": "gitlens:enabled && gitlens:fileHistoryExplorer == gitlens" + "when": "gitlens:enabled && gitlens:views:fileHistory == gitlens" }, { - "id": "gitlens.lineHistoryExplorer:gitlens", + "id": "gitlens.views.lineHistory:gitlens", "name": "Line History", - "when": "gitlens:enabled && gitlens:lineHistoryExplorer == gitlens" + "when": "gitlens:enabled && gitlens:views:lineHistory == gitlens" }, { - "id": "gitlens.resultsExplorer:gitlens", + "id": "gitlens.views.results:gitlens", "name": "Results", - "when": "gitlens:enabled && gitlens:resultsExplorer == gitlens" + "when": "gitlens:enabled && gitlens:views:results == gitlens" } ], "explorer": [ { - "id": "gitlens.repositoriesExplorer:explorer", + "id": "gitlens.views.repositories:explorer", "name": "GitLens Repositories", - "when": "gitlens:enabled && gitlens:repositoriesExplorer == explorer" + "when": "gitlens:enabled && gitlens:views:repositories == explorer" }, { - "id": "gitlens.fileHistoryExplorer:explorer", + "id": "gitlens.views.fileHistory:explorer", "name": "GitLens File History", - "when": "gitlens:enabled && gitlens:fileHistoryExplorer == explorer" + "when": "gitlens:enabled && gitlens:views:fileHistory == explorer" }, { - "id": "gitlens.lineHistoryExplorer:explorer", + "id": "gitlens.views.lineHistory:explorer", "name": "GitLens Line History", - "when": "gitlens:enabled && gitlens:lineHistoryExplorer == explorer" + "when": "gitlens:enabled && gitlens:views:lineHistory == explorer" }, { - "id": "gitlens.resultsExplorer:explorer", + "id": "gitlens.views.results:explorer", "name": "GitLens Results", - "when": "gitlens:enabled && gitlens:resultsExplorer == explorer" + "when": "gitlens:enabled && gitlens:views:results == explorer" } ], "scm": [ { - "id": "gitlens.repositoriesExplorer:scm", + "id": "gitlens.views.repositories:scm", "name": "GitLens Repositories", - "when": "gitlens:enabled && gitlens:repositoriesExplorer == scm" + "when": "gitlens:enabled && gitlens:views:repositories == scm" }, { - "id": "gitlens.fileHistoryExplorer:scm", + "id": "gitlens.views.fileHistory:scm", "name": "GitLens File History", - "when": "gitlens:enabled && gitlens:fileHistoryExplorer == scm" + "when": "gitlens:enabled && gitlens:views:fileHistory == scm" }, { - "id": "gitlens.lineHistoryExplorer:scm", + "id": "gitlens.views.lineHistory:scm", "name": "GitLens Line History", - "when": "gitlens:enabled && gitlens:lineHistoryExplorer == scm" + "when": "gitlens:enabled && gitlens:views:lineHistory == scm" }, { - "id": "gitlens.resultsExplorer:scm", + "id": "gitlens.views.results:scm", "name": "GitLens Results", - "when": "gitlens:enabled && gitlens:resultsExplorer == scm" + "when": "gitlens:enabled && gitlens:views:results == scm" } ] } diff --git a/src/commands.ts b/src/commands.ts index 0f2566e..4f8faa2 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -26,7 +26,6 @@ import { OpenRepoInRemoteCommand } from './commands/openRepoInRemote'; import { OpenWorkingFileCommand } from './commands/openWorkingFile'; import { ResetSuppressedWarningsCommand } from './commands/resetSuppressedWarnings'; import { ShowCommitSearchCommand } from './commands/showCommitSearch'; -import { ShowExplorerCommand } from './commands/showExplorer'; import { ShowLastQuickPickCommand } from './commands/showLastQuickPick'; import { ShowQuickBranchHistoryCommand } from './commands/showQuickBranchHistory'; import { ShowQuickCommitDetailsCommand } from './commands/showQuickCommitDetails'; @@ -35,6 +34,7 @@ import { ShowQuickCurrentBranchHistoryCommand } from './commands/showQuickCurren import { ShowQuickFileHistoryCommand } from './commands/showQuickFileHistory'; import { ShowQuickRepoStatusCommand } from './commands/showQuickRepoStatus'; import { ShowQuickStashListCommand } from './commands/showQuickStashList'; +import { ShowViewCommand } from './commands/showView'; import { StashApplyCommand } from './commands/stashApply'; import { StashDeleteCommand } from './commands/stashDelete'; import { StashSaveCommand } from './commands/stashSave'; @@ -75,7 +75,7 @@ export * from './commands/openRepoInRemote'; export * from './commands/openWorkingFile'; export * from './commands/resetSuppressedWarnings'; export * from './commands/showCommitSearch'; -export * from './commands/showExplorer'; +export * from './commands/showView'; export * from './commands/showLastQuickPick'; export * from './commands/showQuickBranchHistory'; export * from './commands/showQuickCommitDetails'; @@ -124,7 +124,7 @@ export function configureCommands(): void { Container.context.subscriptions.push(new OpenWorkingFileCommand()); Container.context.subscriptions.push(new ResetSuppressedWarningsCommand()); Container.context.subscriptions.push(new ShowCommitSearchCommand()); - Container.context.subscriptions.push(new ShowExplorerCommand()); + Container.context.subscriptions.push(new ShowViewCommand()); Container.context.subscriptions.push(new ShowLastQuickPickCommand()); Container.context.subscriptions.push(new ShowQuickBranchHistoryCommand()); Container.context.subscriptions.push(new ShowQuickCommitDetailsCommand()); diff --git a/src/commands/common.ts b/src/commands/common.ts index db84f8e..05a44f3 100644 --- a/src/commands/common.ts +++ b/src/commands/common.ts @@ -19,7 +19,7 @@ import { GitBranch, GitCommit, GitFile, GitRemote, GitUri, Repository } from '.. import { Logger } from '../logger'; import { CommandQuickPickItem, RepositoriesQuickPick } from '../quickpicks'; // import { Telemetry } from '../telemetry'; -import { ExplorerNode, ExplorerRefNode } from '../views/nodes'; +import { ViewNode, ViewRefNode } from '../views/nodes'; export enum Commands { ClearFileAnnotations = 'gitlens.clearFileAnnotations', @@ -42,8 +42,6 @@ export enum Commands { DiffWithWorking = 'gitlens.diffWithWorking', DiffLineWithWorking = 'gitlens.diffLineWithWorking', ExternalDiff = 'gitlens.externalDiff', - ExplorersOpenDirectoryDiff = 'gitlens.explorers.openDirectoryDiff', - ExplorersOpenDirectoryDiffWithWorking = 'gitlens.explorers.openDirectoryDiffWithWorking', OpenChangedFiles = 'gitlens.openChangedFiles', OpenBranchesInRemote = 'gitlens.openBranchesInRemote', OpenBranchInRemote = 'gitlens.openBranchInRemote', @@ -56,9 +54,9 @@ export enum Commands { ResetSuppressedWarnings = 'gitlens.resetSuppressedWarnings', ShowCommitInResults = 'gitlens.showCommitInResults', ShowCommitSearch = 'gitlens.showCommitSearch', - ShowFileHistoryExplorer = 'gitlens.showFileHistoryExplorer', + ShowFileHistoryView = 'gitlens.showFileHistoryView', ShowFileHistoryInResults = 'gitlens.showFileHistoryInResults', - ShowLineHistoryExplorer = 'gitlens.showLineHistoryExplorer', + ShowLineHistoryView = 'gitlens.showLineHistoryView', ShowLastQuickPick = 'gitlens.showLastQuickPick', ShowQuickBranchHistory = 'gitlens.showQuickBranchHistory', ShowQuickCommitDetails = 'gitlens.showQuickCommitDetails', @@ -68,8 +66,8 @@ export enum Commands { ShowQuickRepoStatus = 'gitlens.showQuickRepoStatus', ShowQuickRevisionDetails = 'gitlens.showQuickRevisionDetails', ShowQuickStashList = 'gitlens.showQuickStashList', - ShowRepositoriesExplorer = 'gitlens.showRepositoriesExplorer', - ShowResultsExplorer = 'gitlens.showResultsExplorer', + ShowRepositoriesView = 'gitlens.showRepositoriesView', + ShowResultsView = 'gitlens.showResultsView', ShowSettingsPage = 'gitlens.showSettingsPage', ShowWelcomePage = 'gitlens.showWelcomePage', StashApply = 'gitlens.stashApply', @@ -82,7 +80,9 @@ export enum Commands { ToggleFileRecentChanges = 'gitlens.toggleFileRecentChanges', ToggleLineBlame = 'gitlens.toggleLineBlame', ToggleReviewMode = 'gitlens.toggleReviewMode', - ToggleZenMode = 'gitlens.toggleZenMode' + ToggleZenMode = 'gitlens.toggleZenMode', + ViewsOpenDirectoryDiff = 'gitlens.views.openDirectoryDiff', + ViewsOpenDirectoryDiffWithWorking = 'gitlens.views.openDirectoryDiffWithWorking' } export function getCommandUri(uri?: Uri, editor?: TextEditor): Uri | undefined { @@ -181,40 +181,40 @@ export interface CommandViewContext extends CommandBaseContext { export interface CommandViewItemContext extends CommandBaseContext { type: 'viewItem'; - node: ExplorerNode; + node: ViewNode; } export function isCommandViewContextWithBranch( context: CommandContext -): context is CommandViewItemContext & { node: ExplorerNode & { branch: GitBranch } } { +): context is CommandViewItemContext & { node: ViewNode & { branch: GitBranch } } { if (context.type !== 'viewItem') return false; - return (context.node as ExplorerNode & { branch: GitBranch }).branch instanceof GitBranch; + return (context.node as ViewNode & { branch: GitBranch }).branch instanceof GitBranch; } export function isCommandViewContextWithCommit( context: CommandContext -): context is CommandViewItemContext & { node: ExplorerNode & { commit: T } } { +): context is CommandViewItemContext & { node: ViewNode & { commit: T } } { if (context.type !== 'viewItem') return false; - return (context.node as ExplorerNode & { commit: GitCommit }).commit instanceof GitCommit; + return (context.node as ViewNode & { commit: GitCommit }).commit instanceof GitCommit; } export function isCommandViewContextWithFile( context: CommandContext -): context is CommandViewItemContext & { node: ExplorerNode & { file: GitFile; repoPath: string } } { +): context is CommandViewItemContext & { node: ViewNode & { file: GitFile; repoPath: string } } { if (context.type !== 'viewItem') return false; - const node = context.node as ExplorerNode & { file: GitFile; repoPath: string }; + const node = context.node as ViewNode & { file: GitFile; repoPath: string }; return node.file !== undefined && (node.file.repoPath !== undefined || node.repoPath !== undefined); } export function isCommandViewContextWithFileCommit( context: CommandContext -): context is CommandViewItemContext & { node: ExplorerNode & { commit: GitCommit; file: GitFile; repoPath: string } } { +): context is CommandViewItemContext & { node: ViewNode & { commit: GitCommit; file: GitFile; repoPath: string } } { if (context.type !== 'viewItem') return false; - const node = context.node as ExplorerNode & { commit: GitCommit; file: GitFile; repoPath: string }; + const node = context.node as ViewNode & { commit: GitCommit; file: GitFile; repoPath: string }; return ( node.file !== undefined && node.commit instanceof GitCommit && @@ -225,11 +225,11 @@ export function isCommandViewContextWithFileCommit( export function isCommandViewContextWithFileRefs( context: CommandContext ): context is CommandViewItemContext & { - node: ExplorerNode & { file: GitFile; ref1: string; ref2: string; repoPath: string }; + node: ViewNode & { file: GitFile; ref1: string; ref2: string; repoPath: string }; } { if (context.type !== 'viewItem') return false; - const node = context.node as ExplorerNode & { file: GitFile; ref1: string; ref2: string; repoPath: string }; + const node = context.node as ViewNode & { file: GitFile; ref1: string; ref2: string; repoPath: string }; return ( node.file !== undefined && node.ref1 !== undefined && @@ -240,24 +240,24 @@ export function isCommandViewContextWithFileRefs( export function isCommandViewContextWithRef( context: CommandContext -): context is CommandViewItemContext & { node: ExplorerNode & { ref: string } } { - return context.type === 'viewItem' && context.node instanceof ExplorerRefNode; +): context is CommandViewItemContext & { node: ViewNode & { ref: string } } { + return context.type === 'viewItem' && context.node instanceof ViewRefNode; } export function isCommandViewContextWithRemote( context: CommandContext -): context is CommandViewItemContext & { node: ExplorerNode & { remote: GitRemote } } { +): context is CommandViewItemContext & { node: ViewNode & { remote: GitRemote } } { if (context.type !== 'viewItem') return false; - return (context.node as ExplorerNode & { remote: GitRemote }).remote instanceof GitRemote; + return (context.node as ViewNode & { remote: GitRemote }).remote instanceof GitRemote; } export function isCommandViewContextWithRepo( context: CommandContext -): context is CommandViewItemContext & { node: ExplorerNode & { repo: Repository } } { +): context is CommandViewItemContext & { node: ViewNode & { repo: Repository } } { if (context.type !== 'viewItem') return false; - return (context.node as ExplorerNode & { repo?: Repository }).repo instanceof Repository; + return (context.node as ViewNode & { repo?: Repository }).repo instanceof Repository; } export type CommandContext = @@ -362,8 +362,8 @@ export abstract class Command implements Disposable { } } - if (firstArg instanceof ExplorerNode) { - const [node, ...rest] = args as [ExplorerNode, any]; + if (firstArg instanceof ViewNode) { + const [node, ...rest] = args as [ViewNode, any]; return [{ command: command, type: 'viewItem', node: node, uri: node.uri }, rest]; } diff --git a/src/commands/diffBranchWithBranch.ts b/src/commands/diffBranchWithBranch.ts index 912cba2..fc7a222 100644 --- a/src/commands/diffBranchWithBranch.ts +++ b/src/commands/diffBranchWithBranch.ts @@ -80,7 +80,7 @@ export class DiffBranchWithBranchCommand extends ActiveEditorCommand { if (args.ref1 === undefined) return undefined; } - await Container.resultsExplorer.addComparison(repoPath, args.ref1, args.ref2); + await Container.resultsView.addComparison(repoPath, args.ref1, args.ref2); return undefined; } diff --git a/src/commands/diffDirectory.ts b/src/commands/diffDirectory.ts index d9defb0..93513a5 100644 --- a/src/commands/diffDirectory.ts +++ b/src/commands/diffDirectory.ts @@ -22,23 +22,19 @@ export interface DiffDirectoryCommandArgs { export class DiffDirectoryCommand extends ActiveEditorCommand { constructor() { - super([ - Commands.DiffDirectory, - Commands.ExplorersOpenDirectoryDiff, - Commands.ExplorersOpenDirectoryDiffWithWorking - ]); + super([Commands.DiffDirectory, Commands.ViewsOpenDirectoryDiff, Commands.ViewsOpenDirectoryDiffWithWorking]); } protected async preExecute(context: CommandContext, args: DiffDirectoryCommandArgs = {}): Promise { switch (context.command) { - case Commands.ExplorersOpenDirectoryDiff: + case Commands.ViewsOpenDirectoryDiff: if (context.type === 'viewItem' && context.node instanceof ResultsComparisonNode) { args.ref1 = context.node.ref1.ref; args.ref2 = context.node.ref2.ref; } break; - case Commands.ExplorersOpenDirectoryDiffWithWorking: + case Commands.ViewsOpenDirectoryDiffWithWorking: if (isCommandViewContextWithRef(context)) { args.ref1 = context.node.ref; args.ref2 = undefined; diff --git a/src/commands/showCommitSearch.ts b/src/commands/showCommitSearch.ts index 88465d4..1bcf4a8 100644 --- a/src/commands/showCommitSearch.ts +++ b/src/commands/showCommitSearch.ts @@ -142,7 +142,7 @@ export class ShowCommitSearchCommand extends ActiveEditorCachedCommand { } if (args.showInResults) { - Container.resultsExplorer.addSearchResults( + Container.resultsView.addSearchResults( repoPath, Container.git.getLogForSearch(repoPath, args.search!, args.searchBy!, { maxCount: args.maxCount @@ -187,7 +187,7 @@ export class ShowCommitSearchCommand extends ActiveEditorCachedCommand { [uri, { ...args, maxCount: 0, goBackCommand: goBackCommand }] ) : undefined, - showInResultsExplorerCommand: + showInResultsCommand: log !== undefined ? new ShowCommitsSearchInResultsQuickPickItem(log, searchLabel!) : undefined }); if (pick === undefined) return undefined; diff --git a/src/commands/showExplorer.ts b/src/commands/showExplorer.ts deleted file mode 100644 index a9d359a..0000000 --- a/src/commands/showExplorer.ts +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; -import { Container } from '../container'; -import { Command, CommandContext, Commands } from './common'; - -export class ShowExplorerCommand extends Command { - constructor() { - super([ - Commands.ShowRepositoriesExplorer, - Commands.ShowFileHistoryExplorer, - Commands.ShowLineHistoryExplorer, - Commands.ShowResultsExplorer - ]); - } - - protected async preExecute(context: CommandContext): Promise { - return this.execute(context.command as Commands); - } - - execute(command: Commands) { - switch (command) { - case Commands.ShowRepositoriesExplorer: - return Container.repositoriesExplorer.show(); - case Commands.ShowFileHistoryExplorer: - return Container.fileHistoryExplorer.show(); - case Commands.ShowLineHistoryExplorer: - return Container.lineHistoryExplorer.show(); - case Commands.ShowResultsExplorer: - return Container.resultsExplorer.show(); - } - - return undefined; - } -} diff --git a/src/commands/showQuickCommitDetails.ts b/src/commands/showQuickCommitDetails.ts index fa7e70f..51b958f 100644 --- a/src/commands/showQuickCommitDetails.ts +++ b/src/commands/showQuickCommitDetails.ts @@ -134,7 +134,7 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand { } if (args.showInResults) { - void (await Container.resultsExplorer.addCommit(args.commit as GitLogCommit)); + void (await Container.resultsView.addCommit(args.commit as GitLogCommit)); return undefined; } diff --git a/src/commands/showQuickFileHistory.ts b/src/commands/showQuickFileHistory.ts index b6e701d..179eec3 100644 --- a/src/commands/showQuickFileHistory.ts +++ b/src/commands/showQuickFileHistory.ts @@ -78,7 +78,7 @@ export class ShowQuickFileHistoryCommand extends ActiveEditorCachedCommand { } if (args.showInResults) { - void (await Container.resultsExplorer.addSearchResults(gitUri.repoPath!, args.log, { + void (await Container.resultsView.addSearchResults(gitUri.repoPath!, args.log, { label: placeHolder, resultsType: { singular: 'commit', plural: 'commits' } })); @@ -153,7 +153,7 @@ export class ShowQuickFileHistoryCommand extends ActiveEditorCachedCommand { [uri, { ...args, log: undefined, maxCount: 0 }] ) : undefined, - showInResultsExplorerCommand: + showInResultsCommand: args.log !== undefined ? new ShowCommitsInResultsQuickPickItem(args.log, { label: placeHolder, diff --git a/src/commands/showView.ts b/src/commands/showView.ts new file mode 100644 index 0000000..5dd9a5e --- /dev/null +++ b/src/commands/showView.ts @@ -0,0 +1,33 @@ +'use strict'; +import { Container } from '../container'; +import { Command, CommandContext, Commands } from './common'; + +export class ShowViewCommand extends Command { + constructor() { + super([ + Commands.ShowRepositoriesView, + Commands.ShowFileHistoryView, + Commands.ShowLineHistoryView, + Commands.ShowResultsView + ]); + } + + protected async preExecute(context: CommandContext): Promise { + return this.execute(context.command as Commands); + } + + execute(command: Commands) { + switch (command) { + case Commands.ShowRepositoriesView: + return Container.repositoriesView.show(); + case Commands.ShowFileHistoryView: + return Container.fileHistoryView.show(); + case Commands.ShowLineHistoryView: + return Container.lineHistoryView.show(); + case Commands.ShowResultsView: + return Container.resultsView.show(); + } + + return undefined; + } +} diff --git a/src/configuration.ts b/src/configuration.ts index 513a56c..ab8288a 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -42,11 +42,12 @@ export class Configuration { `gitlens.${this.name('modes').value}`, `gitlens.${this.name('codeLens').value}`, `gitlens.${this.name('currentLine').value}`, - `gitlens.${this.name('fileHistoryExplorer').value}`, `gitlens.${this.name('hovers').value}`, - `gitlens.${this.name('lineHistoryExplorer').value}`, - `gitlens.${this.name('repositoriesExplorer').value}`, - `gitlens.${this.name('statusBar').value}` + `gitlens.${this.name('statusBar').value}`, + `gitlens.${this.name('views')('fileHistory').value}`, + `gitlens.${this.name('views')('lineHistory').value}`, + `gitlens.${this.name('views')('repositories').value}`, + `gitlens.${this.name('views')('results').value}` ]; } diff --git a/src/constants.ts b/src/constants.ts index e3bcb1a..cb838f1 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -31,18 +31,18 @@ export enum CommandContext { AnnotationStatus = 'gitlens:annotationStatus', CanToggleCodeLens = 'gitlens:canToggleCodeLens', Enabled = 'gitlens:enabled', - ExplorersCanCompare = 'gitlens:explorers:canCompare', HasRemotes = 'gitlens:hasRemotes', - FileHistoryExplorer = 'gitlens:fileHistoryExplorer', - FileHistoryExplorerEditorFollowing = 'gitlens:fileHistoryExplorer:editorFollowing', - LineHistoryExplorer = 'gitlens:lineHistoryExplorer', - LineHistoryExplorerEditorFollowing = 'gitlens:lineHistoryExplorer:editorFollowing', Key = 'gitlens:key', KeyMap = 'gitlens:keymap', - RepositoriesExplorer = 'gitlens:repositoriesExplorer', - RepositoriesExplorerAutoRefresh = 'gitlens:repositoriesExplorer:autoRefresh', - ResultsExplorer = 'gitlens:resultsExplorer', - ResultsExplorerKeepResults = 'gitlens:resultsExplorer:keepResults' + ViewsCanCompare = 'gitlens:views:canCompare', + ViewsFileHistory = 'gitlens:views:fileHistory', + ViewsFileHistoryEditorFollowing = 'gitlens:views:fileHistory:editorFollowing', + ViewsLineHistory = 'gitlens:views:lineHistory', + ViewsLineHistoryEditorFollowing = 'gitlens:views:lineHistory:editorFollowing', + ViewsRepositories = 'gitlens:views:repositories', + ViewsRepositoriesAutoRefresh = 'gitlens:views:repositories:autoRefresh', + ViewsResults = 'gitlens:views:results', + ViewsResultsKeepResults = 'gitlens:views:results:keepResults' } export function setCommandContext(key: CommandContext | string, value: any) { @@ -129,6 +129,6 @@ export const ImageMimetypes: { [key: string]: string } = { }; export enum WorkspaceState { - RepositoriesExplorerAutoRefresh = 'gitlens:repositoriesExplorer:autoRefresh', - ResultsExplorerKeepResults = 'gitlens:resultsExplorer:keepResults' + ViewsRepositoriesAutoRefresh = 'gitlens:views:repositories:autoRefresh', + ViewsResultsKeepResults = 'gitlens:views:results:keepResults' } diff --git a/src/container.ts b/src/container.ts index cb62e0a..d34fd95 100644 --- a/src/container.ts +++ b/src/container.ts @@ -11,11 +11,11 @@ import { Keyboard } from './keyboard'; import { StatusBarController } from './statusbar/statusBarController'; import { GitDocumentTracker } from './trackers/gitDocumentTracker'; import { GitLineTracker } from './trackers/gitLineTracker'; -import { ExplorerCommands } from './views/explorerCommands'; -import { FileHistoryExplorer } from './views/fileHistoryExplorer'; -import { LineHistoryExplorer } from './views/lineHistoryExplorer'; -import { RepositoriesExplorer } from './views/repositoriesExplorer'; -import { ResultsExplorer } from './views/resultsExplorer'; +import { FileHistoryView } from './views/fileHistoryView'; +import { LineHistoryView } from './views/lineHistoryView'; +import { RepositoriesView } from './views/repositoriesView'; +import { ResultsView } from './views/resultsView'; +import { ViewCommands } from './views/viewCommands'; import { SettingsEditor } from './webviews/settingsEditor'; import { WelcomeEditor } from './webviews/welcomeEditor'; @@ -40,41 +40,41 @@ export class Container { context.subscriptions.push((this._settingsEditor = new SettingsEditor())); context.subscriptions.push((this._welcomeEditor = new WelcomeEditor())); - if (config.repositoriesExplorer.enabled) { - context.subscriptions.push((this._repositoriesExplorer = new RepositoriesExplorer())); + if (config.views.repositories.enabled) { + context.subscriptions.push((this._repositoriesView = new RepositoriesView())); } else { let disposable: Disposable; disposable = configuration.onDidChange(e => { - if (configuration.changed(e, configuration.name('repositoriesExplorer')('enabled').value)) { + if (configuration.changed(e, configuration.name('views')('repositories')('enabled').value)) { disposable.dispose(); - context.subscriptions.push((this._repositoriesExplorer = new RepositoriesExplorer())); + context.subscriptions.push((this._repositoriesView = new RepositoriesView())); } }); } - if (config.fileHistoryExplorer.enabled) { - context.subscriptions.push((this._fileHistoryExplorer = new FileHistoryExplorer())); + if (config.views.fileHistory.enabled) { + context.subscriptions.push((this._fileHistoryView = new FileHistoryView())); } else { let disposable: Disposable; disposable = configuration.onDidChange(e => { - if (configuration.changed(e, configuration.name('fileHistoryExplorer')('enabled').value)) { + if (configuration.changed(e, configuration.name('views')('fileHistory')('enabled').value)) { disposable.dispose(); - context.subscriptions.push((this._fileHistoryExplorer = new FileHistoryExplorer())); + context.subscriptions.push((this._fileHistoryView = new FileHistoryView())); } }); } - if (config.lineHistoryExplorer.enabled) { - context.subscriptions.push((this._lineHistoryExplorer = new LineHistoryExplorer())); + if (config.views.lineHistory.enabled) { + context.subscriptions.push((this._lineHistoryView = new LineHistoryView())); } else { let disposable: Disposable; disposable = configuration.onDidChange(e => { - if (configuration.changed(e, configuration.name('lineHistoryExplorer')('enabled').value)) { + if (configuration.changed(e, configuration.name('views')('lineHistory')('enabled').value)) { disposable.dispose(); - context.subscriptions.push((this._lineHistoryExplorer = new LineHistoryExplorer())); + context.subscriptions.push((this._lineHistoryView = new LineHistoryView())); } }); } @@ -100,26 +100,18 @@ export class Container { return this._context; } - private static _explorerCommands: ExplorerCommands | undefined; - static get explorerCommands() { - if (this._explorerCommands === undefined) { - this._context.subscriptions.push((this._explorerCommands = new ExplorerCommands())); - } - return this._explorerCommands; - } - private static _fileAnnotationController: FileAnnotationController; static get fileAnnotations() { return this._fileAnnotationController; } - private static _fileHistoryExplorer: FileHistoryExplorer | undefined; - static get fileHistoryExplorer() { - if (this._fileHistoryExplorer === undefined) { - this._context.subscriptions.push((this._fileHistoryExplorer = new FileHistoryExplorer())); + private static _fileHistoryView: FileHistoryView | undefined; + static get fileHistoryView() { + if (this._fileHistoryView === undefined) { + this._context.subscriptions.push((this._fileHistoryView = new FileHistoryView())); } - return this._fileHistoryExplorer; + return this._fileHistoryView; } private static _git: GitService; @@ -127,9 +119,9 @@ export class Container { return this._git; } - private static _repositoriesExplorer: RepositoriesExplorer | undefined; - static get repositoriesExplorer(): RepositoriesExplorer { - return this._repositoriesExplorer!; + private static _repositoriesView: RepositoriesView | undefined; + static get repositoriesView(): RepositoriesView { + return this._repositoriesView!; } private static _keyboard: Keyboard; @@ -142,13 +134,13 @@ export class Container { return this._lineAnnotationController; } - private static _lineHistoryExplorer: LineHistoryExplorer | undefined; - static get lineHistoryExplorer() { - if (this._lineHistoryExplorer === undefined) { - this._context.subscriptions.push((this._lineHistoryExplorer = new LineHistoryExplorer())); + private static _lineHistoryView: LineHistoryView | undefined; + static get lineHistoryView() { + if (this._lineHistoryView === undefined) { + this._context.subscriptions.push((this._lineHistoryView = new LineHistoryView())); } - return this._lineHistoryExplorer; + return this._lineHistoryView; } private static _lineHoverController: LineHoverController; @@ -161,13 +153,13 @@ export class Container { return this._lineTracker; } - private static _resultsExplorer: ResultsExplorer | undefined; - static get resultsExplorer() { - if (this._resultsExplorer === undefined) { - this._context.subscriptions.push((this._resultsExplorer = new ResultsExplorer())); + private static _resultsView: ResultsView | undefined; + static get resultsView() { + if (this._resultsView === undefined) { + this._context.subscriptions.push((this._resultsView = new ResultsView())); } - return this._resultsExplorer; + return this._resultsView; } private static _settingsEditor: SettingsEditor; @@ -185,6 +177,14 @@ export class Container { return this._tracker; } + private static _viewCommands: ViewCommands | undefined; + static get viewCommands() { + if (this._viewCommands === undefined) { + this._context.subscriptions.push((this._viewCommands = new ViewCommands())); + } + return this._viewCommands; + } + private static _welcomeEditor: WelcomeEditor; static get welcomeEditor() { return this._welcomeEditor; @@ -206,18 +206,24 @@ export class Container { if (mode.currentLine != null) { config.currentLine.enabled = mode.currentLine; } - if (mode.explorers != null) { - config.repositoriesExplorer.enabled = mode.explorers; - } - if (mode.explorers != null) { - config.fileHistoryExplorer.enabled = mode.explorers; - } if (mode.hovers != null) { config.hovers.enabled = mode.hovers; } if (mode.statusBar != null) { config.statusBar.enabled = mode.statusBar; } + if (mode.views != null) { + config.views.fileHistory.enabled = mode.views; + } + if (mode.views != null) { + config.views.lineHistory.enabled = mode.views; + } + if (mode.views != null) { + config.views.repositories.enabled = mode.views; + } + // if (mode.views != null) { + // config.views.results.enabled = mode.views; + // } return config; } diff --git a/src/extension.ts b/src/extension.ts index f1e41ca..943ea27 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -9,6 +9,7 @@ import { GitService } from './git/gitService'; import { Logger } from './logger'; import { Messages } from './messages'; import { Strings, Versions } from './system'; +import { ModeConfig } from './ui/config'; // import { Telemetry } from './telemetry'; export async function activate(context: ExtensionContext) { @@ -33,20 +34,20 @@ export async function activate(context: ExtensionContext) { const cfg = configuration.get(); - // Pretend we are enabled (until we know otherwise) and set the explorer contexts to reduce flashing on load + // Pretend we are enabled (until we know otherwise) and set the view contexts to reduce flashing on load await Promise.all([ setCommandContext(CommandContext.Enabled, true), setCommandContext( - CommandContext.RepositoriesExplorer, - cfg.repositoriesExplorer.enabled ? cfg.repositoriesExplorer.location : false + CommandContext.ViewsRepositories, + cfg.views.repositories.enabled ? cfg.views.repositories.location : false ), setCommandContext( - CommandContext.FileHistoryExplorer, - cfg.fileHistoryExplorer.enabled ? cfg.fileHistoryExplorer.location : false + CommandContext.ViewsFileHistory, + cfg.views.fileHistory.enabled ? cfg.views.fileHistory.location : false ), setCommandContext( - CommandContext.LineHistoryExplorer, - cfg.lineHistoryExplorer.enabled ? cfg.lineHistoryExplorer.location : false + CommandContext.ViewsLineHistory, + cfg.views.lineHistory.enabled ? cfg.views.lineHistory.location : false ) ]); @@ -105,66 +106,126 @@ async function migrateSettings(context: ExtensionContext, previousVersion: strin if (Versions.compare(previous, Versions.from(9, 0, 0)) !== 1) { await configuration.migrate( 'gitExplorer.autoRefresh', - configuration.name('repositoriesExplorer')('autoRefresh').value + configuration.name('views')('repositories')('autoRefresh').value ); await configuration.migrate( 'gitExplorer.branches.layout', - configuration.name('repositoriesExplorer')('branches')('layout').value + configuration.name('views')('repositories')('branches')('layout').value ); await configuration.migrate( 'gitExplorer.enabled', - configuration.name('repositoriesExplorer')('enabled').value + configuration.name('views')('repositories')('enabled').value ); await configuration.migrate( 'gitExplorer.files.compact', - configuration.name('repositoriesExplorer')('files')('compact').value + configuration.name('views')('repositories')('files')('compact').value ); await configuration.migrate( 'gitExplorer.files.layout', - configuration.name('repositoriesExplorer')('files')('layout').value + configuration.name('views')('repositories')('files')('layout').value ); await configuration.migrate( 'gitExplorer.files.threshold', - configuration.name('repositoriesExplorer')('files')('threshold').value + configuration.name('views')('repositories')('files')('threshold').value ); await configuration.migrate( 'gitExplorer.includeWorkingTree', - configuration.name('repositoriesExplorer')('includeWorkingTree').value + configuration.name('views')('repositories')('includeWorkingTree').value ); await configuration.migrate( 'gitExplorer.location', - configuration.name('repositoriesExplorer')('location').value + configuration.name('views')('repositories')('location').value ); await configuration.migrate( 'gitExplorer.showTrackingBranch', - configuration.name('repositoriesExplorer')('showTrackingBranch').value + configuration.name('views')('repositories')('showTrackingBranch').value ); await configuration.migrate( 'historyExplorer.avatars', - configuration.name('fileHistoryExplorer')('avatars').value + configuration.name('views')('fileHistory')('avatars').value ); await configuration.migrate( 'historyExplorer.enabled', - configuration.name('fileHistoryExplorer')('enabled').value + configuration.name('views')('fileHistory')('enabled').value ); await configuration.migrate( 'historyExplorer.location', - configuration.name('fileHistoryExplorer')('location').value + configuration.name('views')('fileHistory')('location').value ); await configuration.migrate( 'historyExplorer.avatars', - configuration.name('lineHistoryExplorer')('avatars').value + configuration.name('views')('lineHistory')('avatars').value ); await configuration.migrate( 'historyExplorer.enabled', - configuration.name('lineHistoryExplorer')('enabled').value + configuration.name('views')('lineHistory')('enabled').value ); await configuration.migrate( 'historyExplorer.location', - configuration.name('lineHistoryExplorer')('location').value + configuration.name('views')('lineHistory')('location').value ); + + await configuration.migrate('explorers.avatars', configuration.name('views')('avatars').value); + await configuration.migrate( + 'explorers.commitFileFormat', + configuration.name('views')('commitFileFormat').value + ); + await configuration.migrate('explorers.commitFormat', configuration.name('views')('commitFormat').value); + await configuration.migrate( + 'explorers.defaultItemLimit', + configuration.name('views')('defaultItemLimit').value + ); + await configuration.migrate( + 'explorers.files.compact', + configuration.name('views')('files')('compact').value + ); + await configuration.migrate('explorers.files.layout', configuration.name('views')('files')('layout').value); + await configuration.migrate( + 'explorers.files.threshold', + configuration.name('views')('files')('threshold').value + ); + await configuration.migrate( + 'explorers.stashFileFormat', + configuration.name('views')('stashFileFormat').value + ); + await configuration.migrate('explorers.stashFormat', configuration.name('views')('stashFormat').value); + await configuration.migrate( + 'explorers.statusFileFormat', + configuration.name('views')('statusFileFormat').value + ); + + await configuration.migrate< + { + [key: string]: { + name: string; + statusBarItemName?: string; + description?: string; + codeLens?: boolean; + currentLine?: boolean; + explorers?: boolean; + hovers?: boolean; + statusBar?: boolean; + }; + }, + { + [key: string]: ModeConfig; + } + >('modes', configuration.name('modes').value, { + migrationFn: v => { + const modes = Object.create(null); + + for (const k in v) { + const { explorers, ...mode } = v[k]; + modes[k] = { ...mode, views: explorers }; + } + + return modes; + } + }); + + // await configuration.migrate('modes', configuration.name('modes')('').value); } } catch (ex) { diff --git a/src/quickpicks/commitsQuickPick.ts b/src/quickpicks/commitsQuickPick.ts index 7914037..5c09925 100644 --- a/src/quickpicks/commitsQuickPick.ts +++ b/src/quickpicks/commitsQuickPick.ts @@ -28,15 +28,15 @@ export class CommitsQuickPick { options: { goBackCommand?: CommandQuickPickItem; showAllCommand?: CommandQuickPickItem; - showInResultsExplorerCommand?: CommandQuickPickItem; + showInResultsCommand?: CommandQuickPickItem; } ): Promise { const items = ((log && [...Iterables.map(log.commits.values(), c => new CommitQuickPickItem(c))]) || [ new MessageQuickPickItem('No results found') ]) as (CommitQuickPickItem | CommandQuickPickItem)[]; - if (options.showInResultsExplorerCommand !== undefined) { - items.splice(0, 0, options.showInResultsExplorerCommand); + if (options.showInResultsCommand !== undefined) { + items.splice(0, 0, options.showInResultsCommand); } if (options.showAllCommand !== undefined) { diff --git a/src/quickpicks/commonQuickPicks.ts b/src/quickpicks/commonQuickPicks.ts index 0a4b851..cea513b 100644 --- a/src/quickpicks/commonQuickPicks.ts +++ b/src/quickpicks/commonQuickPicks.ts @@ -238,7 +238,7 @@ export class ShowCommitInResultsQuickPickItem extends CommandQuickPickItem { public readonly commit: GitLogCommit, item: QuickPickItem = { label: 'Show in Results', - description: `${Strings.pad(GlyphChars.Dash, 2, 2)} displays commit in the GitLens Results explorer` + description: `${Strings.pad(GlyphChars.Dash, 2, 2)} displays commit in the GitLens Results view` } ) { super(item, undefined, undefined); @@ -247,7 +247,7 @@ export class ShowCommitInResultsQuickPickItem extends CommandQuickPickItem { async execute( options: TextDocumentShowOptions = { preserveFocus: false, preview: false } ): Promise<{} | undefined> { - await Container.resultsExplorer.addCommit(this.commit); + await Container.resultsView.addCommit(this.commit); return undefined; } } @@ -258,7 +258,7 @@ export class ShowCommitsInResultsQuickPickItem extends CommandQuickPickItem { public readonly resultsLabel: string | { label: string; resultsType?: { singular: string; plural: string } }, item: QuickPickItem = { label: 'Show in Results', - description: `${Strings.pad(GlyphChars.Dash, 2, 2)} displays commits in the GitLens Results explorer` + description: `${Strings.pad(GlyphChars.Dash, 2, 2)} displays commits in the GitLens Results view` } ) { super(item, undefined, undefined); @@ -267,7 +267,7 @@ export class ShowCommitsInResultsQuickPickItem extends CommandQuickPickItem { async execute( options: TextDocumentShowOptions = { preserveFocus: false, preview: false } ): Promise<{} | undefined> { - await Container.resultsExplorer.addSearchResults(this.results.repoPath, this.results, this.resultsLabel); + await Container.resultsView.addSearchResults(this.results.repoPath, this.results, this.resultsLabel); return undefined; } } @@ -278,7 +278,7 @@ export class ShowCommitsSearchInResultsQuickPickItem extends ShowCommitsInResult public readonly search: string, item: QuickPickItem = { label: 'Show in Results', - description: `${Strings.pad(GlyphChars.Dash, 2, 2)} displays results in the GitLens Results explorer` + description: `${Strings.pad(GlyphChars.Dash, 2, 2)} displays results in the GitLens Results view` } ) { super(results, { label: search }, item); diff --git a/src/quickpicks/fileHistoryQuickPick.ts b/src/quickpicks/fileHistoryQuickPick.ts index ba052ce..7afb5e0 100644 --- a/src/quickpicks/fileHistoryQuickPick.ts +++ b/src/quickpicks/fileHistoryQuickPick.ts @@ -37,7 +37,7 @@ export class FileHistoryQuickPick { pickerOnly?: boolean; progressCancellation?: CancellationTokenSource; showAllCommand?: CommandQuickPickItem; - showInResultsExplorerCommand?: CommandQuickPickItem; + showInResultsCommand?: CommandQuickPickItem; } = {} ): Promise { options = { pickerOnly: false, ...options }; @@ -55,9 +55,9 @@ export class FileHistoryQuickPick { new ChooseFromBranchesAndTagsQuickPickItem(log.repoPath, placeHolder, options.currentCommand) ); - if (options.showInResultsExplorerCommand !== undefined) { + if (options.showInResultsCommand !== undefined) { index++; - items.splice(0, 0, options.showInResultsExplorerCommand); + items.splice(0, 0, options.showInResultsCommand); } if (log.truncated || log.sha) { diff --git a/src/ui/config.ts b/src/ui/config.ts index f4e83d8..557e411 100644 --- a/src/ui/config.ts +++ b/src/ui/config.ts @@ -39,12 +39,12 @@ export enum DateStyle { Relative = 'relative' } -export enum ExplorerBranchesLayout { +export enum ViewBranchesLayout { List = 'list', Tree = 'tree' } -export enum ExplorerFilesLayout { +export enum ViewFilesLayout { Auto = 'auto', List = 'list', Tree = 'tree' @@ -140,10 +140,11 @@ export interface CodeLensConfig { symbolScopes: string[]; } -export interface ExplorersConfig { +export interface ViewsConfig { avatars: boolean; + fileHistory: FileHistoryViewConfig; files: { - layout: ExplorerFilesLayout; + layout: ViewFilesLayout; compact: boolean; threshold: number; }; @@ -151,24 +152,27 @@ export interface ExplorersConfig { commitFormat: string; // dateFormat: string | null; defaultItemLimit: number; + lineHistory: LineHistoryViewConfig; + repositories: RepositoriesViewConfig; + results: ResultsViewConfig; stashFileFormat: string; stashFormat: string; statusFileFormat: string; } -export interface ExplorersFilesConfig { +export interface ViewsFilesConfig { compact: boolean; - layout: ExplorerFilesLayout; + layout: ViewFilesLayout; threshold: number; } -export interface FileHistoryExplorerConfig { +export interface FileHistoryViewConfig { avatars: boolean; enabled: boolean; location: 'explorer' | 'gitlens' | 'scm'; } -export interface LineHistoryExplorerConfig extends FileHistoryExplorerConfig {} +export interface LineHistoryViewConfig extends FileHistoryViewConfig {} export interface MenuConfig { editor: @@ -209,26 +213,26 @@ export interface ModeConfig { description?: string; codeLens?: boolean; currentLine?: boolean; - explorers?: boolean; hovers?: boolean; statusBar?: boolean; + views?: boolean; } -export interface RepositoriesExplorerConfig { +export interface RepositoriesViewConfig { autoRefresh: boolean; autoReveal: boolean; branches: { - layout: ExplorerBranchesLayout; + layout: ViewBranchesLayout; }; enabled: boolean; - files: ExplorersFilesConfig; + files: ViewsFilesConfig; includeWorkingTree: boolean; location: 'explorer' | 'gitlens' | 'scm'; showTrackingBranch: boolean; } -export interface ResultsExplorerConfig { - files: ExplorersFilesConfig; +export interface ResultsViewConfig { + files: ViewsFilesConfig; location: 'explorer' | 'gitlens' | 'scm'; } @@ -281,14 +285,12 @@ export interface Config { defaultDateFormat: string | null; defaultDateStyle: DateStyle; defaultGravatarsStyle: GravatarDefaultStyle; - explorers: ExplorersConfig; heatmap: { ageThreshold: number; coldColor: string; hotColor: string; toggleMode: AnnotationsToggleMode; }; - fileHistoryExplorer: FileHistoryExplorerConfig; hovers: { annotations: { changes: boolean; @@ -307,7 +309,6 @@ export interface Config { }; insiders: boolean; keymap: KeyMap; - lineHistoryExplorer: LineHistoryExplorerConfig; menus: boolean | MenuConfig; mode: { active: string; @@ -325,8 +326,6 @@ export interface Config { toggleMode: AnnotationsToggleMode; }; remotes: RemotesConfig[]; - repositoriesExplorer: RepositoriesExplorerConfig; - resultsExplorer: ResultsExplorerConfig; showWhatsNewAfterUpgrades: boolean; statusBar: { alignment: 'left' | 'right'; @@ -345,5 +344,6 @@ export interface Config { }; }; }; + views: ViewsConfig; advanced: AdvancedConfig; } diff --git a/src/ui/settings/index.html b/src/ui/settings/index.html index 7c3b195..d430221 100644 --- a/src/ui/settings/index.html +++ b/src/ui/settings/index.html @@ -291,28 +291,28 @@ -
+
-

Repositories Explorer - +

Repositories view +

- Adds a Repositories explorer to visualize, navigate, and explore Git repositories + Adds a Repositories view to visualize, navigate, and explore Git repositories

- - +
-
- - @@ -320,74 +320,74 @@
- - - - - - -
+ data-visibility="repositoriesView.enabled & repositoriesView.files.layout !tree" /> + data-visibility="repositoriesView.enabled & repositoriesView.files.layout =tree & repositoriesView.files.compact" /> + data-visibility="repositoriesView.enabled & repositoriesView.files.layout =tree & repositoriesView.files.compact =false" /> + data-visibility="repositoriesView.enabled & views.avatars" />

@@ -395,34 +395,34 @@ User Settings - and search for gitlens.repositoriesExplorer or gitlens.explorers + and search for gitlens.views.repositories or gitlens.views

-
+
-

File History Explorer - +

File History view +

- Adds a File History explorer to visualize, navigate, and explore the revision history + Adds a File History view to visualize, navigate, and explore the revision history of the current file

- - +
-
- - @@ -430,45 +430,45 @@
-
+ data-visibility="fileHistoryView.enabled" /> + data-visibility="fileHistoryView.enabled & fileHistoryView.avatars" />
-
+
-

Line History Explorer - +

Line History view +

- Adds a Line History explorer to visualize, navigate, and explore the revision history + Adds a Line History view to visualize, navigate, and explore the revision history of the selected lines of current file

- - +
-
- - @@ -476,39 +476,39 @@
-
+ data-visibility="lineHistoryView.enabled" /> + data-visibility="lineHistoryView.enabled & lineHistoryView.avatars" />
-
+
-

Results Explorer - +

Results view +

- Adds an on-demand Results explorer to navigate and explore commits, histories, and + Adds an on-demand Results view to navigate and explore commits, histories, and searches, or visualize comparisons between branches, tags, commits, and more

- - @@ -516,8 +516,8 @@
+ data-visibility="resultsView.files.layout !tree" /> + data-visibility="resultsView.files.layout =tree & resultsView.files.compact" /> + data-visibility="resultsView.files.layout =tree & resultsView.files.compact =false" /> + data-visibility="views.avatars" />

@@ -555,7 +555,7 @@ User Settings - and search for gitlens.resultsExplorer or gitlens.explorers + and search for gitlens.views.results or gitlens.views

@@ -1603,23 +1603,23 @@ General
  • - - Repositories Explorer + + Repositories view
  • - - File History Explorer + + File History view
  • - - Line History Explorer + + Line History view
  • - - Results Explorer + + Results view
  • diff --git a/src/ui/welcome/index.html b/src/ui/welcome/index.html index 282babf..6c71cae 100644 --- a/src/ui/welcome/index.html +++ b/src/ui/welcome/index.html @@ -99,27 +99,27 @@ Here are just some of the features that GitLens provides,
    • - a - Repositories explorer + a + Repositories view to visualize, navigate, and explore Git repositories
    • - a - File History explorer + a + File History view to visualize, navigate, and explore the revision history of the current file
    • - a - Line History explorer + a + Line History view to visualize, navigate, and explore the revision history of the selected lines of current file
    • - an on-demand - Results explorer + an on-demand + Results view to navigate and explore commits, histories, and searches, or visualize comparisons between branches, tags, commits, and more diff --git a/src/views/explorer.ts b/src/views/explorer.ts deleted file mode 100644 index 99cc91c..0000000 --- a/src/views/explorer.ts +++ /dev/null @@ -1,178 +0,0 @@ -'use strict'; -import { - ConfigurationChangeEvent, - Disposable, - Event, - EventEmitter, - TreeDataProvider, - TreeItem, - TreeView, - TreeViewVisibilityChangeEvent, - window -} from 'vscode'; -import { configuration } from '../configuration'; -import { Container } from '../container'; -import { Logger } from '../logger'; -import { RefreshNodeCommandArgs } from './explorerCommands'; -import { FileHistoryExplorer } from './fileHistoryExplorer'; -import { LineHistoryExplorer } from './lineHistoryExplorer'; -import { ExplorerNode } from './nodes'; -import { isPageable } from './nodes/explorerNode'; -import { RepositoriesExplorer } from './repositoriesExplorer'; -import { ResultsExplorer } from './resultsExplorer'; - -export enum RefreshReason { - Command = 'Command', - ConfigurationChanged = 'ConfigurationChanged', - VisibilityChanged = 'VisibilityChanged' -} - -export type Explorer = RepositoriesExplorer | FileHistoryExplorer | LineHistoryExplorer | ResultsExplorer; - -export abstract class ExplorerBase implements TreeDataProvider, Disposable { - protected _onDidChangeTreeData = new EventEmitter(); - public get onDidChangeTreeData(): Event { - return this._onDidChangeTreeData.event; - } - - private _onDidChangeVisibility = new EventEmitter(); - public get onDidChangeVisibility(): Event { - return this._onDidChangeVisibility.event; - } - - protected _disposable: Disposable | undefined; - protected _root: TRoot | undefined; - protected _tree: TreeView | undefined; - - constructor( - public readonly id: string - ) { - this.registerCommands(); - - Container.context.subscriptions.push(configuration.onDidChange(this.onConfigurationChanged, this)); - setImmediate(() => this.onConfigurationChanged(configuration.initializingChangeEvent)); - } - - dispose() { - this._disposable && this._disposable.dispose(); - } - - getQualifiedCommand(command: string) { - return `${this.id}.${command}`; - } - - protected abstract getRoot(): TRoot; - protected abstract registerCommands(): void; - protected abstract onConfigurationChanged(e: ConfigurationChangeEvent): void; - - protected initialize(container?: string) { - if (this._disposable) { - this._disposable.dispose(); - this._onDidChangeTreeData = new EventEmitter(); - } - - this._tree = window.createTreeView(`${this.id}${container ? `:${container}` : ''}`, { - treeDataProvider: this - }); - this._disposable = Disposable.from( - this._tree, - this._tree.onDidChangeVisibility(this.onVisibilityChanged, this) - ); - } - - getChildren(node?: ExplorerNode): ExplorerNode[] | Promise { - if (node !== undefined) return node.getChildren(); - - if (this._root === undefined) { - this._root = this.getRoot(); - } - - return this._root.getChildren(); - } - - getParent(node: ExplorerNode): ExplorerNode | undefined { - return node.getParent(); - } - - getTreeItem(node: ExplorerNode): TreeItem | Promise { - return node.getTreeItem(); - } - - protected onVisibilityChanged(e: TreeViewVisibilityChangeEvent) { - this._onDidChangeVisibility.fire(e); - } - - get selection(): ExplorerNode[] { - if (this._tree === undefined || this._root === undefined) return []; - - return this._tree.selection; - } - - get visible(): boolean { - return this._tree !== undefined ? this._tree.visible : false; - } - - async refresh(reason?: RefreshReason) { - if (reason === undefined) { - reason = RefreshReason.Command; - } - - Logger.log(`Explorer(${this.id}).refresh`, `reason='${reason}'`); - - if (this._root !== undefined) { - await this._root.refresh(reason); - } - - this.triggerNodeUpdate(); - } - - async refreshNode(node: ExplorerNode, args?: RefreshNodeCommandArgs) { - Logger.log(`Explorer(${this.id}).refreshNode(${(node as { id?: string }).id || ''})`); - - if (args !== undefined) { - if (isPageable(node)) { - if (args.maxCount === undefined || args.maxCount === 0) { - node.maxCount = args.maxCount; - } - else { - node.maxCount = (node.maxCount || args.maxCount) + args.maxCount; - } - } - } - - const cancel = await node.refresh(); - if (cancel === true) return; - - this.triggerNodeUpdate(node); - } - - async reveal( - node: ExplorerNode, - options?: { - select?: boolean | undefined; - focus?: boolean | undefined; - } - ) { - if (this._tree === undefined || this._root === undefined) return; - - try { - await this._tree.reveal(node, options); - } - catch (ex) { - Logger.error(ex); - } - } - - async show() { - if (this._tree === undefined || this._root === undefined) return; - - // This sucks -- have to get the first child to reveal the tree - const [child] = await this._root.getChildren(); - return this.reveal(child, { select: false, focus: true }); - } - - triggerNodeUpdate(node?: ExplorerNode) { - // Since the root node won't actually refresh, force everything - this._onDidChangeTreeData.fire(node !== undefined && node !== this._root ? node : undefined); - } -} diff --git a/src/views/explorerCommands.ts b/src/views/explorerCommands.ts deleted file mode 100644 index 39580b9..0000000 --- a/src/views/explorerCommands.ts +++ /dev/null @@ -1,550 +0,0 @@ -'use strict'; -import * as path from 'path'; -import { commands, Disposable, InputBoxOptions, Terminal, TextDocumentShowOptions, Uri, window } from 'vscode'; -import { - Commands, - DiffWithCommandArgs, - DiffWithCommandArgsRevision, - DiffWithPreviousCommandArgs, - DiffWithWorkingCommandArgs, - openEditor, - OpenFileInRemoteCommandArgs, - OpenFileRevisionCommandArgs, - openWorkspace -} from '../commands'; -import { BuiltInCommands, CommandContext, extensionTerminalName, setCommandContext } from '../constants'; -import { Container } from '../container'; -import { toGitLensFSUri } from '../git/fsProvider'; -import { GitService, GitUri } from '../git/gitService'; -import { Arrays } from '../system'; -import { - BranchNode, - CommitFileNode, - CommitNode, - ExplorerNode, - ExplorerRefNode, - RemoteNode, - RepositoryNode, - ResultsFileNode, - StashFileNode, - StashNode, - StatusFileNode, - StatusUpstreamNode, - TagNode -} from './nodes'; - -export interface RefreshNodeCommandArgs { - maxCount?: number; -} - -interface ICompareSelected { - ref: string; - repoPath: string | undefined; - uri?: Uri; -} - -export class ExplorerCommands implements Disposable { - private _disposable: Disposable | undefined; - private _terminal: Terminal | undefined; - private _terminalCwd: string | undefined; - - constructor() { - commands.registerCommand('gitlens.explorers.fetch', this.fetch, this); - commands.registerCommand('gitlens.explorers.pull', this.pull, this); - commands.registerCommand('gitlens.explorers.push', this.push, this); - commands.registerCommand('gitlens.explorers.closeRepository', this.closeRepository, this); - - commands.registerCommand('gitlens.explorers.exploreRepoRevision', this.exploreRepoRevision, this); - - commands.registerCommand('gitlens.explorers.openChanges', this.openChanges, this); - commands.registerCommand('gitlens.explorers.openChangesWithWorking', this.openChangesWithWorking, this); - commands.registerCommand('gitlens.explorers.openFile', this.openFile, this); - commands.registerCommand('gitlens.explorers.openFileRevision', this.openFileRevision, this); - commands.registerCommand('gitlens.explorers.openFileRevisionInRemote', this.openFileRevisionInRemote, this); - commands.registerCommand('gitlens.explorers.openChangedFiles', this.openChangedFiles, this); - commands.registerCommand('gitlens.explorers.openChangedFileChanges', this.openChangedFileChanges, this); - commands.registerCommand( - 'gitlens.explorers.openChangedFileChangesWithWorking', - this.openChangedFileChangesWithWorking, - this - ); - commands.registerCommand('gitlens.explorers.openChangedFileRevisions', this.openChangedFileRevisions, this); - commands.registerCommand('gitlens.explorers.applyChanges', this.applyChanges, this); - - commands.registerCommand('gitlens.explorers.stageFile', this.stageFile, this); - commands.registerCommand('gitlens.explorers.unstageFile', this.unstageFile, this); - - commands.registerCommand('gitlens.explorers.compareAncestryWithWorking', this.compareAncestryWithWorking, this); - commands.registerCommand('gitlens.explorers.compareWithHead', this.compareWithHead, this); - commands.registerCommand('gitlens.explorers.compareWithRemote', this.compareWithRemote, this); - commands.registerCommand('gitlens.explorers.compareWithSelected', this.compareWithSelected, this); - commands.registerCommand('gitlens.explorers.compareWithWorking', this.compareWithWorking, this); - commands.registerCommand('gitlens.explorers.selectForCompare', this.selectForCompare, this); - - commands.registerCommand('gitlens.explorers.terminalCheckoutBranch', this.terminalCheckoutBranch, this); - commands.registerCommand('gitlens.explorers.terminalCreateBranch', this.terminalCreateBranch, this); - commands.registerCommand('gitlens.explorers.terminalDeleteBranch', this.terminalDeleteBranch, this); - commands.registerCommand('gitlens.explorers.terminalMergeBranch', this.terminalMergeBranch, this); - commands.registerCommand('gitlens.explorers.terminalRebaseBranch', this.terminalRebaseBranch, this); - commands.registerCommand( - 'gitlens.explorers.terminalRebaseBranchToRemote', - this.terminalRebaseBranchToRemote, - this - ); - commands.registerCommand( - 'gitlens.explorers.terminalSquashBranchIntoCommit', - this.terminalSquashBranchIntoCommit, - this - ); - commands.registerCommand('gitlens.explorers.terminalCheckoutCommit', this.terminalCheckoutCommit, this); - commands.registerCommand('gitlens.explorers.terminalCherryPickCommit', this.terminalCherryPickCommit, this); - commands.registerCommand('gitlens.explorers.terminalPushCommit', this.terminalPushCommit, this); - commands.registerCommand('gitlens.explorers.terminalRebaseCommit', this.terminalRebaseCommit, this); - commands.registerCommand('gitlens.explorers.terminalResetCommit', this.terminalResetCommit, this); - commands.registerCommand('gitlens.explorers.terminalRevertCommit', this.terminalRevertCommit, this); - commands.registerCommand('gitlens.explorers.terminalRemoveRemote', this.terminalRemoveRemote, this); - commands.registerCommand('gitlens.explorers.terminalCreateTag', this.terminalCreateTag, this); - commands.registerCommand('gitlens.explorers.terminalDeleteTag', this.terminalDeleteTag, this); - } - - dispose() { - this._disposable && this._disposable.dispose(); - } - - private fetch(node: RepositoryNode) { - if (!(node instanceof RepositoryNode)) return; - - return node.fetch(); - } - - private pull(node: RepositoryNode) { - if (!(node instanceof RepositoryNode)) return; - - return node.pull(); - } - - private push(node: RepositoryNode) { - if (!(node instanceof RepositoryNode)) return; - - return node.push(); - } - - private async applyChanges(node: CommitFileNode | StashFileNode | ResultsFileNode) { - void (await this.openFile(node)); - - if (node.uri.sha !== undefined && node.uri.sha !== 'HEAD') { - void (await Container.git.applyChangesToWorkingFile(node.uri)); - } - } - - private closeRepository(node: RepositoryNode) { - if (!(node instanceof RepositoryNode)) return; - - node.repo.closed = true; - } - - private compareWithHead(node: ExplorerNode) { - if (!(node instanceof ExplorerRefNode)) return; - - return Container.resultsExplorer.addComparison(node.repoPath, node.ref, 'HEAD'); - } - - private compareWithRemote(node: BranchNode) { - if (!node.branch.tracking) return; - - return Container.resultsExplorer.addComparison(node.repoPath, node.branch.tracking, node.ref); - } - - private compareWithWorking(node: ExplorerNode) { - if (!(node instanceof ExplorerRefNode)) return; - - return Container.resultsExplorer.addComparison(node.repoPath, node.ref, ''); - } - - private async compareAncestryWithWorking(node: BranchNode) { - const branch = await Container.git.getBranch(node.repoPath); - if (branch === undefined) return; - - const commonAncestor = await Container.git.getMergeBase(node.repoPath, branch.ref, node.ref); - if (commonAncestor === undefined) return; - - return Container.resultsExplorer.addComparison( - node.repoPath, - { ref: commonAncestor, label: `ancestry with ${node.ref} (${GitService.shortenSha(commonAncestor)})` }, - '' - ); - } - - private compareWithSelected(node: ExplorerNode) { - if (this._selection === undefined || !(node instanceof ExplorerRefNode)) return; - if (this._selection.repoPath !== node.repoPath) return; - - if (this._selection.uri !== undefined) { - if (!(node instanceof CommitFileNode)) return; - - const diffArgs: DiffWithCommandArgs = { - repoPath: this._selection.repoPath, - lhs: { - sha: this._selection.ref, - uri: this._selection.uri! - }, - rhs: { - sha: node.ref, - uri: node.uri - } - }; - commands.executeCommand(Commands.DiffWith, diffArgs); - - return; - } - - return Container.resultsExplorer.addComparison(this._selection.repoPath, this._selection.ref, node.ref); - } - - private _selection: ICompareSelected | undefined; - - private selectForCompare(node: ExplorerNode) { - if (!(node instanceof ExplorerRefNode)) return; - - this._selection = { - ref: node.ref, - repoPath: node.repoPath, - uri: node instanceof CommitFileNode ? node.uri : undefined - }; - setCommandContext(CommandContext.ExplorersCanCompare, true); - } - - private exploreRepoRevision(node: ExplorerRefNode, options: { openInNewWindow?: boolean } = {}) { - if (!(node instanceof ExplorerRefNode)) return; - - const uri = toGitLensFSUri(node.ref, node.repoPath); - const gitUri = GitUri.fromRevisionUri(uri); - - openWorkspace(uri, `${path.basename(gitUri.repoPath!)} @ ${gitUri.shortSha}`, options); - - void commands.executeCommand(BuiltInCommands.FocusFilesExplorer); - } - - private openChanges(node: CommitFileNode | StashFileNode | ResultsFileNode) { - const command = node.getCommand(); - if (command === undefined || command.arguments === undefined) return; - - const [uri, args] = command.arguments as [Uri, DiffWithPreviousCommandArgs]; - args.showOptions!.preview = false; - return commands.executeCommand(command.command, uri, args); - } - - private async openChangesWithWorking(node: CommitFileNode | StashFileNode | ResultsFileNode) { - const args: DiffWithWorkingCommandArgs = { - showOptions: { - preserveFocus: true, - preview: false - } - }; - - if (node instanceof ResultsFileNode) { - args.commit = await Container.git.getLogCommitForFile(node.repoPath, node.uri.fsPath, { - ref: node.uri.sha, - firstIfNotFound: true, - reverse: true - }); - } - - return commands.executeCommand(Commands.DiffWithWorking, node.uri, args); - } - - private openFile(node: CommitFileNode | StashFileNode | ResultsFileNode) { - return openEditor(node.uri, { preserveFocus: true, preview: false }); - } - - private openFileRevision( - node: CommitFileNode | StashFileNode | ResultsFileNode, - options: OpenFileRevisionCommandArgs = { showOptions: { preserveFocus: true, preview: false } } - ) { - let uri = options.uri; - if (uri == null) { - if (node instanceof ResultsFileNode) { - uri = GitUri.toRevisionUri(node.uri); - } - else { - uri = - node.commit.status === 'D' - ? GitUri.toRevisionUri( - node.commit.previousSha!, - node.commit.previousUri.fsPath, - node.commit.repoPath - ) - : GitUri.toRevisionUri(node.uri); - } - } - - return openEditor(uri, options.showOptions || { preserveFocus: true, preview: false }); - } - - private async openChangedFileChanges( - node: CommitNode | StashNode, - options: TextDocumentShowOptions = { preserveFocus: false, preview: false } - ) { - const repoPath = node.commit.repoPath; - const uris = node.commit.files.map(s => GitUri.fromFile(s, repoPath)); - - for (const uri of uris) { - await this.openDiffWith( - repoPath, - { - uri: uri, - sha: - node.commit.previousSha !== undefined ? node.commit.previousSha : GitService.deletedOrMissingSha - }, - { uri: uri, sha: node.commit.sha }, - options - ); - } - } - - private async openChangedFileChangesWithWorking( - node: CommitNode | StashNode, - options: TextDocumentShowOptions = { preserveFocus: false, preview: false } - ) { - const repoPath = node.commit.repoPath; - const uris = Arrays.filterMap( - node.commit.files, - f => (f.status !== 'D' ? GitUri.fromFile(f, repoPath) : undefined) - ); - - for (const uri of uris) { - await this.openDiffWith(repoPath, { uri: uri, sha: node.commit.sha }, { uri: uri, sha: '' }, options); - } - } - - private async openChangedFiles( - node: CommitNode | StashNode, - options: TextDocumentShowOptions = { preserveFocus: false, preview: false } - ) { - const repoPath = node.commit.repoPath; - const uris = Arrays.filterMap(node.commit.files, f => GitUri.fromFile(f, repoPath)); - - for (const uri of uris) { - await openEditor(uri, options); - } - } - - private async openChangedFileRevisions( - node: CommitNode | StashNode, - options: TextDocumentShowOptions = { preserveFocus: false, preview: false } - ) { - const uris = Arrays.filterMap(node.commit.files, f => - GitUri.toRevisionUri( - f.status === 'D' ? node.commit.previousFileSha : node.commit.sha, - f, - node.commit.repoPath - ) - ); - for (const uri of uris) { - await openEditor(uri, options); - } - } - - private async openDiffWith( - repoPath: string, - lhs: DiffWithCommandArgsRevision, - rhs: DiffWithCommandArgsRevision, - options: TextDocumentShowOptions = { preserveFocus: false, preview: false } - ) { - const diffArgs: DiffWithCommandArgs = { - repoPath: repoPath, - lhs: lhs, - rhs: rhs, - showOptions: options - }; - return commands.executeCommand(Commands.DiffWith, diffArgs); - } - - private async openFileRevisionInRemote(node: CommitFileNode | StashFileNode | StatusFileNode) { - return commands.executeCommand(Commands.OpenFileInRemote, node.commit.toGitUri(node.commit.status === 'D'), { - range: false - } as OpenFileInRemoteCommandArgs); - } - - stageFile(node: CommitFileNode | StatusFileNode) { - if (!(node instanceof CommitFileNode) && !(node instanceof StatusFileNode)) return; - - Container.git.stageFile(node.repoPath, node.file.fileName); - } - - unstageFile(node: CommitFileNode | StatusFileNode) { - if (!(node instanceof CommitFileNode) && !(node instanceof StatusFileNode)) return; - - Container.git.unStageFile(node.repoPath, node.file.fileName); - } - - async terminalCheckoutBranch(node: ExplorerNode) { - if (!(node instanceof BranchNode)) return; - - this.sendTerminalCommand('checkout', `${node.ref}`, node.repoPath); - } - - async terminalCreateBranch(node: ExplorerNode) { - if (!(node instanceof ExplorerRefNode)) return; - - let remoteBranch = false; - let value = undefined; - if (node instanceof BranchNode && node.branch.remote) { - remoteBranch = true; - value = node.branch.getName(); - } - - const name = await window.showInputBox({ - prompt: `Please provide a branch name (Press 'Enter' to confirm or 'Escape' to cancel)`, - placeHolder: `Branch name`, - value: value - } as InputBoxOptions); - if (name === undefined || name === '') return; - - this.sendTerminalCommand('branch', `${remoteBranch ? '-t ' : ''}${name} ${node.ref}`, node.repoPath); - } - - terminalDeleteBranch(node: ExplorerNode) { - if (!(node instanceof BranchNode)) return; - - if (node.branch.remote) { - this.sendTerminalCommand('push', `${node.branch.getRemote()} :${node.branch.getName()}`, node.repoPath); - } - else { - this.sendTerminalCommand('branch', `-d ${node.ref}`, node.repoPath); - } - } - - terminalMergeBranch(node: ExplorerNode) { - if (!(node instanceof BranchNode)) return; - - this.sendTerminalCommand('merge', `${node.ref}`, node.repoPath); - } - - terminalRebaseBranch(node: ExplorerNode) { - if (!(node instanceof BranchNode)) return; - - this.sendTerminalCommand('rebase', `-i ${node.ref}`, node.repoPath); - } - - terminalRebaseBranchToRemote(node: ExplorerNode) { - if (node instanceof BranchNode) { - if (!node.branch.current || !node.branch.tracking) return; - - this.sendTerminalCommand('rebase', `-i ${node.branch.tracking}`, node.repoPath); - } - else if (node instanceof StatusUpstreamNode) { - this.sendTerminalCommand('rebase', `-i ${node.status.upstream}`, node.status.repoPath); - } - } - - terminalSquashBranchIntoCommit(node: ExplorerNode) { - if (!(node instanceof BranchNode)) return; - - this.sendTerminalCommand('merge', `--squash ${node.ref}`, node.repoPath); - } - - terminalCheckoutCommit(node: ExplorerNode) { - if (!(node instanceof CommitNode)) return; - - this.sendTerminalCommand('checkout', `${node.ref}`, node.repoPath); - } - - terminalCherryPickCommit(node: ExplorerNode) { - if (!(node instanceof CommitNode)) return; - - this.sendTerminalCommand('cherry-pick', `-e ${node.ref}`, node.repoPath); - } - - async terminalPushCommit(node: ExplorerNode) { - if (!(node instanceof CommitNode)) return; - - const branch = node.branch || (await Container.git.getBranch(node.repoPath)); - if (branch === undefined) return; - - this.sendTerminalCommand('push', `${branch.getRemote()} ${node.ref}:${branch.getName()}`, node.repoPath); - } - - terminalRebaseCommit(node: ExplorerNode) { - if (!(node instanceof CommitNode)) return; - - this.sendTerminalCommand('rebase', `-i ${node.ref}^`, node.repoPath); - } - - terminalResetCommit(node: ExplorerNode) { - if (!(node instanceof CommitNode)) return; - - this.sendTerminalCommand('reset', `--soft ${node.ref}`, node.repoPath); - } - - terminalRevertCommit(node: ExplorerNode) { - if (!(node instanceof CommitNode)) return; - - this.sendTerminalCommand('revert', `-e ${node.ref}`, node.repoPath); - } - - terminalRemoveRemote(node: ExplorerNode) { - if (!(node instanceof RemoteNode)) return; - - this.sendTerminalCommand('remote', `remove ${node.remote.name}`, node.remote.repoPath); - } - - async terminalCreateTag(node: ExplorerNode) { - if (!(node instanceof ExplorerRefNode)) return; - - const name = await window.showInputBox({ - prompt: `Please provide a tag name (Press 'Enter' to confirm or 'Escape' to cancel)`, - placeHolder: `Tag name` - } as InputBoxOptions); - if (name === undefined || name === '') return; - - const message = await window.showInputBox({ - prompt: `Please provide an optional message to annotate the tag (Press 'Enter' to confirm or 'Escape' to cancel)`, - placeHolder: `Tag message` - } as InputBoxOptions); - if (message === undefined) return; - - const args = `${message !== '' ? `-a -m "${message}" ` : ''}${name} ${node.ref}`; - this.sendTerminalCommand('tag', args, node.repoPath); - } - - terminalDeleteTag(node: ExplorerNode) { - if (!(node instanceof TagNode)) return; - - this.sendTerminalCommand('tag', `-d ${node.ref}`, node.repoPath); - } - - private ensureTerminal(cwd: string): Terminal { - if (this._terminal === undefined) { - this._terminal = window.createTerminal(extensionTerminalName); - this._disposable = window.onDidCloseTerminal((e: Terminal) => { - if (e.name === extensionTerminalName) { - this._terminal = undefined; - this._disposable!.dispose(); - this._disposable = undefined; - } - }, this); - - Container.context.subscriptions.push(this._disposable); - this._terminalCwd = undefined; - } - - if (this._terminalCwd !== cwd) { - this._terminal.sendText(`cd "${cwd}"`, true); - this._terminalCwd = cwd; - } - - return this._terminal; - } - - private sendTerminalCommand(command: string, args: string, cwd: string) { - // let git = GitService.getGitPath(); - // if (git.includes(' ')) { - // git = `"${git}"`; - // } - - const terminal = this.ensureTerminal(cwd); - terminal.show(false); - terminal.sendText(`git ${command} ${args}`, false); - } -} diff --git a/src/views/fileHistoryExplorer.ts b/src/views/fileHistoryExplorer.ts deleted file mode 100644 index c221d4d..0000000 --- a/src/views/fileHistoryExplorer.ts +++ /dev/null @@ -1,98 +0,0 @@ -'use strict'; -import { commands, ConfigurationChangeEvent } from 'vscode'; -import { configuration, ExplorersConfig, FileHistoryExplorerConfig } from '../configuration'; -import { CommandContext, setCommandContext } from '../constants'; -import { Container } from '../container'; -import { ExplorerBase, RefreshReason } from './explorer'; -import { RefreshNodeCommandArgs } from './explorerCommands'; -import { ExplorerNode, FileHistoryTrackerNode } from './nodes'; - -export class FileHistoryExplorer extends ExplorerBase { - constructor() { - super('gitlens.fileHistoryExplorer'); - } - - getRoot() { - return new FileHistoryTrackerNode(this); - } - - protected registerCommands() { - Container.explorerCommands; - commands.registerCommand(this.getQualifiedCommand('refresh'), () => this.refresh(), this); - commands.registerCommand( - this.getQualifiedCommand('refreshNode'), - (node: ExplorerNode, args?: RefreshNodeCommandArgs) => this.refreshNode(node, args), - this - ); - - commands.registerCommand( - this.getQualifiedCommand('setEditorFollowingOn'), - () => this.setEditorFollowing(true), - this - ); - commands.registerCommand( - this.getQualifiedCommand('setEditorFollowingOff'), - () => this.setEditorFollowing(false), - this - ); - commands.registerCommand( - this.getQualifiedCommand('setRenameFollowingOn'), - () => this.setRenameFollowing(true), - this - ); - commands.registerCommand( - this.getQualifiedCommand('setRenameFollowingOff'), - () => this.setRenameFollowing(false), - this - ); - } - - protected onConfigurationChanged(e: ConfigurationChangeEvent) { - const initializing = configuration.initializing(e); - - if ( - !initializing && - !configuration.changed(e, configuration.name('fileHistoryExplorer').value) && - !configuration.changed(e, configuration.name('explorers').value) && - !configuration.changed(e, configuration.name('defaultGravatarsStyle').value) && - !configuration.changed(e, configuration.name('advanced')('fileHistoryFollowsRenames').value) - ) { - return; - } - - if ( - initializing || - configuration.changed(e, configuration.name('fileHistoryExplorer')('enabled').value) || - configuration.changed(e, configuration.name('fileHistoryExplorer')('location').value) - ) { - setCommandContext(CommandContext.FileHistoryExplorer, this.config.enabled ? this.config.location : false); - setCommandContext(CommandContext.FileHistoryExplorerEditorFollowing, true); - } - - if (initializing || configuration.changed(e, configuration.name('fileHistoryExplorer')('location').value)) { - this.initialize(this.config.location); - } - - if (!initializing && this._root !== undefined) { - void this.refresh(RefreshReason.ConfigurationChanged); - } - } - - get config(): ExplorersConfig & FileHistoryExplorerConfig { - return { ...Container.config.explorers, ...Container.config.fileHistoryExplorer }; - } - - private setEditorFollowing(enabled: boolean) { - setCommandContext(CommandContext.FileHistoryExplorerEditorFollowing, enabled); - if (this._root !== undefined) { - this._root.setEditorFollowing(enabled); - } - } - - private setRenameFollowing(enabled: boolean) { - return configuration.updateEffective( - configuration.name('advanced')('fileHistoryFollowsRenames').value, - enabled - ); - } -} diff --git a/src/views/fileHistoryView.ts b/src/views/fileHistoryView.ts new file mode 100644 index 0000000..0c9701b --- /dev/null +++ b/src/views/fileHistoryView.ts @@ -0,0 +1,98 @@ +'use strict'; +import { commands, ConfigurationChangeEvent } from 'vscode'; +import { configuration, FileHistoryViewConfig, ViewsConfig } from '../configuration'; +import { CommandContext, setCommandContext } from '../constants'; +import { Container } from '../container'; +import { FileHistoryTrackerNode, ViewNode } from './nodes'; +import { RefreshReason, ViewBase } from './viewBase'; +import { RefreshNodeCommandArgs } from './viewCommands'; + +export class FileHistoryView extends ViewBase { + constructor() { + super('gitlens.views.fileHistory'); + } + + getRoot() { + return new FileHistoryTrackerNode(this); + } + + protected registerCommands() { + Container.viewCommands; + commands.registerCommand(this.getQualifiedCommand('refresh'), () => this.refresh(), this); + commands.registerCommand( + this.getQualifiedCommand('refreshNode'), + (node: ViewNode, args?: RefreshNodeCommandArgs) => this.refreshNode(node, args), + this + ); + + commands.registerCommand( + this.getQualifiedCommand('setEditorFollowingOn'), + () => this.setEditorFollowing(true), + this + ); + commands.registerCommand( + this.getQualifiedCommand('setEditorFollowingOff'), + () => this.setEditorFollowing(false), + this + ); + commands.registerCommand( + this.getQualifiedCommand('setRenameFollowingOn'), + () => this.setRenameFollowing(true), + this + ); + commands.registerCommand( + this.getQualifiedCommand('setRenameFollowingOff'), + () => this.setRenameFollowing(false), + this + ); + } + + protected onConfigurationChanged(e: ConfigurationChangeEvent) { + const initializing = configuration.initializing(e); + + if ( + !initializing && + !configuration.changed(e, configuration.name('views')('fileHistory').value) && + !configuration.changed(e, configuration.name('views').value) && + !configuration.changed(e, configuration.name('defaultGravatarsStyle').value) && + !configuration.changed(e, configuration.name('advanced')('fileHistoryFollowsRenames').value) + ) { + return; + } + + if ( + initializing || + configuration.changed(e, configuration.name('views')('fileHistory')('enabled').value) || + configuration.changed(e, configuration.name('views')('fileHistory')('location').value) + ) { + setCommandContext(CommandContext.ViewsFileHistory, this.config.enabled ? this.config.location : false); + setCommandContext(CommandContext.ViewsFileHistoryEditorFollowing, true); + } + + if (initializing || configuration.changed(e, configuration.name('views')('fileHistory')('location').value)) { + this.initialize(this.config.location); + } + + if (!initializing && this._root !== undefined) { + void this.refresh(RefreshReason.ConfigurationChanged); + } + } + + get config(): ViewsConfig & FileHistoryViewConfig { + return { ...Container.config.views, ...Container.config.views.fileHistory }; + } + + private setEditorFollowing(enabled: boolean) { + setCommandContext(CommandContext.ViewsFileHistoryEditorFollowing, enabled); + if (this._root !== undefined) { + this._root.setEditorFollowing(enabled); + } + } + + private setRenameFollowing(enabled: boolean) { + return configuration.updateEffective( + configuration.name('advanced')('fileHistoryFollowsRenames').value, + enabled + ); + } +} diff --git a/src/views/lineHistoryExplorer.ts b/src/views/lineHistoryExplorer.ts deleted file mode 100644 index e94eb99..0000000 --- a/src/views/lineHistoryExplorer.ts +++ /dev/null @@ -1,97 +0,0 @@ -'use strict'; -import { commands, ConfigurationChangeEvent } from 'vscode'; -import { configuration, ExplorersConfig, LineHistoryExplorerConfig } from '../configuration'; -import { CommandContext, setCommandContext } from '../constants'; -import { Container } from '../container'; -import { ExplorerBase, RefreshReason } from './explorer'; -import { RefreshNodeCommandArgs } from './explorerCommands'; -import { ExplorerNode, LineHistoryTrackerNode } from './nodes'; - -export class LineHistoryExplorer extends ExplorerBase { - constructor() { - super('gitlens.lineHistoryExplorer'); - } - - getRoot() { - return new LineHistoryTrackerNode(this); - } - - protected registerCommands() { - Container.explorerCommands; - commands.registerCommand(this.getQualifiedCommand('refresh'), () => this.refresh(), this); - commands.registerCommand( - this.getQualifiedCommand('refreshNode'), - (node: ExplorerNode, args?: RefreshNodeCommandArgs) => this.refreshNode(node, args), - this - ); - commands.registerCommand( - this.getQualifiedCommand('setEditorFollowingOn'), - () => this.setEditorFollowing(true), - this - ); - commands.registerCommand( - this.getQualifiedCommand('setEditorFollowingOff'), - () => this.setEditorFollowing(false), - this - ); - commands.registerCommand( - this.getQualifiedCommand('setRenameFollowingOn'), - () => this.setRenameFollowing(true), - this - ); - commands.registerCommand( - this.getQualifiedCommand('setRenameFollowingOff'), - () => this.setRenameFollowing(false), - this - ); - } - - protected onConfigurationChanged(e: ConfigurationChangeEvent) { - const initializing = configuration.initializing(e); - - if ( - !initializing && - !configuration.changed(e, configuration.name('lineHistoryExplorer').value) && - !configuration.changed(e, configuration.name('explorers').value) && - !configuration.changed(e, configuration.name('defaultGravatarsStyle').value) && - !configuration.changed(e, configuration.name('advanced')('fileHistoryFollowsRenames').value) - ) { - return; - } - - if ( - initializing || - configuration.changed(e, configuration.name('lineHistoryExplorer')('enabled').value) || - configuration.changed(e, configuration.name('lineHistoryExplorer')('location').value) - ) { - setCommandContext(CommandContext.LineHistoryExplorer, this.config.enabled ? this.config.location : false); - setCommandContext(CommandContext.LineHistoryExplorerEditorFollowing, true); - } - - if (initializing || configuration.changed(e, configuration.name('lineHistoryExplorer')('location').value)) { - this.initialize(this.config.location); - } - - if (!initializing && this._root !== undefined) { - void this.refresh(RefreshReason.ConfigurationChanged); - } - } - - get config(): ExplorersConfig & LineHistoryExplorerConfig { - return { ...Container.config.explorers, ...Container.config.lineHistoryExplorer }; - } - - private setEditorFollowing(enabled: boolean) { - setCommandContext(CommandContext.LineHistoryExplorerEditorFollowing, enabled); - if (this._root !== undefined) { - this._root.setEditorFollowing(enabled); - } - } - - private setRenameFollowing(enabled: boolean) { - return configuration.updateEffective( - configuration.name('advanced')('fileHistoryFollowsRenames').value, - enabled - ); - } -} diff --git a/src/views/lineHistoryView.ts b/src/views/lineHistoryView.ts new file mode 100644 index 0000000..8e36ca4 --- /dev/null +++ b/src/views/lineHistoryView.ts @@ -0,0 +1,97 @@ +'use strict'; +import { commands, ConfigurationChangeEvent } from 'vscode'; +import { configuration, LineHistoryViewConfig, ViewsConfig } from '../configuration'; +import { CommandContext, setCommandContext } from '../constants'; +import { Container } from '../container'; +import { LineHistoryTrackerNode, ViewNode } from './nodes'; +import { RefreshReason, ViewBase } from './viewBase'; +import { RefreshNodeCommandArgs } from './viewCommands'; + +export class LineHistoryView extends ViewBase { + constructor() { + super('gitlens.views.lineHistory'); + } + + getRoot() { + return new LineHistoryTrackerNode(this); + } + + protected registerCommands() { + Container.viewCommands; + commands.registerCommand(this.getQualifiedCommand('refresh'), () => this.refresh(), this); + commands.registerCommand( + this.getQualifiedCommand('refreshNode'), + (node: ViewNode, args?: RefreshNodeCommandArgs) => this.refreshNode(node, args), + this + ); + commands.registerCommand( + this.getQualifiedCommand('setEditorFollowingOn'), + () => this.setEditorFollowing(true), + this + ); + commands.registerCommand( + this.getQualifiedCommand('setEditorFollowingOff'), + () => this.setEditorFollowing(false), + this + ); + commands.registerCommand( + this.getQualifiedCommand('setRenameFollowingOn'), + () => this.setRenameFollowing(true), + this + ); + commands.registerCommand( + this.getQualifiedCommand('setRenameFollowingOff'), + () => this.setRenameFollowing(false), + this + ); + } + + protected onConfigurationChanged(e: ConfigurationChangeEvent) { + const initializing = configuration.initializing(e); + + if ( + !initializing && + !configuration.changed(e, configuration.name('views')('lineHistory').value) && + !configuration.changed(e, configuration.name('views').value) && + !configuration.changed(e, configuration.name('defaultGravatarsStyle').value) && + !configuration.changed(e, configuration.name('advanced')('fileHistoryFollowsRenames').value) + ) { + return; + } + + if ( + initializing || + configuration.changed(e, configuration.name('views')('lineHistory')('enabled').value) || + configuration.changed(e, configuration.name('views')('lineHistory')('location').value) + ) { + setCommandContext(CommandContext.ViewsLineHistory, this.config.enabled ? this.config.location : false); + setCommandContext(CommandContext.ViewsLineHistoryEditorFollowing, true); + } + + if (initializing || configuration.changed(e, configuration.name('views')('lineHistory')('location').value)) { + this.initialize(this.config.location); + } + + if (!initializing && this._root !== undefined) { + void this.refresh(RefreshReason.ConfigurationChanged); + } + } + + get config(): ViewsConfig & LineHistoryViewConfig { + return { ...Container.config.views, ...Container.config.views.lineHistory }; + } + + private setEditorFollowing(enabled: boolean) { + setCommandContext(CommandContext.ViewsLineHistoryEditorFollowing, enabled); + if (this._root !== undefined) { + this._root.setEditorFollowing(enabled); + } + } + + private setRenameFollowing(enabled: boolean) { + return configuration.updateEffective( + configuration.name('advanced')('fileHistoryFollowsRenames').value, + enabled + ); + } +} diff --git a/src/views/nodes.ts b/src/views/nodes.ts index 702f93f..4de4d64 100644 --- a/src/views/nodes.ts +++ b/src/views/nodes.ts @@ -1,6 +1,6 @@ 'use strict'; -export * from './nodes/explorerNode'; +export * from './nodes/viewNode'; export * from './nodes/branchesNode'; export * from './nodes/branchNode'; export * from './nodes/commitFileNode'; diff --git a/src/views/nodes/branchNode.ts b/src/views/nodes/branchNode.ts index 66c85bc..f9a5582 100644 --- a/src/views/nodes/branchNode.ts +++ b/src/views/nodes/branchNode.ts @@ -1,27 +1,27 @@ 'use strict'; import { TreeItem, TreeItemCollapsibleState } from 'vscode'; -import { ExplorerBranchesLayout } from '../../configuration'; +import { ViewBranchesLayout } from '../../configuration'; import { GlyphChars } from '../../constants'; import { Container } from '../../container'; import { GitBranch, GitUri } from '../../git/gitService'; import { Arrays, Iterables } from '../../system'; -import { RepositoriesExplorer } from '../repositoriesExplorer'; +import { RepositoriesView } from '../repositoriesView'; import { CommitNode } from './commitNode'; import { MessageNode, ShowMoreNode } from './common'; -import { ExplorerNode, ExplorerRefNode, PageableExplorerNode, ResourceType } from './explorerNode'; import { insertDateMarkers } from './helpers'; +import { PageableViewNode, ResourceType, ViewNode, ViewRefNode } from './viewNode'; -export class BranchNode extends ExplorerRefNode implements PageableExplorerNode { +export class BranchNode extends ViewRefNode implements PageableViewNode { readonly supportsPaging: boolean = true; maxCount: number | undefined; - private _children: ExplorerNode[] | undefined; + private _children: ViewNode[] | undefined; constructor( public readonly branch: GitBranch, uri: GitUri, - parent: ExplorerNode, - public readonly explorer: RepositoriesExplorer, + parent: ViewNode, + public readonly view: RepositoriesView, private readonly _markCurrent: boolean = true ) { super(uri, parent); @@ -39,7 +39,7 @@ export class BranchNode extends ExplorerRefNode implements PageableExplorerNode get label(): string { const branchName = this.branch.getName(); - if (this.explorer.config.branches.layout === ExplorerBranchesLayout.List) return branchName; + if (this.view.config.branches.layout === ViewBranchesLayout.List) return branchName; return this.current || GitBranch.isDetached(branchName) ? branchName : this.branch.getBasename(); } @@ -48,10 +48,10 @@ export class BranchNode extends ExplorerRefNode implements PageableExplorerNode return this.branch.ref; } - async getChildren(): Promise { + async getChildren(): Promise { if (this._children === undefined) { const log = await Container.git.getLog(this.uri.repoPath!, { - maxCount: this.maxCount || this.explorer.config.defaultItemLimit, + maxCount: this.maxCount || this.view.config.defaultItemLimit, ref: this.ref }); if (log === undefined) return [new MessageNode(this, 'No commits yet')]; @@ -75,14 +75,14 @@ export class BranchNode extends ExplorerRefNode implements PageableExplorerNode ...insertDateMarkers( Iterables.map( log.commits.values(), - c => new CommitNode(c, this, this.explorer, this.branch, getBranchTips) + c => new CommitNode(c, this, this.view, this.branch, getBranchTips) ), this ) ]; if (log.truncated) { - children.push(new ShowMoreNode('Commits', this, this.explorer)); + children.push(new ShowMoreNode('Commits', this, this.view)); } this._children = children; @@ -96,7 +96,7 @@ export class BranchNode extends ExplorerRefNode implements PageableExplorerNode let iconSuffix = ''; if (!this.branch.remote && this.branch.tracking !== undefined) { - if (this.explorer.config.showTrackingBranch) { + if (this.view.config.showTrackingBranch) { name += `${this.branch.getTrackingStatus({ prefix: `${GlyphChars.Space} ` })}${GlyphChars.Space} ${ GlyphChars.ArrowLeftRightLong }${GlyphChars.Space} ${this.branch.tracking}`; diff --git a/src/views/nodes/branchOrTagFolderNode.ts b/src/views/nodes/branchOrTagFolderNode.ts index 980ebf0..3761bc8 100644 --- a/src/views/nodes/branchOrTagFolderNode.ts +++ b/src/views/nodes/branchOrTagFolderNode.ts @@ -2,20 +2,20 @@ import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode'; import { GitUri } from '../../git/gitService'; import { Arrays, Objects } from '../../system'; -import { Explorer } from '../explorer'; +import { View } from '../viewBase'; import { BranchNode } from './branchNode'; -import { ExplorerNode, ResourceType } from './explorerNode'; import { TagNode } from './tagNode'; +import { ResourceType, ViewNode } from './viewNode'; -export class BranchOrTagFolderNode extends ExplorerNode { +export class BranchOrTagFolderNode extends ViewNode { constructor( public readonly type: 'branch' | 'remote-branch' | 'tag', public readonly repoPath: string, public readonly folderName: string, public readonly relativePath: string | undefined, public readonly root: Arrays.IHierarchicalItem, - parent: ExplorerNode, - public readonly explorer: Explorer, + parent: ViewNode, + public readonly view: View, private readonly _expanded: boolean = false ) { super(GitUri.fromRepoPath(repoPath), parent); @@ -25,7 +25,7 @@ export class BranchOrTagFolderNode extends ExplorerNode { return `gitlens:repository(${this.repoPath}):${this.type}-folder(${this.folderName})`; } - async getChildren(): Promise { + async getChildren(): Promise { if (this.root.descendants === undefined || this.root.children === undefined) return []; const children: (BranchOrTagFolderNode | BranchNode | TagNode)[] = []; @@ -44,7 +44,7 @@ export class BranchOrTagFolderNode extends ExplorerNode { folder.relativePath, folder, this, - this.explorer, + this.view, expanded ) ); diff --git a/src/views/nodes/branchesNode.ts b/src/views/nodes/branchesNode.ts index bfe434d..3e3aca3 100644 --- a/src/views/nodes/branchesNode.ts +++ b/src/views/nodes/branchesNode.ts @@ -1,22 +1,22 @@ 'use strict'; import { TreeItem, TreeItemCollapsibleState } from 'vscode'; -import { ExplorerBranchesLayout } from '../../configuration'; +import { ViewBranchesLayout } from '../../configuration'; import { Container } from '../../container'; import { GitUri, Repository } from '../../git/gitService'; import { Arrays, Iterables } from '../../system'; -import { RepositoriesExplorer } from '../repositoriesExplorer'; +import { RepositoriesView } from '../repositoriesView'; import { BranchNode } from './branchNode'; import { BranchOrTagFolderNode } from './branchOrTagFolderNode'; -import { ExplorerNode, ResourceType } from './explorerNode'; +import { ResourceType, ViewNode } from './viewNode'; -export class BranchesNode extends ExplorerNode { - private _children: ExplorerNode[] | undefined; +export class BranchesNode extends ViewNode { + private _children: ViewNode[] | undefined; constructor( uri: GitUri, public readonly repo: Repository, - parent: ExplorerNode, - public readonly explorer: RepositoriesExplorer + parent: ViewNode, + public readonly view: RepositoriesView ) { super(uri, parent); } @@ -25,7 +25,7 @@ export class BranchesNode extends ExplorerNode { return `gitlens:repository(${this.repo.path}):branches`; } - async getChildren(): Promise { + async getChildren(): Promise { if (this._children === undefined) { const branches = await this.repo.getBranches(); if (branches === undefined) return []; @@ -36,27 +36,19 @@ export class BranchesNode extends ExplorerNode { const branchNodes = [ ...Iterables.filterMap( branches, - b => (b.remote ? undefined : new BranchNode(b, this.uri, this, this.explorer)) + b => (b.remote ? undefined : new BranchNode(b, this.uri, this, this.view)) ) ]; - if (this.explorer.config.branches.layout === ExplorerBranchesLayout.List) return branchNodes; + if (this.view.config.branches.layout === ViewBranchesLayout.List) return branchNodes; const hierarchy = Arrays.makeHierarchical( branchNodes, n => (n.branch.detached ? [n.branch.name] : n.branch.getName().split('/')), (...paths: string[]) => paths.join('/'), - this.explorer.config.files.compact + this.view.config.files.compact ); - const root = new BranchOrTagFolderNode( - 'branch', - this.repo.path, - '', - undefined, - hierarchy, - this, - this.explorer - ); + const root = new BranchOrTagFolderNode('branch', this.repo.path, '', undefined, hierarchy, this, this.view); this._children = await root.getChildren(); } return this._children; diff --git a/src/views/nodes/commitFileNode.ts b/src/views/nodes/commitFileNode.ts index 9342594..c7e4ec5 100644 --- a/src/views/nodes/commitFileNode.ts +++ b/src/views/nodes/commitFileNode.ts @@ -13,8 +13,8 @@ import { IStatusFormatOptions, StatusFileFormatter } from '../../git/gitService'; -import { Explorer } from '../explorer'; -import { ExplorerNode, ExplorerRefNode, ResourceType } from './explorerNode'; +import { View } from '../viewBase'; +import { ResourceType, ViewNode, ViewRefNode } from './viewNode'; export enum CommitFileNodeDisplayAs { CommitLabel = 1 << 0, @@ -27,12 +27,12 @@ export enum CommitFileNodeDisplayAs { File = FileLabel | StatusIcon } -export class CommitFileNode extends ExplorerRefNode { +export class CommitFileNode extends ViewRefNode { constructor( public readonly file: GitFile, public commit: GitLogCommit, - parent: ExplorerNode, - public readonly explorer: Explorer, + parent: ViewNode, + public readonly view: View, private readonly _displayAs: CommitFileNodeDisplayAs, private readonly _selection?: Selection ) { @@ -47,7 +47,7 @@ export class CommitFileNode extends ExplorerRefNode { return this.commit.sha; } - async getChildren(): Promise { + async getChildren(): Promise { return []; } @@ -161,11 +161,11 @@ export class CommitFileNode extends ExplorerRefNode { } protected getCommitTemplate() { - return this.explorer.config.commitFormat; + return this.view.config.commitFormat; } protected getCommitFileTemplate() { - return this.explorer.config.commitFileFormat; + return this.view.config.commitFileFormat; } getCommand(): Command | undefined { diff --git a/src/views/nodes/commitNode.ts b/src/views/nodes/commitNode.ts index d8faf7e..8a00d21 100644 --- a/src/views/nodes/commitNode.ts +++ b/src/views/nodes/commitNode.ts @@ -2,21 +2,21 @@ import * as path from 'path'; import { Command, TreeItem, TreeItemCollapsibleState } from 'vscode'; import { Commands, DiffWithPreviousCommandArgs } from '../../commands'; -import { ExplorerFilesLayout } from '../../configuration'; +import { ViewFilesLayout } from '../../configuration'; import { GlyphChars } from '../../constants'; import { Container } from '../../container'; import { CommitFormatter, GitBranch, GitLogCommit, ICommitFormatOptions } from '../../git/gitService'; import { Arrays, Iterables, Strings } from '../../system'; -import { Explorer } from '../explorer'; +import { View } from '../viewBase'; import { CommitFileNode, CommitFileNodeDisplayAs } from './commitFileNode'; -import { ExplorerNode, ExplorerRefNode, ResourceType } from './explorerNode'; -import { FileExplorerNode, FolderNode } from './folderNode'; +import { FileNode, FolderNode } from './folderNode'; +import { ResourceType, ViewNode, ViewRefNode } from './viewNode'; -export class CommitNode extends ExplorerRefNode { +export class CommitNode extends ViewRefNode { constructor( public readonly commit: GitLogCommit, - parent: ExplorerNode, - public readonly explorer: Explorer, + parent: ViewNode, + public readonly view: View, public readonly branch?: GitBranch, private readonly getBranchTips?: (sha: string) => string | undefined ) { @@ -27,25 +27,25 @@ export class CommitNode extends ExplorerRefNode { return this.commit.sha; } - async getChildren(): Promise { + async getChildren(): Promise { const commit = this.commit; - let children: FileExplorerNode[] = [ + let children: FileNode[] = [ ...Iterables.map( commit.files, - s => new CommitFileNode(s, commit.toFileCommit(s), this, this.explorer, CommitFileNodeDisplayAs.File) + s => new CommitFileNode(s, commit.toFileCommit(s), this, this.view, CommitFileNodeDisplayAs.File) ) ]; - if (this.explorer.config.files.layout !== ExplorerFilesLayout.List) { + if (this.view.config.files.layout !== ViewFilesLayout.List) { const hierarchy = Arrays.makeHierarchical( children, n => n.uri.getRelativePath().split('/'), (...paths: string[]) => Strings.normalizePath(path.join(...paths)), - this.explorer.config.files.compact + this.view.config.files.compact ); - const root = new FolderNode(this.repoPath, '', undefined, hierarchy, this, this.explorer); - children = (await root.getChildren()) as FileExplorerNode[]; + const root = new FolderNode(this.repoPath, '', undefined, hierarchy, this, this.view); + children = (await root.getChildren()) as FileNode[]; } else { children.sort((a, b) => a.label!.localeCompare(b.label!)); @@ -54,7 +54,7 @@ export class CommitNode extends ExplorerRefNode { } getTreeItem(): TreeItem { - let label = CommitFormatter.fromTemplate(this.explorer.config.commitFormat, this.commit, { + let label = CommitFormatter.fromTemplate(this.view.config.commitFormat, this.commit, { truncateMessageAtNewLine: true, dateFormat: Container.config.defaultDateFormat } as ICommitFormatOptions); @@ -71,7 +71,7 @@ export class CommitNode extends ExplorerRefNode { item.contextValue = this.branch === undefined || this.branch.current ? ResourceType.CommitOnCurrentBranch : ResourceType.Commit; - if (this.explorer.config.avatars) { + if (this.view.config.avatars) { item.iconPath = this.commit.getGravatarUri(Container.config.defaultGravatarsStyle); } else { diff --git a/src/views/nodes/common.ts b/src/views/nodes/common.ts index 7a5dd78..aa1e888 100644 --- a/src/views/nodes/common.ts +++ b/src/views/nodes/common.ts @@ -1,13 +1,13 @@ import { Command, ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri } from 'vscode'; import { GlyphChars } from '../../constants'; import { Container } from '../../container'; -import { Explorer } from '../explorer'; -import { RefreshNodeCommandArgs } from '../explorerCommands'; -import { ExplorerNode, ResourceType, unknownGitUri } from '../nodes/explorerNode'; +import { View } from '../viewBase'; +import { RefreshNodeCommandArgs } from '../viewCommands'; +import { ResourceType, unknownGitUri, ViewNode } from './viewNode'; -export class MessageNode extends ExplorerNode { +export class MessageNode extends ViewNode { constructor( - parent: ExplorerNode, + parent: ViewNode, private readonly _message: string, private readonly _tooltip?: string, private readonly _iconPath?: @@ -22,7 +22,7 @@ export class MessageNode extends ExplorerNode { super(unknownGitUri, parent); } - getChildren(): ExplorerNode[] | Promise { + getChildren(): ViewNode[] | Promise { return []; } @@ -37,7 +37,7 @@ export class MessageNode extends ExplorerNode { export class CommandMessageNode extends MessageNode { constructor( - parent: ExplorerNode, + parent: ViewNode, private readonly _command: Command, message: string, tooltip?: string, @@ -67,9 +67,9 @@ export class CommandMessageNode extends MessageNode { } } -export class UpdateableMessageNode extends ExplorerNode { +export class UpdateableMessageNode extends ViewNode { constructor( - parent: ExplorerNode, + parent: ViewNode, public readonly id: string, private _message: string, private _tooltip?: string, @@ -85,7 +85,7 @@ export class UpdateableMessageNode extends ExplorerNode { super(unknownGitUri, parent); } - getChildren(): ExplorerNode[] | Promise { + getChildren(): ViewNode[] | Promise { return []; } @@ -112,7 +112,7 @@ export class UpdateableMessageNode extends ExplorerNode { } | ThemeIcon; }, - explorer: Explorer + view: View ) { if (changes.message !== undefined) { this._message = changes.message; @@ -126,22 +126,22 @@ export class UpdateableMessageNode extends ExplorerNode { this._iconPath = changes.iconPath === null ? undefined : changes.iconPath; } - explorer.triggerNodeUpdate(this); + view.triggerNodeUpdate(this); } } -export abstract class PagerNode extends ExplorerNode { +export abstract class PagerNode extends ViewNode { protected _args: RefreshNodeCommandArgs = {}; constructor( protected readonly message: string, - protected readonly parent: ExplorerNode, - protected readonly explorer: Explorer + protected readonly parent: ViewNode, + protected readonly view: View ) { super(unknownGitUri, parent); } - getChildren(): ExplorerNode[] | Promise { + getChildren(): ViewNode[] | Promise { return []; } @@ -159,25 +159,20 @@ export abstract class PagerNode extends ExplorerNode { getCommand(): Command | undefined { return { title: 'Refresh', - command: this.explorer.getQualifiedCommand('refreshNode'), + command: this.view.getQualifiedCommand('refreshNode'), arguments: [this.parent, this._args] } as Command; } } export class ShowMoreNode extends PagerNode { - constructor( - type: string, - parent: ExplorerNode, - explorer: Explorer, - maxCount: number = Container.config.advanced.maxListItems - ) { + constructor(type: string, parent: ViewNode, view: View, maxCount: number = Container.config.advanced.maxListItems) { super( maxCount === 0 ? `Show All ${type} ${GlyphChars.Space}${GlyphChars.Dash}${GlyphChars.Space} this may take a while` : `Show More ${type}`, parent, - explorer + view ); this._args.maxCount = maxCount; } diff --git a/src/views/nodes/explorerNode.ts b/src/views/nodes/explorerNode.ts deleted file mode 100644 index 9afa5f8..0000000 --- a/src/views/nodes/explorerNode.ts +++ /dev/null @@ -1,185 +0,0 @@ -'use strict'; -import { Command, Disposable, Event, TreeItem, TreeViewVisibilityChangeEvent } from 'vscode'; -import { GitUri } from '../../git/gitService'; -import { Explorer, RefreshReason } from '../explorer'; - -export enum ResourceType { - ActiveFileHistory = 'gitlens:active:history-file', - ActiveLineHistory = 'gitlens:active:history-line', - Branch = 'gitlens:branch', - BranchWithTracking = 'gitlens:branch:tracking', - Branches = 'gitlens:branches', - BranchesWithRemotes = 'gitlens:branches:remotes', - CurrentBranch = 'gitlens:branch:current', - CurrentBranchWithTracking = 'gitlens:branch:current:tracking', - RemoteBranch = 'gitlens:branch:remote', - Commit = 'gitlens:commit', - CommitOnCurrentBranch = 'gitlens:commit:current', - CommitFile = 'gitlens:file:commit', - Commits = 'gitlens:commits', - ComparisonResults = 'gitlens:results:comparison', - FileHistory = 'gitlens:history-file', - FileStaged = 'gitlens:file:staged', - FileStagedAndUnstaged = 'gitlens:file:staged:unstaged', - FileUnstaged = 'gitlens:file:unstaged', - Folder = 'gitlens:folder', - Message = 'gitlens:message', - Pager = 'gitlens:pager', - Remote = 'gitlens:remote', - Remotes = 'gitlens:remotes', - Repositories = 'gitlens:repositories', - Repository = 'gitlens:repository', - Results = 'gitlens:results', - ResultsCommits = 'gitlens:results:commits', - ResultsFile = 'gitlens:file:results', - ResultsFiles = 'gitlens:results:files', - SearchResults = 'gitlens:results:search', - Stash = 'gitlens:stash', - StashFile = 'gitlens:file:stash', - Stashes = 'gitlens:stashes', - StatusFileCommits = 'gitlens:status:file:commits', - StatusFiles = 'gitlens:status:files', - StatusUpstream = 'gitlens:status:upstream', - Tag = 'gitlens:tag', - Tags = 'gitlens:tags' -} - -export interface NamedRef { - label?: string; - ref: string; -} - -export const unknownGitUri = new GitUri(); - -export abstract class ExplorerNode { - constructor( - uri: GitUri, - private readonly _parent: ExplorerNode | undefined - ) { - this._uri = uri; - } - - protected _uri: GitUri; - get uri() { - return this._uri; - } - - abstract getChildren(): ExplorerNode[] | Promise; - getParent(): ExplorerNode | undefined { - return this._parent; - } - abstract getTreeItem(): TreeItem | Promise; - - getCommand(): Command | undefined { - return undefined; - } - - refresh(reason?: RefreshReason): void | boolean | Promise | Promise {} -} - -export abstract class ExplorerRefNode extends ExplorerNode { - abstract get ref(): string; - - get repoPath(): string { - return this.uri.repoPath!; - } -} - -export interface PageableExplorerNode { - readonly supportsPaging: boolean; - maxCount: number | undefined; -} - -export function isPageable( - node: ExplorerNode -): node is ExplorerNode & { supportsPaging: boolean; maxCount: number | undefined } { - return Boolean((node as any).supportsPaging); -} - -export function supportsAutoRefresh( - explorer: Explorer -): explorer is Explorer & { autoRefresh: boolean; onDidChangeAutoRefresh: Event } { - return (explorer as any).onDidChangeAutoRefresh !== undefined; -} - -export abstract class SubscribeableExplorerNode extends ExplorerNode { - protected _disposable: Disposable; - protected _subscription: Disposable | undefined; - - constructor( - uri: GitUri, - parent: ExplorerNode | undefined, - public readonly explorer: TExplorer - ) { - super(uri, parent); - - const disposables = [this.explorer.onDidChangeVisibility(this.onVisibilityChanged, this)]; - - if (supportsAutoRefresh(this.explorer)) { - disposables.push(this.explorer.onDidChangeAutoRefresh(this.onAutoRefreshChanged, this)); - } - - this._disposable = Disposable.from(...disposables); - } - - dispose() { - this.unsubscribe(); - - if (this._disposable !== undefined) { - this._disposable.dispose(); - } - } - - private _canSubscribe: boolean = true; - protected get canSubscribe(): boolean { - return this._canSubscribe; - } - protected set canSubscribe(value: boolean) { - if (this._canSubscribe === value) return; - - this._canSubscribe = value; - - void this.ensureSubscription(); - if (value) { - void this.explorer.refreshNode(this); - } - } - - protected abstract async subscribe(): Promise; - protected unsubscribe(): void { - if (this._subscription !== undefined) { - this._subscription.dispose(); - this._subscription = undefined; - } - } - - protected onAutoRefreshChanged() { - this.onVisibilityChanged({ visible: this.explorer.visible }); - } - - protected onVisibilityChanged(e: TreeViewVisibilityChangeEvent) { - void this.ensureSubscription(); - - if (e.visible) { - void this.explorer.refreshNode(this); - } - } - - async ensureSubscription() { - // We only need to subscribe if we are visible and if auto-refresh enabled (when supported) - if ( - !this.canSubscribe || - !this.explorer.visible || - (supportsAutoRefresh(this.explorer) && !this.explorer.autoRefresh) - ) { - this.unsubscribe(); - - return; - } - - // If we already have a subscription, just kick out - if (this._subscription !== undefined) return; - - this._subscription = await this.subscribe(); - } -} diff --git a/src/views/nodes/fileHistoryNode.ts b/src/views/nodes/fileHistoryNode.ts index b6799b5..21f2f7e 100644 --- a/src/views/nodes/fileHistoryNode.ts +++ b/src/views/nodes/fileHistoryNode.ts @@ -12,23 +12,23 @@ import { } from '../../git/gitService'; import { Logger } from '../../logger'; import { Iterables } from '../../system'; -import { FileHistoryExplorer } from '../fileHistoryExplorer'; +import { FileHistoryView } from '../fileHistoryView'; import { CommitFileNode, CommitFileNodeDisplayAs } from './commitFileNode'; import { MessageNode } from './common'; -import { ExplorerNode, ResourceType, SubscribeableExplorerNode } from './explorerNode'; import { insertDateMarkers } from './helpers'; +import { ResourceType, SubscribeableViewNode, ViewNode } from './viewNode'; -export class FileHistoryNode extends SubscribeableExplorerNode { - constructor(uri: GitUri, parent: ExplorerNode, explorer: FileHistoryExplorer) { - super(uri, parent, explorer); +export class FileHistoryNode extends SubscribeableViewNode { + constructor(uri: GitUri, parent: ViewNode, view: FileHistoryView) { + super(uri, parent, view); } - async getChildren(): Promise { - const children: ExplorerNode[] = []; + async getChildren(): Promise { + const children: ViewNode[] = []; const displayAs = CommitFileNodeDisplayAs.CommitLabel | - (this.explorer.config.avatars ? CommitFileNodeDisplayAs.Gravatar : CommitFileNodeDisplayAs.StatusIcon); + (this.view.config.avatars ? CommitFileNodeDisplayAs.Gravatar : CommitFileNodeDisplayAs.StatusIcon); const status = await Container.git.getStatusForFile(this.uri.repoPath!, this.uri.fsPath); if (status !== undefined && (status.indexStatus !== undefined || status.workingTreeStatus !== undefined)) { @@ -65,7 +65,7 @@ export class FileHistoryNode extends SubscribeableExplorerNode new CommitFileNode(c.files[0], c, this, this.explorer, displayAs) + c => new CommitFileNode(c.files[0], c, this, this.view, displayAs) ), this ) @@ -120,7 +120,7 @@ export class FileHistoryNode extends SubscribeableExplorerNode { +export class FileHistoryTrackerNode extends SubscribeableViewNode { private _child: FileHistoryNode | undefined; - constructor(explorer: FileHistoryExplorer) { - super(unknownGitUri, undefined, explorer); + constructor(view: FileHistoryView) { + super(unknownGitUri, undefined, view); } dispose() { @@ -30,13 +30,13 @@ export class FileHistoryTrackerNode extends SubscribeableExplorerNode { + async getChildren(): Promise { if (this._child === undefined) { if (this.uri === unknownGitUri) { return [new MessageNode(this, 'There are no editors open that can provide file history')]; } - this._child = new FileHistoryNode(this.uri, this, this.explorer); + this._child = new FileHistoryNode(this.uri, this, this.view); } return [this._child]; @@ -113,6 +113,6 @@ export class FileHistoryTrackerNode extends SubscribeableExplorerNode; + root?: Arrays.IHierarchicalItem; } -export class FolderNode extends ExplorerNode { +export class FolderNode extends ViewNode { readonly priority: number = 1; constructor( public readonly repoPath: string, public readonly folderName: string, public readonly relativePath: string | undefined, - public readonly root: Arrays.IHierarchicalItem, - parent: ExplorerNode, - public readonly explorer: Explorer + public readonly root: Arrays.IHierarchicalItem, + parent: ViewNode, + public readonly view: View ) { super(GitUri.fromRepoPath(repoPath), parent); } - async getChildren(): Promise<(FolderNode | FileExplorerNode)[]> { + async getChildren(): Promise<(FolderNode | FileNode)[]> { if (this.root.descendants === undefined || this.root.children === undefined) return []; - let children: (FolderNode | FileExplorerNode)[]; + let children: (FolderNode | FileNode)[]; const nesting = FolderNode.getFileNesting( - this.explorer.config.files, + this.view.config.files, this.root.descendants, this.relativePath === undefined ); - if (nesting !== ExplorerFilesLayout.List) { + if (nesting !== ViewFilesLayout.List) { children = []; for (const folder of Objects.values(this.root.children)) { if (folder.value === undefined) { children.push( - new FolderNode(this.repoPath, folder.name, folder.relativePath, folder, this, this.explorer) + new FolderNode(this.repoPath, folder.name, folder.relativePath, folder, this, this.view) ); continue; } @@ -81,18 +81,18 @@ export class FolderNode extends ExplorerNode { return this.folderName; } - static getFileNesting( - config: ExplorersFilesConfig, + static getFileNesting( + config: ViewsFilesConfig, children: T[], isRoot: boolean - ): ExplorerFilesLayout { - const nesting = config.layout || ExplorerFilesLayout.Auto; - if (nesting === ExplorerFilesLayout.Auto) { + ): ViewFilesLayout { + const nesting = config.layout || ViewFilesLayout.Auto; + if (nesting === ViewFilesLayout.Auto) { if (isRoot || config.compact) { const nestingThreshold = config.threshold || 5; - if (children.length <= nestingThreshold) return ExplorerFilesLayout.List; + if (children.length <= nestingThreshold) return ViewFilesLayout.List; } - return ExplorerFilesLayout.Tree; + return ViewFilesLayout.Tree; } return nesting; } diff --git a/src/views/nodes/helpers.ts b/src/views/nodes/helpers.ts index 8c410d3..bbc883d 100644 --- a/src/views/nodes/helpers.ts +++ b/src/views/nodes/helpers.ts @@ -1,7 +1,7 @@ 'use strict'; import { GitLogCommit } from '../../git/gitService'; import { MessageNode } from './common'; -import { ExplorerNode } from './explorerNode'; +import { ViewNode } from './viewNode'; const markers: [number, string][] = [ [0, 'Less than a week ago'], @@ -11,10 +11,10 @@ const markers: [number, string][] = [ ]; export function* insertDateMarkers( - iterable: Iterable, - parent: ExplorerNode, + iterable: Iterable, + parent: ViewNode, skip?: number -): Iterable { +): Iterable { let index = skip || 0; let time = undefined; const now = Date.now(); diff --git a/src/views/nodes/lineHistoryNode.ts b/src/views/nodes/lineHistoryNode.ts index 6fbb533..d66eec9 100644 --- a/src/views/nodes/lineHistoryNode.ts +++ b/src/views/nodes/lineHistoryNode.ts @@ -11,28 +11,28 @@ import { } from '../../git/gitService'; import { Logger } from '../../logger'; import { Iterables } from '../../system'; -import { LineHistoryExplorer } from '../lineHistoryExplorer'; +import { LineHistoryView } from '../lineHistoryView'; import { CommitFileNode, CommitFileNodeDisplayAs } from './commitFileNode'; import { MessageNode } from './common'; -import { ExplorerNode, ResourceType, SubscribeableExplorerNode } from './explorerNode'; import { insertDateMarkers } from './helpers'; +import { ResourceType, SubscribeableViewNode, ViewNode } from './viewNode'; -export class LineHistoryNode extends SubscribeableExplorerNode { +export class LineHistoryNode extends SubscribeableViewNode { constructor( uri: GitUri, public readonly selection: Selection, - parent: ExplorerNode, - explorer: LineHistoryExplorer + parent: ViewNode, + view: LineHistoryView ) { - super(uri, parent, explorer); + super(uri, parent, view); } - async getChildren(): Promise { - const children: ExplorerNode[] = []; + async getChildren(): Promise { + const children: ViewNode[] = []; const displayAs = CommitFileNodeDisplayAs.CommitLabel | - (this.explorer.config.avatars ? CommitFileNodeDisplayAs.Gravatar : CommitFileNodeDisplayAs.StatusIcon); + (this.view.config.avatars ? CommitFileNodeDisplayAs.Gravatar : CommitFileNodeDisplayAs.StatusIcon); const log = await Container.git.getLogForFile(this.uri.repoPath, this.uri.fsPath, { ref: this.uri.sha, @@ -43,7 +43,7 @@ export class LineHistoryNode extends SubscribeableExplorerNode new CommitFileNode(c.files[0], c, this, this.explorer, displayAs, this.selection) + c => new CommitFileNode(c.files[0], c, this, this.view, displayAs, this.selection) ), this ) @@ -85,7 +85,7 @@ export class LineHistoryNode extends SubscribeableExplorerNode { +export class LineHistoryTrackerNode extends SubscribeableViewNode { private _child: LineHistoryNode | undefined; private _selection: Selection | undefined; - constructor(explorer: LineHistoryExplorer) { - super(unknownGitUri, undefined, explorer); + constructor(view: LineHistoryView) { + super(unknownGitUri, undefined, view); } dispose() { @@ -31,13 +31,13 @@ export class LineHistoryTrackerNode extends SubscribeableExplorerNode { + async getChildren(): Promise { if (this._child === undefined) { if (this.uri === unknownGitUri) { return [new MessageNode(this, 'There are no editors open that can provide line history')]; } - this._child = new LineHistoryNode(this.uri, this._selection!, this, this.explorer); + this._child = new LineHistoryNode(this.uri, this._selection!, this, this.view); } return [this._child]; @@ -116,6 +116,6 @@ export class LineHistoryTrackerNode extends SubscribeableExplorerNode { + async getChildren(): Promise { const branches = await this.repo.getBranches(); if (branches === undefined) return []; @@ -38,16 +38,16 @@ export class RemoteNode extends ExplorerNode { b => !b.remote || !b.name.startsWith(this.remote.name) ? undefined - : new BranchNode(b, this.uri, this, this.explorer) + : new BranchNode(b, this.uri, this, this.view) ) ]; - if (this.explorer.config.branches.layout === ExplorerBranchesLayout.List) return branchNodes; + if (this.view.config.branches.layout === ViewBranchesLayout.List) return branchNodes; const hierarchy = Arrays.makeHierarchical( branchNodes, n => (n.branch.detached ? [n.branch.name] : n.branch.getName().split('/')), (...paths: string[]) => paths.join('/'), - this.explorer.config.files.compact + this.view.config.files.compact ); const root = new BranchOrTagFolderNode( @@ -57,7 +57,7 @@ export class RemoteNode extends ExplorerNode { undefined, hierarchy, this, - this.explorer + this.view ); const children = (await root.getChildren()) as (BranchOrTagFolderNode | BranchNode)[]; diff --git a/src/views/nodes/remotesNode.ts b/src/views/nodes/remotesNode.ts index 1bf3b70..341977f 100644 --- a/src/views/nodes/remotesNode.ts +++ b/src/views/nodes/remotesNode.ts @@ -3,17 +3,17 @@ import { TreeItem, TreeItemCollapsibleState } from 'vscode'; import { Container } from '../../container'; import { GitUri, Repository } from '../../git/gitService'; import { Iterables } from '../../system'; -import { RepositoriesExplorer } from '../repositoriesExplorer'; +import { RepositoriesView } from '../repositoriesView'; import { MessageNode } from './common'; -import { ExplorerNode, ResourceType } from './explorerNode'; import { RemoteNode } from './remoteNode'; +import { ResourceType, ViewNode } from './viewNode'; -export class RemotesNode extends ExplorerNode { +export class RemotesNode extends ViewNode { constructor( uri: GitUri, public readonly repo: Repository, - parent: ExplorerNode, - public readonly explorer: RepositoriesExplorer + parent: ViewNode, + public readonly view: RepositoriesView ) { super(uri, parent); } @@ -22,12 +22,12 @@ export class RemotesNode extends ExplorerNode { return `gitlens:repository(${this.repo.path}):remotes`; } - async getChildren(): Promise { + async getChildren(): Promise { const remotes = await this.repo.getRemotes(); if (remotes === undefined || remotes.length === 0) return [new MessageNode(this, 'No remotes configured')]; remotes.sort((a, b) => a.name.localeCompare(b.name)); - return [...Iterables.map(remotes, r => new RemoteNode(r, this.uri, this.repo, this, this.explorer))]; + return [...Iterables.map(remotes, r => new RemoteNode(r, this.uri, this.repo, this, this.view))]; } getTreeItem(): TreeItem { diff --git a/src/views/nodes/repositoriesNode.ts b/src/views/nodes/repositoriesNode.ts index 37a6081..834686f 100644 --- a/src/views/nodes/repositoriesNode.ts +++ b/src/views/nodes/repositoriesNode.ts @@ -4,17 +4,17 @@ import { Container } from '../../container'; import { GitUri } from '../../git/gitService'; import { Logger } from '../../logger'; import { Functions } from '../../system'; -import { RefreshReason } from '../explorer'; -import { RepositoriesExplorer } from '../repositoriesExplorer'; +import { RepositoriesView } from '../repositoriesView'; +import { RefreshReason } from '../viewBase'; import { MessageNode } from './common'; -import { ExplorerNode, ResourceType, SubscribeableExplorerNode, unknownGitUri } from './explorerNode'; import { RepositoryNode } from './repositoryNode'; +import { ResourceType, SubscribeableViewNode, unknownGitUri, ViewNode } from './viewNode'; -export class RepositoriesNode extends SubscribeableExplorerNode { +export class RepositoriesNode extends SubscribeableViewNode { private _children: (RepositoryNode | MessageNode)[] | undefined; - constructor(explorer: RepositoriesExplorer) { - super(unknownGitUri, undefined, explorer); + constructor(view: RepositoriesView) { + super(unknownGitUri, undefined, view); } dispose() { @@ -30,7 +30,7 @@ export class RepositoriesNode extends SubscribeableExplorerNode { + async getChildren(): Promise { if (this._children === undefined) { const repositories = [...(await Container.git.getRepositories())]; if (repositories.length === 0) return [new MessageNode(this, 'No repositories found')]; @@ -39,7 +39,7 @@ export class RepositoriesNode extends SubscribeableExplorerNode a.index - b.index)) { if (repo.closed) continue; - children.push(new RepositoryNode(GitUri.fromRepoPath(repo.path), repo, this, this.explorer)); + children.push(new RepositoryNode(GitUri.fromRepoPath(repo.path), repo, this, this.view)); } this._children = children; @@ -133,7 +133,7 @@ export class RepositoriesNode extends SubscribeableExplorerNode { - private _children: ExplorerNode[] | undefined; +export class RepositoryNode extends SubscribeableViewNode { + private _children: ViewNode[] | undefined; private _lastFetched: number = 0; private _status: Promise; constructor( uri: GitUri, public readonly repo: Repository, - parent: ExplorerNode, - explorer: RepositoriesExplorer + parent: ViewNode, + view: RepositoriesView ) { - super(uri, parent, explorer); + super(uri, parent, view); this._status = this.repo.getStatus(); } @@ -46,7 +46,7 @@ export class RepositoryNode extends SubscribeableExplorerNode { + async getChildren(): Promise { if (this._children === undefined) { const children = []; @@ -62,29 +62,29 @@ export class RepositoryNode extends SubscribeableExplorerNode c instanceof StashesNode); if (node !== undefined) { - void this.explorer.refreshNode(node); + void this.view.refreshNode(node); } } if (e.changed(RepositoryChange.Remotes)) { const node = this._children.find(c => c instanceof RemotesNode); if (node !== undefined) { - void this.explorer.refreshNode(node); + void this.view.refreshNode(node); } } if (e.changed(RepositoryChange.Tags)) { const node = this._children.find(c => c instanceof TagsNode); if (node !== undefined) { - void this.explorer.refreshNode(node); + void this.view.refreshNode(node); } } } @@ -332,6 +332,6 @@ export class RepositoryNode extends SubscribeableExplorerNode= Dates.MillisecondsPerDay) return; - this.explorer.triggerNodeUpdate(this); + this.view.triggerNodeUpdate(this); } } diff --git a/src/views/nodes/resultsCommitNode.ts b/src/views/nodes/resultsCommitNode.ts index 1843848..2e63d90 100644 --- a/src/views/nodes/resultsCommitNode.ts +++ b/src/views/nodes/resultsCommitNode.ts @@ -1,20 +1,20 @@ 'use strict'; import { TreeItem, TreeItemCollapsibleState } from 'vscode'; import { GitLogCommit } from '../../git/gitService'; -import { ResultsExplorer } from '../resultsExplorer'; +import { ResultsView } from '../resultsView'; import { CommitNode } from './commitNode'; -import { ExplorerNode, ResourceType } from './explorerNode'; +import { ResourceType, ViewNode } from './viewNode'; -export class ResultsCommitNode extends ExplorerNode { +export class ResultsCommitNode extends ViewNode { constructor( public readonly commit: GitLogCommit, - public readonly explorer: ResultsExplorer + public readonly view: ResultsView ) { super(commit.toGitUri(), undefined); } - getChildren(): ExplorerNode[] { - return [new CommitNode(this.commit, this, this.explorer)]; + getChildren(): ViewNode[] { + return [new CommitNode(this.commit, this, this.view)]; } getTreeItem(): TreeItem { diff --git a/src/views/nodes/resultsCommitsNode.ts b/src/views/nodes/resultsCommitsNode.ts index 74cfc48..cda49bd 100644 --- a/src/views/nodes/resultsCommitsNode.ts +++ b/src/views/nodes/resultsCommitsNode.ts @@ -2,40 +2,40 @@ import { TreeItem, TreeItemCollapsibleState } from 'vscode'; import { GitLog, GitUri } from '../../git/gitService'; import { Iterables } from '../../system'; -import { ResultsExplorer } from '../resultsExplorer'; +import { ResultsView } from '../resultsView'; import { CommitNode } from './commitNode'; import { ShowMoreNode } from './common'; -import { ExplorerNode, PageableExplorerNode, ResourceType } from './explorerNode'; +import { PageableViewNode, ResourceType, ViewNode } from './viewNode'; export interface CommitsQueryResults { label: string; log: GitLog | undefined; } -export class ResultsCommitsNode extends ExplorerNode implements PageableExplorerNode { +export class ResultsCommitsNode extends ViewNode implements PageableViewNode { readonly supportsPaging: boolean = true; maxCount: number | undefined; constructor( public readonly repoPath: string, private readonly _commitsQuery: (maxCount: number | undefined) => Promise, - parent: ExplorerNode | undefined, - public readonly explorer: ResultsExplorer, + parent: ViewNode | undefined, + public readonly view: ResultsView, private readonly _contextValue: ResourceType = ResourceType.ResultsCommits ) { super(GitUri.fromRepoPath(repoPath), parent); } - async getChildren(): Promise { + async getChildren(): Promise { const { log } = await this.getCommitsQueryResults(); if (log === undefined) return []; const children: (CommitNode | ShowMoreNode)[] = [ - ...Iterables.map(log.commits.values(), c => new CommitNode(c, this, this.explorer)) + ...Iterables.map(log.commits.values(), c => new CommitNode(c, this, this.view)) ]; if (log.truncated) { - children.push(new ShowMoreNode('Results', this, this.explorer)); + children.push(new ShowMoreNode('Results', this, this.view)); } return children; diff --git a/src/views/nodes/resultsComparisonNode.ts b/src/views/nodes/resultsComparisonNode.ts index d478163..baaa79d 100644 --- a/src/views/nodes/resultsComparisonNode.ts +++ b/src/views/nodes/resultsComparisonNode.ts @@ -4,17 +4,17 @@ import { GlyphChars } from '../../constants'; import { Container } from '../../container'; import { GitService, GitUri } from '../../git/gitService'; import { Strings } from '../../system'; -import { ResultsExplorer } from '../resultsExplorer'; -import { ExplorerNode, NamedRef, ResourceType } from './explorerNode'; +import { ResultsView } from '../resultsView'; import { CommitsQueryResults, ResultsCommitsNode } from './resultsCommitsNode'; import { ResultsFilesNode } from './resultsFilesNode'; +import { NamedRef, ResourceType, ViewNode } from './viewNode'; -export class ResultsComparisonNode extends ExplorerNode { +export class ResultsComparisonNode extends ViewNode { constructor( public readonly repoPath: string, ref1: NamedRef, ref2: NamedRef, - public readonly explorer: ResultsExplorer + public readonly view: ResultsView ) { super(GitUri.fromRepoPath(repoPath), undefined); @@ -32,10 +32,10 @@ export class ResultsComparisonNode extends ExplorerNode { return this._ref2; } - async getChildren(): Promise { + async getChildren(): Promise { return [ - new ResultsCommitsNode(this.uri.repoPath!, this.getCommitsQuery.bind(this), this, this.explorer), - new ResultsFilesNode(this.uri.repoPath!, this._ref1.ref, this._ref2.ref, this, this.explorer) + new ResultsCommitsNode(this.uri.repoPath!, this.getCommitsQuery.bind(this), this, this.view), + new ResultsFilesNode(this.uri.repoPath!, this._ref1.ref, this._ref2.ref, this, this.view) ]; } @@ -62,7 +62,7 @@ export class ResultsComparisonNode extends ExplorerNode { this._ref1 = this._ref2; this._ref2 = ref1; - this.explorer.triggerNodeUpdate(this); + this.view.triggerNodeUpdate(this); } private async getCommitsQuery(maxCount: number | undefined): Promise { diff --git a/src/views/nodes/resultsFileNode.ts b/src/views/nodes/resultsFileNode.ts index f71f272..6b13901 100644 --- a/src/views/nodes/resultsFileNode.ts +++ b/src/views/nodes/resultsFileNode.ts @@ -4,22 +4,22 @@ import { Command, TreeItem, TreeItemCollapsibleState } from 'vscode'; import { Commands, DiffWithCommandArgs } from '../../commands'; import { Container } from '../../container'; import { GitFile, GitUri, IStatusFormatOptions, StatusFileFormatter } from '../../git/gitService'; -import { Explorer } from '../explorer'; -import { ExplorerNode, ResourceType } from './explorerNode'; +import { View } from '../viewBase'; +import { ResourceType, ViewNode } from './viewNode'; -export class ResultsFileNode extends ExplorerNode { +export class ResultsFileNode extends ViewNode { constructor( public readonly repoPath: string, public readonly file: GitFile, public readonly ref1: string, public readonly ref2: string, - parent: ExplorerNode, - public readonly explorer: Explorer + parent: ViewNode, + public readonly view: View ) { super(GitUri.fromFile(file, repoPath, ref1 ? ref1 : ref2 ? ref2 : undefined), parent); } - getChildren(): ExplorerNode[] { + getChildren(): ViewNode[] { return []; } diff --git a/src/views/nodes/resultsFilesNode.ts b/src/views/nodes/resultsFilesNode.ts index 5d807d1..7f10239 100644 --- a/src/views/nodes/resultsFilesNode.ts +++ b/src/views/nodes/resultsFilesNode.ts @@ -1,52 +1,49 @@ 'use strict'; import * as path from 'path'; import { TreeItem, TreeItemCollapsibleState } from 'vscode'; -import { ExplorerFilesLayout } from '../../configuration'; +import { ViewFilesLayout } from '../../configuration'; import { Container } from '../../container'; import { GitFile, GitUri } from '../../git/gitService'; import { Arrays, Iterables, Strings } from '../../system'; -import { Explorer } from '../explorer'; -import { ExplorerNode, ResourceType } from './explorerNode'; -import { FileExplorerNode, FolderNode } from './folderNode'; +import { View } from '../viewBase'; +import { FileNode, FolderNode } from './folderNode'; import { ResultsFileNode } from './resultsFileNode'; +import { ResourceType, ViewNode } from './viewNode'; export interface FilesQueryResults { label: string; diff: GitFile[] | undefined; } -export class ResultsFilesNode extends ExplorerNode { +export class ResultsFilesNode extends ViewNode { constructor( public readonly repoPath: string, private readonly _ref1: string, private readonly _ref2: string, - parent: ExplorerNode, - public readonly explorer: Explorer + parent: ViewNode, + public readonly view: View ) { super(GitUri.fromRepoPath(repoPath), parent); } - async getChildren(): Promise { + async getChildren(): Promise { const { diff } = await this.getFilesQueryResults(); if (diff === undefined) return []; - let children: FileExplorerNode[] = [ - ...Iterables.map( - diff, - s => new ResultsFileNode(this.repoPath, s, this._ref1, this._ref2, this, this.explorer) - ) + let children: FileNode[] = [ + ...Iterables.map(diff, s => new ResultsFileNode(this.repoPath, s, this._ref1, this._ref2, this, this.view)) ]; - if (this.explorer.config.files.layout !== ExplorerFilesLayout.List) { + if (this.view.config.files.layout !== ViewFilesLayout.List) { const hierarchy = Arrays.makeHierarchical( children, n => n.uri.getRelativePath().split('/'), (...paths: string[]) => Strings.normalizePath(path.join(...paths)), - this.explorer.config.files.compact + this.view.config.files.compact ); - const root = new FolderNode(this.repoPath, '', undefined, hierarchy, this, this.explorer); - children = (await root.getChildren()) as FileExplorerNode[]; + const root = new FolderNode(this.repoPath, '', undefined, hierarchy, this, this.view); + children = (await root.getChildren()) as FileNode[]; } else { children.sort((a, b) => a.priority - b.priority || a.label!.localeCompare(b.label!)); diff --git a/src/views/nodes/resultsNode.ts b/src/views/nodes/resultsNode.ts index c300957..3e26e3f 100644 --- a/src/views/nodes/resultsNode.ts +++ b/src/views/nodes/resultsNode.ts @@ -4,20 +4,20 @@ import { ShowCommitSearchCommandArgs } from '../../commands'; import { GlyphChars } from '../../constants'; import { GitRepoSearchBy } from '../../git/gitService'; import { Strings } from '../../system'; -import { ResultsExplorer } from '../resultsExplorer'; +import { ResultsView } from '../resultsView'; import { CommandMessageNode, MessageNode } from './common'; -import { ExplorerNode, ResourceType, unknownGitUri } from './explorerNode'; +import { ResourceType, unknownGitUri, ViewNode } from './viewNode'; -export class ResultsNode extends ExplorerNode { - private _children: (ExplorerNode | MessageNode)[] = []; +export class ResultsNode extends ViewNode { + private _children: (ViewNode | MessageNode)[] = []; constructor( - public readonly explorer: ResultsExplorer + public readonly view: ResultsView ) { super(unknownGitUri, undefined); } - async getChildren(): Promise { + async getChildren(): Promise { if (this._children.length === 0) { const command = { title: 'Search Commits', @@ -100,7 +100,7 @@ export class ResultsNode extends ExplorerNode { return item; } - addOrReplace(results: ExplorerNode, replace: boolean) { + addOrReplace(results: ViewNode, replace: boolean) { if (this._children.includes(results)) return; if (this._children.length !== 0 && replace) { @@ -111,24 +111,24 @@ export class ResultsNode extends ExplorerNode { this._children.splice(0, 0, results); } - this.explorer.triggerNodeUpdate(); + this.view.triggerNodeUpdate(); } clear() { if (this._children.length === 0) return; this._children.length = 0; - this.explorer.triggerNodeUpdate(); + this.view.triggerNodeUpdate(); } - dismiss(node: ExplorerNode) { + dismiss(node: ViewNode) { if (this._children.length === 0) return; const index = this._children.findIndex(n => n === node); if (index === -1) return; this._children.splice(index, 1); - this.explorer.triggerNodeUpdate(); + this.view.triggerNodeUpdate(); } async refresh() { diff --git a/src/views/nodes/stashFileNode.ts b/src/views/nodes/stashFileNode.ts index e454b4c..55aa2d8 100644 --- a/src/views/nodes/stashFileNode.ts +++ b/src/views/nodes/stashFileNode.ts @@ -1,12 +1,12 @@ 'use strict'; import { GitFile, GitLogCommit } from '../../git/gitService'; -import { Explorer } from '../explorer'; +import { View } from '../viewBase'; import { CommitFileNode, CommitFileNodeDisplayAs } from './commitFileNode'; -import { ExplorerNode, ResourceType } from './explorerNode'; +import { ResourceType, ViewNode } from './viewNode'; export class StashFileNode extends CommitFileNode { - constructor(file: GitFile, commit: GitLogCommit, parent: ExplorerNode, explorer: Explorer) { - super(file, commit, parent, explorer, CommitFileNodeDisplayAs.File); + constructor(file: GitFile, commit: GitLogCommit, parent: ViewNode, view: View) { + super(file, commit, parent, view, CommitFileNodeDisplayAs.File); } protected get resourceType(): ResourceType { @@ -14,10 +14,10 @@ export class StashFileNode extends CommitFileNode { } protected getCommitTemplate() { - return this.explorer.config.stashFormat; + return this.view.config.stashFormat; } protected getCommitFileTemplate() { - return this.explorer.config.stashFileFormat; + return this.view.config.stashFileFormat; } } diff --git a/src/views/nodes/stashNode.ts b/src/views/nodes/stashNode.ts index 838a7c9..8a0df13 100644 --- a/src/views/nodes/stashNode.ts +++ b/src/views/nodes/stashNode.ts @@ -3,15 +3,15 @@ import { TreeItem, TreeItemCollapsibleState } from 'vscode'; import { Container } from '../../container'; import { CommitFormatter, GitStashCommit, ICommitFormatOptions } from '../../git/gitService'; import { Iterables } from '../../system'; -import { Explorer } from '../explorer'; -import { ExplorerNode, ExplorerRefNode, ResourceType } from './explorerNode'; +import { View } from '../viewBase'; import { StashFileNode } from './stashFileNode'; +import { ResourceType, ViewNode, ViewRefNode } from './viewNode'; -export class StashNode extends ExplorerRefNode { +export class StashNode extends ViewRefNode { constructor( public readonly commit: GitStashCommit, - parent: ExplorerNode, - public readonly explorer: Explorer + parent: ViewNode, + public readonly view: View ) { super(commit.toGitUri(), parent); } @@ -24,7 +24,7 @@ export class StashNode extends ExplorerRefNode { return this.commit.sha; } - async getChildren(): Promise { + async getChildren(): Promise { const files = (this.commit as GitStashCommit).files; // Check for any untracked files -- since git doesn't return them via `git stash list` :( @@ -41,14 +41,14 @@ export class StashNode extends ExplorerRefNode { } } - const children = files.map(s => new StashFileNode(s, this.commit.toFileCommit(s), this, this.explorer)); + const children = files.map(s => new StashFileNode(s, this.commit.toFileCommit(s), this, this.view)); children.sort((a, b) => a.label!.localeCompare(b.label!)); return children; } getTreeItem(): TreeItem { const item = new TreeItem( - CommitFormatter.fromTemplate(this.explorer.config.stashFormat, this.commit, { + CommitFormatter.fromTemplate(this.view.config.stashFormat, this.commit, { truncateMessageAtNewLine: true, dateFormat: Container.config.defaultDateFormat } as ICommitFormatOptions), diff --git a/src/views/nodes/stashesNode.ts b/src/views/nodes/stashesNode.ts index 18fbf25..976246a 100644 --- a/src/views/nodes/stashesNode.ts +++ b/src/views/nodes/stashesNode.ts @@ -3,17 +3,17 @@ import { TreeItem, TreeItemCollapsibleState } from 'vscode'; import { Container } from '../../container'; import { GitUri, Repository } from '../../git/gitService'; import { Iterables } from '../../system'; -import { Explorer } from '../explorer'; +import { View } from '../viewBase'; import { MessageNode } from './common'; -import { ExplorerNode, ResourceType } from './explorerNode'; import { StashNode } from './stashNode'; +import { ResourceType, ViewNode } from './viewNode'; -export class StashesNode extends ExplorerNode { +export class StashesNode extends ViewNode { constructor( uri: GitUri, public readonly repo: Repository, - parent: ExplorerNode, - public readonly explorer: Explorer + parent: ViewNode, + public readonly view: View ) { super(uri, parent); } @@ -22,11 +22,11 @@ export class StashesNode extends ExplorerNode { return `gitlens:repository(${this.repo.path}):stashes`; } - async getChildren(): Promise { + async getChildren(): Promise { const stash = await this.repo.getStashList(); if (stash === undefined) return [new MessageNode(this, 'No stashed changes')]; - return [...Iterables.map(stash.commits.values(), c => new StashNode(c, this, this.explorer))]; + return [...Iterables.map(stash.commits.values(), c => new StashNode(c, this, this.view))]; } getTreeItem(): TreeItem { diff --git a/src/views/nodes/statusFileNode.ts b/src/views/nodes/statusFileNode.ts index 5763ebd..b5b87d1 100644 --- a/src/views/nodes/statusFileNode.ts +++ b/src/views/nodes/statusFileNode.ts @@ -12,11 +12,11 @@ import { StatusFileFormatter } from '../../git/gitService'; import { Strings } from '../../system'; -import { Explorer } from '../explorer'; +import { View } from '../viewBase'; import { CommitFileNode, CommitFileNodeDisplayAs } from './commitFileNode'; -import { ExplorerNode, ResourceType } from './explorerNode'; +import { ResourceType, ViewNode } from './viewNode'; -export class StatusFileNode extends ExplorerNode { +export class StatusFileNode extends ViewNode { private readonly _hasStagedChanges: boolean = false; private readonly _hasUnstagedChanges: boolean = false; @@ -24,8 +24,8 @@ export class StatusFileNode extends ExplorerNode { public readonly repoPath: string, public readonly file: GitFile, public readonly commits: GitLogCommit[], - parent: ExplorerNode, - public readonly explorer: Explorer + parent: ViewNode, + public readonly view: View ) { super(GitUri.fromFile(file, repoPath, 'HEAD'), parent); @@ -41,16 +41,16 @@ export class StatusFileNode extends ExplorerNode { } } - async getChildren(): Promise { + async getChildren(): Promise { return this.commits.map( c => new CommitFileNode( this.file, c, this, - this.explorer, + this.view, CommitFileNodeDisplayAs.CommitLabel | - (this.explorer.config.avatars + (this.view.config.avatars ? CommitFileNodeDisplayAs.Gravatar : CommitFileNodeDisplayAs.CommitIcon) ) @@ -132,7 +132,7 @@ export class StatusFileNode extends ExplorerNode { get label() { if (this._label === undefined) { this._label = StatusFileFormatter.fromTemplate( - this.explorer.config.statusFileFormat, + this.view.config.statusFileFormat, { ...this.file, commit: this.commit diff --git a/src/views/nodes/statusFilesNode.ts b/src/views/nodes/statusFilesNode.ts index f6d8286..7e75e9f 100644 --- a/src/views/nodes/statusFilesNode.ts +++ b/src/views/nodes/statusFilesNode.ts @@ -1,7 +1,7 @@ 'use strict'; import * as path from 'path'; import { TreeItem, TreeItemCollapsibleState } from 'vscode'; -import { ExplorerFilesLayout } from '../../configuration'; +import { ViewFilesLayout } from '../../configuration'; import { Container } from '../../container'; import { GitStatusFile } from '../../git/git'; import { @@ -14,19 +14,19 @@ import { GitUri } from '../../git/gitService'; import { Arrays, Iterables, Objects, Strings } from '../../system'; -import { RepositoriesExplorer } from '../repositoriesExplorer'; -import { ExplorerNode, ResourceType } from './explorerNode'; -import { FileExplorerNode, FolderNode } from './folderNode'; +import { RepositoriesView } from '../repositoriesView'; +import { FileNode, FolderNode } from './folderNode'; import { StatusFileNode } from './statusFileNode'; +import { ResourceType, ViewNode } from './viewNode'; -export class StatusFilesNode extends ExplorerNode { +export class StatusFilesNode extends ViewNode { readonly repoPath: string; constructor( public readonly status: GitStatus, public readonly range: string | undefined, - parent: ExplorerNode, - public readonly explorer: RepositoriesExplorer + parent: ViewNode, + public readonly view: RepositoriesView ) { super(GitUri.fromRepoPath(status.repoPath), parent); this.repoPath = status.repoPath; @@ -36,7 +36,7 @@ export class StatusFilesNode extends ExplorerNode { return `gitlens:repository(${this.status.repoPath}):status:files`; } - async getChildren(): Promise { + async getChildren(): Promise { let files: GitFileWithCommit[] = []; const repoPath = this.repoPath; @@ -82,24 +82,24 @@ export class StatusFilesNode extends ExplorerNode { const groups = Arrays.groupBy(files, s => s.fileName); - let children: FileExplorerNode[] = [ + let children: FileNode[] = [ ...Iterables.map( Objects.values(groups), files => - new StatusFileNode(repoPath, files[files.length - 1], files.map(s => s.commit), this, this.explorer) + new StatusFileNode(repoPath, files[files.length - 1], files.map(s => s.commit), this, this.view) ) ]; - if (this.explorer.config.files.layout !== ExplorerFilesLayout.List) { + if (this.view.config.files.layout !== ViewFilesLayout.List) { const hierarchy = Arrays.makeHierarchical( children, n => n.uri.getRelativePath().split('/'), (...paths: string[]) => Strings.normalizePath(path.join(...paths)), - this.explorer.config.files.compact + this.view.config.files.compact ); - const root = new FolderNode(repoPath, '', undefined, hierarchy, this, this.explorer); - children = (await root.getChildren()) as FileExplorerNode[]; + const root = new FolderNode(repoPath, '', undefined, hierarchy, this, this.view); + children = (await root.getChildren()) as FileNode[]; } else { children.sort((a, b) => a.priority - b.priority || a.label!.localeCompare(b.label!)); @@ -147,7 +147,7 @@ export class StatusFilesNode extends ExplorerNode { } private get includeWorkingTree(): boolean { - return this.explorer.config.includeWorkingTree; + return this.view.config.includeWorkingTree; } private toStatusFile(file: GitStatusFile, ref: string, previousRef: string, date?: Date): GitFileWithCommit { diff --git a/src/views/nodes/statusUpstreamNode.ts b/src/views/nodes/statusUpstreamNode.ts index 8579694..afcc6d5 100644 --- a/src/views/nodes/statusUpstreamNode.ts +++ b/src/views/nodes/statusUpstreamNode.ts @@ -3,21 +3,21 @@ import { TreeItem, TreeItemCollapsibleState } from 'vscode'; import { Container } from '../../container'; import { GitStatus, GitUri } from '../../git/gitService'; import { Iterables, Strings } from '../../system'; -import { RepositoriesExplorer } from '../repositoriesExplorer'; +import { RepositoriesView } from '../repositoriesView'; import { CommitNode } from './commitNode'; import { ShowMoreNode } from './common'; -import { ExplorerNode, PageableExplorerNode, ResourceType } from './explorerNode'; import { insertDateMarkers } from './helpers'; +import { PageableViewNode, ResourceType, ViewNode } from './viewNode'; -export class StatusUpstreamNode extends ExplorerNode implements PageableExplorerNode { +export class StatusUpstreamNode extends ViewNode implements PageableViewNode { readonly supportsPaging: boolean = true; maxCount: number | undefined; constructor( public readonly status: GitStatus, public readonly direction: 'ahead' | 'behind', - parent: ExplorerNode, - public readonly explorer: RepositoriesExplorer + parent: ViewNode, + public readonly view: RepositoriesView ) { super(GitUri.fromRepoPath(status.repoPath), parent); } @@ -26,14 +26,14 @@ export class StatusUpstreamNode extends ExplorerNode implements PageableExplorer return `gitlens:repository(${this.status.repoPath}):status:upstream:${this.direction}`; } - async getChildren(): Promise { + async getChildren(): Promise { const ahead = this.direction === 'ahead'; const range = ahead ? `${this.status.upstream}..${this.status.ref}` : `${this.status.ref}..${this.status.upstream}`; const log = await Container.git.getLog(this.uri.repoPath!, { - maxCount: this.maxCount || this.explorer.config.defaultItemLimit, + maxCount: this.maxCount || this.view.config.defaultItemLimit, ref: range }); if (log === undefined) return []; @@ -50,12 +50,12 @@ export class StatusUpstreamNode extends ExplorerNode implements PageableExplorer } } - children = [...insertDateMarkers(commits.map(c => new CommitNode(c, this, this.explorer)), this, 1)]; + children = [...insertDateMarkers(commits.map(c => new CommitNode(c, this, this.view)), this, 1)]; } else { children = [ ...insertDateMarkers( - Iterables.map(log.commits.values(), c => new CommitNode(c, this, this.explorer)), + Iterables.map(log.commits.values(), c => new CommitNode(c, this, this.view)), this, 1 ) @@ -63,7 +63,7 @@ export class StatusUpstreamNode extends ExplorerNode implements PageableExplorer } if (log.truncated) { - children.push(new ShowMoreNode('Commits', this, this.explorer)); + children.push(new ShowMoreNode('Commits', this, this.view)); } return children; } diff --git a/src/views/nodes/tagNode.ts b/src/views/nodes/tagNode.ts index 86281c9..b45e36d 100644 --- a/src/views/nodes/tagNode.ts +++ b/src/views/nodes/tagNode.ts @@ -1,24 +1,24 @@ 'use strict'; import { TreeItem, TreeItemCollapsibleState } from 'vscode'; -import { ExplorerBranchesLayout } from '../../configuration'; +import { ViewBranchesLayout } from '../../configuration'; import { Container } from '../../container'; import { GitTag, GitUri } from '../../git/gitService'; import { Iterables } from '../../system'; -import { RepositoriesExplorer } from '../repositoriesExplorer'; +import { RepositoriesView } from '../repositoriesView'; import { CommitNode } from './commitNode'; import { MessageNode, ShowMoreNode } from './common'; -import { ExplorerNode, ExplorerRefNode, PageableExplorerNode, ResourceType } from './explorerNode'; import { insertDateMarkers } from './helpers'; +import { PageableViewNode, ResourceType, ViewNode, ViewRefNode } from './viewNode'; -export class TagNode extends ExplorerRefNode implements PageableExplorerNode { +export class TagNode extends ViewRefNode implements PageableViewNode { readonly supportsPaging: boolean = true; maxCount: number | undefined; constructor( public readonly tag: GitTag, uri: GitUri, - parent: ExplorerNode, - public readonly explorer: RepositoriesExplorer + parent: ViewNode, + public readonly view: RepositoriesView ) { super(uri, parent); } @@ -28,28 +28,26 @@ export class TagNode extends ExplorerRefNode implements PageableExplorerNode { } get label(): string { - return this.explorer.config.branches.layout === ExplorerBranchesLayout.Tree - ? this.tag.getBasename() - : this.tag.name; + return this.view.config.branches.layout === ViewBranchesLayout.Tree ? this.tag.getBasename() : this.tag.name; } get ref(): string { return this.tag.name; } - async getChildren(): Promise { + async getChildren(): Promise { const log = await Container.git.getLog(this.uri.repoPath!, { - maxCount: this.maxCount || this.explorer.config.defaultItemLimit, + maxCount: this.maxCount || this.view.config.defaultItemLimit, ref: this.tag.name }); if (log === undefined) return [new MessageNode(this, 'No commits yet')]; const children = [ - ...insertDateMarkers(Iterables.map(log.commits.values(), c => new CommitNode(c, this, this.explorer)), this) + ...insertDateMarkers(Iterables.map(log.commits.values(), c => new CommitNode(c, this, this.view)), this) ]; if (log.truncated) { - children.push(new ShowMoreNode('Commits', this, this.explorer)); + children.push(new ShowMoreNode('Commits', this, this.view)); } return children; } diff --git a/src/views/nodes/tagsNode.ts b/src/views/nodes/tagsNode.ts index 85c3422..7708ff8 100644 --- a/src/views/nodes/tagsNode.ts +++ b/src/views/nodes/tagsNode.ts @@ -1,21 +1,21 @@ 'use strict'; import { TreeItem, TreeItemCollapsibleState } from 'vscode'; -import { ExplorerBranchesLayout } from '../../configuration'; +import { ViewBranchesLayout } from '../../configuration'; import { Container } from '../../container'; import { GitUri, Repository } from '../../git/gitService'; import { Arrays } from '../../system'; -import { RepositoriesExplorer } from '../repositoriesExplorer'; +import { RepositoriesView } from '../repositoriesView'; import { BranchOrTagFolderNode } from './branchOrTagFolderNode'; import { MessageNode } from './common'; -import { ExplorerNode, ResourceType } from './explorerNode'; import { TagNode } from './tagNode'; +import { ResourceType, ViewNode } from './viewNode'; -export class TagsNode extends ExplorerNode { +export class TagsNode extends ViewNode { constructor( uri: GitUri, public readonly repo: Repository, - parent: ExplorerNode, - public readonly explorer: RepositoriesExplorer + parent: ViewNode, + public readonly view: RepositoriesView ) { super(uri, parent); } @@ -24,22 +24,22 @@ export class TagsNode extends ExplorerNode { return `gitlens:repository(${this.repo.path}):tags`; } - async getChildren(): Promise { + async getChildren(): Promise { const tags = await this.repo.getTags(); if (tags.length === 0) return [new MessageNode(this, 'No tags yet')]; tags.sort((a, b) => a.name.localeCompare(b.name)); - const tagNodes = [...tags.map(t => new TagNode(t, this.uri, this, this.explorer))]; - if (this.explorer.config.branches.layout === ExplorerBranchesLayout.List) return tagNodes; + const tagNodes = [...tags.map(t => new TagNode(t, this.uri, this, this.view))]; + if (this.view.config.branches.layout === ViewBranchesLayout.List) return tagNodes; const hierarchy = Arrays.makeHierarchical( tagNodes, n => n.tag.name.split('/'), (...paths: string[]) => paths.join('/'), - this.explorer.config.files.compact + this.view.config.files.compact ); - const root = new BranchOrTagFolderNode('tag', this.repo.path, '', undefined, hierarchy, this, this.explorer); + const root = new BranchOrTagFolderNode('tag', this.repo.path, '', undefined, hierarchy, this, this.view); const children = (await root.getChildren()) as (BranchOrTagFolderNode | TagNode)[]; return children; } diff --git a/src/views/nodes/viewNode.ts b/src/views/nodes/viewNode.ts new file mode 100644 index 0000000..4174c72 --- /dev/null +++ b/src/views/nodes/viewNode.ts @@ -0,0 +1,181 @@ +'use strict'; +import { Command, Disposable, Event, TreeItem, TreeViewVisibilityChangeEvent } from 'vscode'; +import { GitUri } from '../../git/gitService'; +import { RefreshReason, View } from '../viewBase'; + +export enum ResourceType { + ActiveFileHistory = 'gitlens:active:history-file', + ActiveLineHistory = 'gitlens:active:history-line', + Branch = 'gitlens:branch', + BranchWithTracking = 'gitlens:branch:tracking', + Branches = 'gitlens:branches', + BranchesWithRemotes = 'gitlens:branches:remotes', + CurrentBranch = 'gitlens:branch:current', + CurrentBranchWithTracking = 'gitlens:branch:current:tracking', + RemoteBranch = 'gitlens:branch:remote', + Commit = 'gitlens:commit', + CommitOnCurrentBranch = 'gitlens:commit:current', + CommitFile = 'gitlens:file:commit', + Commits = 'gitlens:commits', + ComparisonResults = 'gitlens:results:comparison', + FileHistory = 'gitlens:history-file', + FileStaged = 'gitlens:file:staged', + FileStagedAndUnstaged = 'gitlens:file:staged:unstaged', + FileUnstaged = 'gitlens:file:unstaged', + Folder = 'gitlens:folder', + Message = 'gitlens:message', + Pager = 'gitlens:pager', + Remote = 'gitlens:remote', + Remotes = 'gitlens:remotes', + Repositories = 'gitlens:repositories', + Repository = 'gitlens:repository', + Results = 'gitlens:results', + ResultsCommits = 'gitlens:results:commits', + ResultsFile = 'gitlens:file:results', + ResultsFiles = 'gitlens:results:files', + SearchResults = 'gitlens:results:search', + Stash = 'gitlens:stash', + StashFile = 'gitlens:file:stash', + Stashes = 'gitlens:stashes', + StatusFileCommits = 'gitlens:status:file:commits', + StatusFiles = 'gitlens:status:files', + StatusUpstream = 'gitlens:status:upstream', + Tag = 'gitlens:tag', + Tags = 'gitlens:tags' +} + +export interface NamedRef { + label?: string; + ref: string; +} + +export const unknownGitUri = new GitUri(); + +export abstract class ViewNode { + constructor( + uri: GitUri, + private readonly _parent: ViewNode | undefined + ) { + this._uri = uri; + } + + protected _uri: GitUri; + get uri() { + return this._uri; + } + + abstract getChildren(): ViewNode[] | Promise; + getParent(): ViewNode | undefined { + return this._parent; + } + abstract getTreeItem(): TreeItem | Promise; + + getCommand(): Command | undefined { + return undefined; + } + + refresh(reason?: RefreshReason): void | boolean | Promise | Promise {} +} + +export abstract class ViewRefNode extends ViewNode { + abstract get ref(): string; + + get repoPath(): string { + return this.uri.repoPath!; + } +} + +export interface PageableViewNode { + readonly supportsPaging: boolean; + maxCount: number | undefined; +} + +export function isPageable( + node: ViewNode +): node is ViewNode & { supportsPaging: boolean; maxCount: number | undefined } { + return Boolean((node as any).supportsPaging); +} + +export function supportsAutoRefresh( + view: View +): view is View & { autoRefresh: boolean; onDidChangeAutoRefresh: Event } { + return (view as any).onDidChangeAutoRefresh !== undefined; +} + +export abstract class SubscribeableViewNode extends ViewNode { + protected _disposable: Disposable; + protected _subscription: Disposable | undefined; + + constructor( + uri: GitUri, + parent: ViewNode | undefined, + public readonly view: TView + ) { + super(uri, parent); + + const disposables = [this.view.onDidChangeVisibility(this.onVisibilityChanged, this)]; + + if (supportsAutoRefresh(this.view)) { + disposables.push(this.view.onDidChangeAutoRefresh(this.onAutoRefreshChanged, this)); + } + + this._disposable = Disposable.from(...disposables); + } + + dispose() { + this.unsubscribe(); + + if (this._disposable !== undefined) { + this._disposable.dispose(); + } + } + + private _canSubscribe: boolean = true; + protected get canSubscribe(): boolean { + return this._canSubscribe; + } + protected set canSubscribe(value: boolean) { + if (this._canSubscribe === value) return; + + this._canSubscribe = value; + + void this.ensureSubscription(); + if (value) { + void this.view.refreshNode(this); + } + } + + protected abstract async subscribe(): Promise; + protected unsubscribe(): void { + if (this._subscription !== undefined) { + this._subscription.dispose(); + this._subscription = undefined; + } + } + + protected onAutoRefreshChanged() { + this.onVisibilityChanged({ visible: this.view.visible }); + } + + protected onVisibilityChanged(e: TreeViewVisibilityChangeEvent) { + void this.ensureSubscription(); + + if (e.visible) { + void this.view.refreshNode(this); + } + } + + async ensureSubscription() { + // We only need to subscribe if we are visible and if auto-refresh enabled (when supported) + if (!this.canSubscribe || !this.view.visible || (supportsAutoRefresh(this.view) && !this.view.autoRefresh)) { + this.unsubscribe(); + + return; + } + + // If we already have a subscription, just kick out + if (this._subscription !== undefined) return; + + this._subscription = await this.subscribe(); + } +} diff --git a/src/views/repositoriesExplorer.ts b/src/views/repositoriesExplorer.ts deleted file mode 100644 index c812ecb..0000000 --- a/src/views/repositoriesExplorer.ts +++ /dev/null @@ -1,148 +0,0 @@ -'use strict'; -import { commands, ConfigurationChangeEvent, Event, EventEmitter } from 'vscode'; -import { configuration, ExplorerFilesLayout, ExplorersConfig, RepositoriesExplorerConfig } from '../configuration'; -import { CommandContext, setCommandContext, WorkspaceState } from '../constants'; -import { Container } from '../container'; -import { ExplorerBase, RefreshReason } from './explorer'; -import { RefreshNodeCommandArgs } from './explorerCommands'; -import { RepositoriesNode } from './nodes'; -import { ExplorerNode } from './nodes/explorerNode'; - -export class RepositoriesExplorer extends ExplorerBase { - constructor() { - super('gitlens.repositoriesExplorer'); - } - - private _onDidChangeAutoRefresh = new EventEmitter(); - public get onDidChangeAutoRefresh(): Event { - return this._onDidChangeAutoRefresh.event; - } - - getRoot() { - return new RepositoriesNode(this); - } - - protected registerCommands() { - Container.explorerCommands; - - commands.registerCommand(this.getQualifiedCommand('fetchAll'), () => this.fetchAll(), this); - commands.registerCommand(this.getQualifiedCommand('pullAll'), () => this.pullAll(), this); - - commands.registerCommand(this.getQualifiedCommand('refresh'), () => this.refresh(), this); - commands.registerCommand( - this.getQualifiedCommand('refreshNode'), - (node: ExplorerNode, args?: RefreshNodeCommandArgs) => this.refreshNode(node, args), - this - ); - commands.registerCommand( - this.getQualifiedCommand('setFilesLayoutToAuto'), - () => this.setFilesLayout(ExplorerFilesLayout.Auto), - this - ); - commands.registerCommand( - this.getQualifiedCommand('setFilesLayoutToList'), - () => this.setFilesLayout(ExplorerFilesLayout.List), - this - ); - commands.registerCommand( - this.getQualifiedCommand('setFilesLayoutToTree'), - () => this.setFilesLayout(ExplorerFilesLayout.Tree), - this - ); - - commands.registerCommand( - this.getQualifiedCommand('setAutoRefreshToOn'), - () => this.setAutoRefresh(Container.config.repositoriesExplorer.autoRefresh, true), - this - ); - commands.registerCommand( - this.getQualifiedCommand('setAutoRefreshToOff'), - () => this.setAutoRefresh(Container.config.repositoriesExplorer.autoRefresh, false), - this - ); - } - - protected onConfigurationChanged(e: ConfigurationChangeEvent) { - const initializing = configuration.initializing(e); - - if ( - !initializing && - !configuration.changed(e, configuration.name('repositoriesExplorer').value) && - !configuration.changed(e, configuration.name('explorers').value) && - !configuration.changed(e, configuration.name('defaultGravatarsStyle').value) - ) { - return; - } - - if ( - initializing || - configuration.changed(e, configuration.name('repositoriesExplorer')('enabled').value) || - configuration.changed(e, configuration.name('repositoriesExplorer')('location').value) - ) { - setCommandContext(CommandContext.RepositoriesExplorer, this.config.enabled ? this.config.location : false); - } - - if (configuration.changed(e, configuration.name('repositoriesExplorer')('autoRefresh').value)) { - void this.setAutoRefresh(Container.config.repositoriesExplorer.autoRefresh); - } - - if (initializing || configuration.changed(e, configuration.name('repositoriesExplorer')('location').value)) { - this.initialize(this.config.location); - } - - if (!initializing && this._root !== undefined) { - void this.refresh(RefreshReason.ConfigurationChanged); - } - } - - get autoRefresh() { - return ( - this.config.autoRefresh && - Container.context.workspaceState.get(WorkspaceState.RepositoriesExplorerAutoRefresh, true) - ); - } - - get config(): ExplorersConfig & RepositoriesExplorerConfig { - return { ...Container.config.explorers, ...Container.config.repositoriesExplorer }; - } - - private fetchAll() { - if (this._root === undefined) return; - - return this._root.fetchAll(); - } - - private pullAll() { - if (this._root === undefined) return; - - return this._root.pullAll(); - } - - private async setAutoRefresh(enabled: boolean, workspaceEnabled?: boolean) { - if (enabled) { - if (workspaceEnabled === undefined) { - workspaceEnabled = Container.context.workspaceState.get( - WorkspaceState.RepositoriesExplorerAutoRefresh, - true - ); - } - else { - await Container.context.workspaceState.update( - WorkspaceState.RepositoriesExplorerAutoRefresh, - workspaceEnabled - ); - } - } - - setCommandContext(CommandContext.RepositoriesExplorerAutoRefresh, enabled && workspaceEnabled); - - this._onDidChangeAutoRefresh.fire(); - } - - private setFilesLayout(layout: ExplorerFilesLayout) { - return configuration.updateEffective( - configuration.name('repositoriesExplorer')('files')('layout').value, - layout - ); - } -} diff --git a/src/views/repositoriesView.ts b/src/views/repositoriesView.ts new file mode 100644 index 0000000..6b5c3f3 --- /dev/null +++ b/src/views/repositoriesView.ts @@ -0,0 +1,148 @@ +'use strict'; +import { commands, ConfigurationChangeEvent, Event, EventEmitter } from 'vscode'; +import { configuration, RepositoriesViewConfig, ViewFilesLayout, ViewsConfig } from '../configuration'; +import { CommandContext, setCommandContext, WorkspaceState } from '../constants'; +import { Container } from '../container'; +import { RepositoriesNode } from './nodes'; +import { ViewNode } from './nodes/viewNode'; +import { RefreshReason, ViewBase } from './viewBase'; +import { RefreshNodeCommandArgs } from './viewCommands'; + +export class RepositoriesView extends ViewBase { + constructor() { + super('gitlens.views.repositories'); + } + + private _onDidChangeAutoRefresh = new EventEmitter(); + public get onDidChangeAutoRefresh(): Event { + return this._onDidChangeAutoRefresh.event; + } + + getRoot() { + return new RepositoriesNode(this); + } + + protected registerCommands() { + Container.viewCommands; + + commands.registerCommand(this.getQualifiedCommand('fetchAll'), () => this.fetchAll(), this); + commands.registerCommand(this.getQualifiedCommand('pullAll'), () => this.pullAll(), this); + + commands.registerCommand(this.getQualifiedCommand('refresh'), () => this.refresh(), this); + commands.registerCommand( + this.getQualifiedCommand('refreshNode'), + (node: ViewNode, args?: RefreshNodeCommandArgs) => this.refreshNode(node, args), + this + ); + commands.registerCommand( + this.getQualifiedCommand('setFilesLayoutToAuto'), + () => this.setFilesLayout(ViewFilesLayout.Auto), + this + ); + commands.registerCommand( + this.getQualifiedCommand('setFilesLayoutToList'), + () => this.setFilesLayout(ViewFilesLayout.List), + this + ); + commands.registerCommand( + this.getQualifiedCommand('setFilesLayoutToTree'), + () => this.setFilesLayout(ViewFilesLayout.Tree), + this + ); + + commands.registerCommand( + this.getQualifiedCommand('setAutoRefreshToOn'), + () => this.setAutoRefresh(Container.config.views.repositories.autoRefresh, true), + this + ); + commands.registerCommand( + this.getQualifiedCommand('setAutoRefreshToOff'), + () => this.setAutoRefresh(Container.config.views.repositories.autoRefresh, false), + this + ); + } + + protected onConfigurationChanged(e: ConfigurationChangeEvent) { + const initializing = configuration.initializing(e); + + if ( + !initializing && + !configuration.changed(e, configuration.name('views')('repositories').value) && + !configuration.changed(e, configuration.name('views').value) && + !configuration.changed(e, configuration.name('defaultGravatarsStyle').value) + ) { + return; + } + + if ( + initializing || + configuration.changed(e, configuration.name('views')('repositories')('enabled').value) || + configuration.changed(e, configuration.name('views')('repositories')('location').value) + ) { + setCommandContext(CommandContext.ViewsRepositories, this.config.enabled ? this.config.location : false); + } + + if (configuration.changed(e, configuration.name('views')('repositories')('autoRefresh').value)) { + void this.setAutoRefresh(Container.config.views.repositories.autoRefresh); + } + + if (initializing || configuration.changed(e, configuration.name('views')('repositories')('location').value)) { + this.initialize(this.config.location); + } + + if (!initializing && this._root !== undefined) { + void this.refresh(RefreshReason.ConfigurationChanged); + } + } + + get autoRefresh() { + return ( + this.config.autoRefresh && + Container.context.workspaceState.get(WorkspaceState.ViewsRepositoriesAutoRefresh, true) + ); + } + + get config(): ViewsConfig & RepositoriesViewConfig { + return { ...Container.config.views, ...Container.config.views.repositories }; + } + + private fetchAll() { + if (this._root === undefined) return; + + return this._root.fetchAll(); + } + + private pullAll() { + if (this._root === undefined) return; + + return this._root.pullAll(); + } + + private async setAutoRefresh(enabled: boolean, workspaceEnabled?: boolean) { + if (enabled) { + if (workspaceEnabled === undefined) { + workspaceEnabled = Container.context.workspaceState.get( + WorkspaceState.ViewsRepositoriesAutoRefresh, + true + ); + } + else { + await Container.context.workspaceState.update( + WorkspaceState.ViewsRepositoriesAutoRefresh, + workspaceEnabled + ); + } + } + + setCommandContext(CommandContext.ViewsRepositoriesAutoRefresh, enabled && workspaceEnabled); + + this._onDidChangeAutoRefresh.fire(); + } + + private setFilesLayout(layout: ViewFilesLayout) { + return configuration.updateEffective( + configuration.name('views')('repositories')('files')('layout').value, + layout + ); + } +} diff --git a/src/views/resultsExplorer.ts b/src/views/resultsExplorer.ts deleted file mode 100644 index 58e5459..0000000 --- a/src/views/resultsExplorer.ts +++ /dev/null @@ -1,225 +0,0 @@ -'use strict'; -import { commands, ConfigurationChangeEvent } from 'vscode'; -import { configuration, ExplorerFilesLayout, ExplorersConfig, ResultsExplorerConfig } from '../configuration'; -import { CommandContext, GlyphChars, setCommandContext, WorkspaceState } from '../constants'; -import { Container } from '../container'; -import { GitLog, GitLogCommit } from '../git/gitService'; -import { Functions, Strings } from '../system'; -import { ExplorerBase, RefreshReason } from './explorer'; -import { RefreshNodeCommandArgs } from './explorerCommands'; -import { - ExplorerNode, - NamedRef, - ResourceType, - ResultsCommitNode, - ResultsCommitsNode, - ResultsComparisonNode, - ResultsNode -} from './nodes'; - -export class ResultsExplorer extends ExplorerBase { - constructor() { - super('gitlens.resultsExplorer'); - - setCommandContext(CommandContext.ResultsExplorerKeepResults, this.keepResults); - } - - getRoot() { - return new ResultsNode(this); - } - - protected registerCommands() { - Container.explorerCommands; - commands.registerCommand(this.getQualifiedCommand('refresh'), () => this.refresh(), this); - commands.registerCommand( - this.getQualifiedCommand('refreshNode'), - (node: ExplorerNode, args?: RefreshNodeCommandArgs) => this.refreshNode(node, args), - this - ); - commands.registerCommand( - this.getQualifiedCommand('setFilesLayoutToAuto'), - () => this.setFilesLayout(ExplorerFilesLayout.Auto), - this - ); - commands.registerCommand( - this.getQualifiedCommand('setFilesLayoutToList'), - () => this.setFilesLayout(ExplorerFilesLayout.List), - this - ); - commands.registerCommand( - this.getQualifiedCommand('setFilesLayoutToTree'), - () => this.setFilesLayout(ExplorerFilesLayout.Tree), - this - ); - - commands.registerCommand( - this.getQualifiedCommand('dismissNode'), - (node: ExplorerNode) => this.dismissNode(node), - this - ); - commands.registerCommand(this.getQualifiedCommand('close'), () => this.close(), this); - commands.registerCommand(this.getQualifiedCommand('setKeepResultsToOn'), () => this.setKeepResults(true), this); - commands.registerCommand( - this.getQualifiedCommand('setKeepResultsToOff'), - () => this.setKeepResults(false), - this - ); - commands.registerCommand(this.getQualifiedCommand('swapComparision'), this.swapComparision, this); - } - - protected onConfigurationChanged(e: ConfigurationChangeEvent) { - const initializing = configuration.initializing(e); - - if ( - !initializing && - !configuration.changed(e, configuration.name('resultsExplorer').value) && - !configuration.changed(e, configuration.name('explorers').value) && - !configuration.changed(e, configuration.name('defaultGravatarsStyle').value) - ) { - return; - } - - if (initializing || configuration.changed(e, configuration.name('resultsExplorer')('location').value)) { - setCommandContext(CommandContext.ResultsExplorer, this.enabled ? this.config.location : false); - } - - if (initializing || configuration.changed(e, configuration.name('resultsExplorer')('location').value)) { - this.initialize(this.config.location); - } - - if (!initializing && this._root !== undefined) { - void this.refresh(RefreshReason.ConfigurationChanged); - } - } - - get config(): ExplorersConfig & ResultsExplorerConfig { - return { ...Container.config.explorers, ...Container.config.resultsExplorer }; - } - - private _enabled: boolean = false; - get enabled(): boolean { - return this._enabled; - } - - get keepResults(): boolean { - return Container.context.workspaceState.get(WorkspaceState.ResultsExplorerKeepResults, false); - } - - close() { - if (this._root === undefined) return; - - this._root.clear(); - - this._enabled = false; - setCommandContext(CommandContext.ResultsExplorer, false); - } - - addCommit(commit: GitLogCommit) { - return this.addResults(new ResultsCommitNode(commit, this)); - } - - addComparison(repoPath: string, ref1: string | NamedRef, ref2: string | NamedRef) { - return this.addResults( - new ResultsComparisonNode( - repoPath, - typeof ref1 === 'string' ? { ref: ref1 } : ref1, - typeof ref2 === 'string' ? { ref: ref2 } : ref2, - this - ) - ); - } - - addSearchResults( - repoPath: string, - resultsOrPromise: GitLog | Promise, - resultsLabel: - | string - | { - label: string; - resultsType?: { singular: string; plural: string }; - } - ) { - const getCommitsQuery = async (maxCount: number | undefined) => { - const results = await resultsOrPromise; - - let log; - if (results !== undefined) { - log = await Functions.seeded( - results.query === undefined - ? (maxCount: number | undefined) => Promise.resolve(results) - : results.query, - results.maxCount === maxCount ? results : undefined - )(maxCount); - } - - let label; - if (typeof resultsLabel === 'string') { - label = resultsLabel; - } - else { - const count = log !== undefined ? log.count : 0; - const truncated = log !== undefined ? log.truncated : false; - - const resultsType = - resultsLabel.resultsType === undefined - ? { singular: 'result', plural: 'results' } - : resultsLabel.resultsType; - - let repository = ''; - if ((await Container.git.getRepositoryCount()) > 1) { - const repo = await Container.git.getRepository(repoPath); - repository = ` ${Strings.pad(GlyphChars.Dash, 1, 1)} ${(repo && repo.formattedName) || repoPath}`; - } - - label = `${Strings.pluralize(resultsType.singular, count, { - number: truncated ? `${count}+` : undefined, - plural: resultsType.plural, - zero: 'No' - })} for ${resultsLabel.label}${repository}`; - } - - return { - label: label, - log: log - }; - }; - - return this.addResults( - new ResultsCommitsNode(repoPath, getCommitsQuery, undefined, this, ResourceType.SearchResults) - ); - } - - private async addResults(results: ExplorerNode) { - if (this._root === undefined) { - this._root = this.getRoot(); - } - - this._root.addOrReplace(results, !this.keepResults); - - this._enabled = true; - await setCommandContext(CommandContext.ResultsExplorer, this.config.location); - - setTimeout(() => this._tree!.reveal(results, { select: true }), 250); - } - - private dismissNode(node: ExplorerNode) { - if (this._root === undefined) return; - - this._root.dismiss(node); - } - - private setFilesLayout(layout: ExplorerFilesLayout) { - return configuration.updateEffective(configuration.name('resultsExplorer')('files')('layout').value, layout); - } - - private setKeepResults(enabled: boolean) { - Container.context.workspaceState.update(WorkspaceState.ResultsExplorerKeepResults, enabled); - setCommandContext(CommandContext.ResultsExplorerKeepResults, enabled); - } - - private swapComparision(node: ExplorerNode) { - if (!(node instanceof ResultsComparisonNode)) return; - - node.swap(); - } -} diff --git a/src/views/resultsView.ts b/src/views/resultsView.ts new file mode 100644 index 0000000..2b2bfea --- /dev/null +++ b/src/views/resultsView.ts @@ -0,0 +1,225 @@ +'use strict'; +import { commands, ConfigurationChangeEvent } from 'vscode'; +import { configuration, ResultsViewConfig, ViewFilesLayout, ViewsConfig } from '../configuration'; +import { CommandContext, GlyphChars, setCommandContext, WorkspaceState } from '../constants'; +import { Container } from '../container'; +import { GitLog, GitLogCommit } from '../git/gitService'; +import { Functions, Strings } from '../system'; +import { + NamedRef, + ResourceType, + ResultsCommitNode, + ResultsCommitsNode, + ResultsComparisonNode, + ResultsNode, + ViewNode +} from './nodes'; +import { RefreshReason, ViewBase } from './viewBase'; +import { RefreshNodeCommandArgs } from './viewCommands'; + +export class ResultsView extends ViewBase { + constructor() { + super('gitlens.views.results'); + + setCommandContext(CommandContext.ViewsResultsKeepResults, this.keepResults); + } + + getRoot() { + return new ResultsNode(this); + } + + protected registerCommands() { + Container.viewCommands; + commands.registerCommand(this.getQualifiedCommand('refresh'), () => this.refresh(), this); + commands.registerCommand( + this.getQualifiedCommand('refreshNode'), + (node: ViewNode, args?: RefreshNodeCommandArgs) => this.refreshNode(node, args), + this + ); + commands.registerCommand( + this.getQualifiedCommand('setFilesLayoutToAuto'), + () => this.setFilesLayout(ViewFilesLayout.Auto), + this + ); + commands.registerCommand( + this.getQualifiedCommand('setFilesLayoutToList'), + () => this.setFilesLayout(ViewFilesLayout.List), + this + ); + commands.registerCommand( + this.getQualifiedCommand('setFilesLayoutToTree'), + () => this.setFilesLayout(ViewFilesLayout.Tree), + this + ); + + commands.registerCommand( + this.getQualifiedCommand('dismissNode'), + (node: ViewNode) => this.dismissNode(node), + this + ); + commands.registerCommand(this.getQualifiedCommand('close'), () => this.close(), this); + commands.registerCommand(this.getQualifiedCommand('setKeepResultsToOn'), () => this.setKeepResults(true), this); + commands.registerCommand( + this.getQualifiedCommand('setKeepResultsToOff'), + () => this.setKeepResults(false), + this + ); + commands.registerCommand(this.getQualifiedCommand('swapComparision'), this.swapComparision, this); + } + + protected onConfigurationChanged(e: ConfigurationChangeEvent) { + const initializing = configuration.initializing(e); + + if ( + !initializing && + !configuration.changed(e, configuration.name('views')('results').value) && + !configuration.changed(e, configuration.name('views').value) && + !configuration.changed(e, configuration.name('defaultGravatarsStyle').value) + ) { + return; + } + + if (initializing || configuration.changed(e, configuration.name('views')('results')('location').value)) { + setCommandContext(CommandContext.ViewsResults, this.enabled ? this.config.location : false); + } + + if (initializing || configuration.changed(e, configuration.name('views')('results')('location').value)) { + this.initialize(this.config.location); + } + + if (!initializing && this._root !== undefined) { + void this.refresh(RefreshReason.ConfigurationChanged); + } + } + + get config(): ViewsConfig & ResultsViewConfig { + return { ...Container.config.views, ...Container.config.views.results }; + } + + private _enabled: boolean = false; + get enabled(): boolean { + return this._enabled; + } + + get keepResults(): boolean { + return Container.context.workspaceState.get(WorkspaceState.ViewsResultsKeepResults, false); + } + + close() { + if (this._root === undefined) return; + + this._root.clear(); + + this._enabled = false; + setCommandContext(CommandContext.ViewsResults, false); + } + + addCommit(commit: GitLogCommit) { + return this.addResults(new ResultsCommitNode(commit, this)); + } + + addComparison(repoPath: string, ref1: string | NamedRef, ref2: string | NamedRef) { + return this.addResults( + new ResultsComparisonNode( + repoPath, + typeof ref1 === 'string' ? { ref: ref1 } : ref1, + typeof ref2 === 'string' ? { ref: ref2 } : ref2, + this + ) + ); + } + + addSearchResults( + repoPath: string, + resultsOrPromise: GitLog | Promise, + resultsLabel: + | string + | { + label: string; + resultsType?: { singular: string; plural: string }; + } + ) { + const getCommitsQuery = async (maxCount: number | undefined) => { + const results = await resultsOrPromise; + + let log; + if (results !== undefined) { + log = await Functions.seeded( + results.query === undefined + ? (maxCount: number | undefined) => Promise.resolve(results) + : results.query, + results.maxCount === maxCount ? results : undefined + )(maxCount); + } + + let label; + if (typeof resultsLabel === 'string') { + label = resultsLabel; + } + else { + const count = log !== undefined ? log.count : 0; + const truncated = log !== undefined ? log.truncated : false; + + const resultsType = + resultsLabel.resultsType === undefined + ? { singular: 'result', plural: 'results' } + : resultsLabel.resultsType; + + let repository = ''; + if ((await Container.git.getRepositoryCount()) > 1) { + const repo = await Container.git.getRepository(repoPath); + repository = ` ${Strings.pad(GlyphChars.Dash, 1, 1)} ${(repo && repo.formattedName) || repoPath}`; + } + + label = `${Strings.pluralize(resultsType.singular, count, { + number: truncated ? `${count}+` : undefined, + plural: resultsType.plural, + zero: 'No' + })} for ${resultsLabel.label}${repository}`; + } + + return { + label: label, + log: log + }; + }; + + return this.addResults( + new ResultsCommitsNode(repoPath, getCommitsQuery, undefined, this, ResourceType.SearchResults) + ); + } + + private async addResults(results: ViewNode) { + if (this._root === undefined) { + this._root = this.getRoot(); + } + + this._root.addOrReplace(results, !this.keepResults); + + this._enabled = true; + await setCommandContext(CommandContext.ViewsResults, this.config.location); + + setTimeout(() => this._tree!.reveal(results, { select: true }), 250); + } + + private dismissNode(node: ViewNode) { + if (this._root === undefined) return; + + this._root.dismiss(node); + } + + private setFilesLayout(layout: ViewFilesLayout) { + return configuration.updateEffective(configuration.name('views')('results')('files')('layout').value, layout); + } + + private setKeepResults(enabled: boolean) { + Container.context.workspaceState.update(WorkspaceState.ViewsResultsKeepResults, enabled); + setCommandContext(CommandContext.ViewsResultsKeepResults, enabled); + } + + private swapComparision(node: ViewNode) { + if (!(node instanceof ResultsComparisonNode)) return; + + node.swap(); + } +} diff --git a/src/views/viewBase.ts b/src/views/viewBase.ts new file mode 100644 index 0000000..5ba38df --- /dev/null +++ b/src/views/viewBase.ts @@ -0,0 +1,178 @@ +'use strict'; +import { + ConfigurationChangeEvent, + Disposable, + Event, + EventEmitter, + TreeDataProvider, + TreeItem, + TreeView, + TreeViewVisibilityChangeEvent, + window +} from 'vscode'; +import { configuration } from '../configuration'; +import { Container } from '../container'; +import { Logger } from '../logger'; +import { FileHistoryView } from './fileHistoryView'; +import { LineHistoryView } from './lineHistoryView'; +import { ViewNode } from './nodes'; +import { isPageable } from './nodes/viewNode'; +import { RepositoriesView } from './repositoriesView'; +import { ResultsView } from './resultsView'; +import { RefreshNodeCommandArgs } from './viewCommands'; + +export enum RefreshReason { + Command = 'Command', + ConfigurationChanged = 'ConfigurationChanged', + VisibilityChanged = 'VisibilityChanged' +} + +export type View = RepositoriesView | FileHistoryView | LineHistoryView | ResultsView; + +export abstract class ViewBase implements TreeDataProvider, Disposable { + protected _onDidChangeTreeData = new EventEmitter(); + public get onDidChangeTreeData(): Event { + return this._onDidChangeTreeData.event; + } + + private _onDidChangeVisibility = new EventEmitter(); + public get onDidChangeVisibility(): Event { + return this._onDidChangeVisibility.event; + } + + protected _disposable: Disposable | undefined; + protected _root: TRoot | undefined; + protected _tree: TreeView | undefined; + + constructor( + public readonly id: string + ) { + this.registerCommands(); + + Container.context.subscriptions.push(configuration.onDidChange(this.onConfigurationChanged, this)); + setImmediate(() => this.onConfigurationChanged(configuration.initializingChangeEvent)); + } + + dispose() { + this._disposable && this._disposable.dispose(); + } + + getQualifiedCommand(command: string) { + return `${this.id}.${command}`; + } + + protected abstract getRoot(): TRoot; + protected abstract registerCommands(): void; + protected abstract onConfigurationChanged(e: ConfigurationChangeEvent): void; + + protected initialize(container?: string) { + if (this._disposable) { + this._disposable.dispose(); + this._onDidChangeTreeData = new EventEmitter(); + } + + this._tree = window.createTreeView(`${this.id}${container ? `:${container}` : ''}`, { + treeDataProvider: this + }); + this._disposable = Disposable.from( + this._tree, + this._tree.onDidChangeVisibility(this.onVisibilityChanged, this) + ); + } + + getChildren(node?: ViewNode): ViewNode[] | Promise { + if (node !== undefined) return node.getChildren(); + + if (this._root === undefined) { + this._root = this.getRoot(); + } + + return this._root.getChildren(); + } + + getParent(node: ViewNode): ViewNode | undefined { + return node.getParent(); + } + + getTreeItem(node: ViewNode): TreeItem | Promise { + return node.getTreeItem(); + } + + protected onVisibilityChanged(e: TreeViewVisibilityChangeEvent) { + this._onDidChangeVisibility.fire(e); + } + + get selection(): ViewNode[] { + if (this._tree === undefined || this._root === undefined) return []; + + return this._tree.selection; + } + + get visible(): boolean { + return this._tree !== undefined ? this._tree.visible : false; + } + + async refresh(reason?: RefreshReason) { + if (reason === undefined) { + reason = RefreshReason.Command; + } + + Logger.log(`View(${this.id}).refresh`, `reason='${reason}'`); + + if (this._root !== undefined) { + await this._root.refresh(reason); + } + + this.triggerNodeUpdate(); + } + + async refreshNode(node: ViewNode, args?: RefreshNodeCommandArgs) { + Logger.log(`View(${this.id}).refreshNode(${(node as { id?: string }).id || ''})`); + + if (args !== undefined) { + if (isPageable(node)) { + if (args.maxCount === undefined || args.maxCount === 0) { + node.maxCount = args.maxCount; + } + else { + node.maxCount = (node.maxCount || args.maxCount) + args.maxCount; + } + } + } + + const cancel = await node.refresh(); + if (cancel === true) return; + + this.triggerNodeUpdate(node); + } + + async reveal( + node: ViewNode, + options?: { + select?: boolean | undefined; + focus?: boolean | undefined; + } + ) { + if (this._tree === undefined || this._root === undefined) return; + + try { + await this._tree.reveal(node, options); + } + catch (ex) { + Logger.error(ex); + } + } + + async show() { + if (this._tree === undefined || this._root === undefined) return; + + // This sucks -- have to get the first child to reveal the tree + const [child] = await this._root.getChildren(); + return this.reveal(child, { select: false, focus: true }); + } + + triggerNodeUpdate(node?: ViewNode) { + // Since the root node won't actually refresh, force everything + this._onDidChangeTreeData.fire(node !== undefined && node !== this._root ? node : undefined); + } +} diff --git a/src/views/viewCommands.ts b/src/views/viewCommands.ts new file mode 100644 index 0000000..62d7340 --- /dev/null +++ b/src/views/viewCommands.ts @@ -0,0 +1,546 @@ +'use strict'; +import * as path from 'path'; +import { commands, Disposable, InputBoxOptions, Terminal, TextDocumentShowOptions, Uri, window } from 'vscode'; +import { + Commands, + DiffWithCommandArgs, + DiffWithCommandArgsRevision, + DiffWithPreviousCommandArgs, + DiffWithWorkingCommandArgs, + openEditor, + OpenFileInRemoteCommandArgs, + OpenFileRevisionCommandArgs, + openWorkspace +} from '../commands'; +import { BuiltInCommands, CommandContext, extensionTerminalName, setCommandContext } from '../constants'; +import { Container } from '../container'; +import { toGitLensFSUri } from '../git/fsProvider'; +import { GitService, GitUri } from '../git/gitService'; +import { Arrays } from '../system'; +import { + BranchNode, + CommitFileNode, + CommitNode, + RemoteNode, + RepositoryNode, + ResultsFileNode, + StashFileNode, + StashNode, + StatusFileNode, + StatusUpstreamNode, + TagNode, + ViewNode, + ViewRefNode +} from './nodes'; + +export interface RefreshNodeCommandArgs { + maxCount?: number; +} + +interface ICompareSelected { + ref: string; + repoPath: string | undefined; + uri?: Uri; +} + +export class ViewCommands implements Disposable { + private _disposable: Disposable | undefined; + private _terminal: Terminal | undefined; + private _terminalCwd: string | undefined; + + constructor() { + commands.registerCommand('gitlens.views.fetch', this.fetch, this); + commands.registerCommand('gitlens.views.pull', this.pull, this); + commands.registerCommand('gitlens.views.push', this.push, this); + commands.registerCommand('gitlens.views.closeRepository', this.closeRepository, this); + + commands.registerCommand('gitlens.views.exploreRepoRevision', this.exploreRepoRevision, this); + + commands.registerCommand('gitlens.views.openChanges', this.openChanges, this); + commands.registerCommand('gitlens.views.openChangesWithWorking', this.openChangesWithWorking, this); + commands.registerCommand('gitlens.views.openFile', this.openFile, this); + commands.registerCommand('gitlens.views.openFileRevision', this.openFileRevision, this); + commands.registerCommand('gitlens.views.openFileRevisionInRemote', this.openFileRevisionInRemote, this); + commands.registerCommand('gitlens.views.openChangedFiles', this.openChangedFiles, this); + commands.registerCommand('gitlens.views.openChangedFileChanges', this.openChangedFileChanges, this); + commands.registerCommand( + 'gitlens.views.openChangedFileChangesWithWorking', + this.openChangedFileChangesWithWorking, + this + ); + commands.registerCommand('gitlens.views.openChangedFileRevisions', this.openChangedFileRevisions, this); + commands.registerCommand('gitlens.views.applyChanges', this.applyChanges, this); + + commands.registerCommand('gitlens.views.stageFile', this.stageFile, this); + commands.registerCommand('gitlens.views.unstageFile', this.unstageFile, this); + + commands.registerCommand('gitlens.views.compareAncestryWithWorking', this.compareAncestryWithWorking, this); + commands.registerCommand('gitlens.views.compareWithHead', this.compareWithHead, this); + commands.registerCommand('gitlens.views.compareWithRemote', this.compareWithRemote, this); + commands.registerCommand('gitlens.views.compareWithSelected', this.compareWithSelected, this); + commands.registerCommand('gitlens.views.compareWithWorking', this.compareWithWorking, this); + commands.registerCommand('gitlens.views.selectForCompare', this.selectForCompare, this); + + commands.registerCommand('gitlens.views.terminalCheckoutBranch', this.terminalCheckoutBranch, this); + commands.registerCommand('gitlens.views.terminalCreateBranch', this.terminalCreateBranch, this); + commands.registerCommand('gitlens.views.terminalDeleteBranch', this.terminalDeleteBranch, this); + commands.registerCommand('gitlens.views.terminalMergeBranch', this.terminalMergeBranch, this); + commands.registerCommand('gitlens.views.terminalRebaseBranch', this.terminalRebaseBranch, this); + commands.registerCommand('gitlens.views.terminalRebaseBranchToRemote', this.terminalRebaseBranchToRemote, this); + commands.registerCommand( + 'gitlens.views.terminalSquashBranchIntoCommit', + this.terminalSquashBranchIntoCommit, + this + ); + commands.registerCommand('gitlens.views.terminalCheckoutCommit', this.terminalCheckoutCommit, this); + commands.registerCommand('gitlens.views.terminalCherryPickCommit', this.terminalCherryPickCommit, this); + commands.registerCommand('gitlens.views.terminalPushCommit', this.terminalPushCommit, this); + commands.registerCommand('gitlens.views.terminalRebaseCommit', this.terminalRebaseCommit, this); + commands.registerCommand('gitlens.views.terminalResetCommit', this.terminalResetCommit, this); + commands.registerCommand('gitlens.views.terminalRevertCommit', this.terminalRevertCommit, this); + commands.registerCommand('gitlens.views.terminalRemoveRemote', this.terminalRemoveRemote, this); + commands.registerCommand('gitlens.views.terminalCreateTag', this.terminalCreateTag, this); + commands.registerCommand('gitlens.views.terminalDeleteTag', this.terminalDeleteTag, this); + } + + dispose() { + this._disposable && this._disposable.dispose(); + } + + private fetch(node: RepositoryNode) { + if (!(node instanceof RepositoryNode)) return; + + return node.fetch(); + } + + private pull(node: RepositoryNode) { + if (!(node instanceof RepositoryNode)) return; + + return node.pull(); + } + + private push(node: RepositoryNode) { + if (!(node instanceof RepositoryNode)) return; + + return node.push(); + } + + private async applyChanges(node: CommitFileNode | StashFileNode | ResultsFileNode) { + void (await this.openFile(node)); + + if (node.uri.sha !== undefined && node.uri.sha !== 'HEAD') { + void (await Container.git.applyChangesToWorkingFile(node.uri)); + } + } + + private closeRepository(node: RepositoryNode) { + if (!(node instanceof RepositoryNode)) return; + + node.repo.closed = true; + } + + private compareWithHead(node: ViewNode) { + if (!(node instanceof ViewRefNode)) return; + + return Container.resultsView.addComparison(node.repoPath, node.ref, 'HEAD'); + } + + private compareWithRemote(node: BranchNode) { + if (!node.branch.tracking) return; + + return Container.resultsView.addComparison(node.repoPath, node.branch.tracking, node.ref); + } + + private compareWithWorking(node: ViewNode) { + if (!(node instanceof ViewRefNode)) return; + + return Container.resultsView.addComparison(node.repoPath, node.ref, ''); + } + + private async compareAncestryWithWorking(node: BranchNode) { + const branch = await Container.git.getBranch(node.repoPath); + if (branch === undefined) return; + + const commonAncestor = await Container.git.getMergeBase(node.repoPath, branch.ref, node.ref); + if (commonAncestor === undefined) return; + + return Container.resultsView.addComparison( + node.repoPath, + { ref: commonAncestor, label: `ancestry with ${node.ref} (${GitService.shortenSha(commonAncestor)})` }, + '' + ); + } + + private compareWithSelected(node: ViewNode) { + if (this._selection === undefined || !(node instanceof ViewRefNode)) return; + if (this._selection.repoPath !== node.repoPath) return; + + if (this._selection.uri !== undefined) { + if (!(node instanceof CommitFileNode)) return; + + const diffArgs: DiffWithCommandArgs = { + repoPath: this._selection.repoPath, + lhs: { + sha: this._selection.ref, + uri: this._selection.uri! + }, + rhs: { + sha: node.ref, + uri: node.uri + } + }; + commands.executeCommand(Commands.DiffWith, diffArgs); + + return; + } + + return Container.resultsView.addComparison(this._selection.repoPath, this._selection.ref, node.ref); + } + + private _selection: ICompareSelected | undefined; + + private selectForCompare(node: ViewNode) { + if (!(node instanceof ViewRefNode)) return; + + this._selection = { + ref: node.ref, + repoPath: node.repoPath, + uri: node instanceof CommitFileNode ? node.uri : undefined + }; + setCommandContext(CommandContext.ViewsCanCompare, true); + } + + private exploreRepoRevision(node: ViewRefNode, options: { openInNewWindow?: boolean } = {}) { + if (!(node instanceof ViewRefNode)) return; + + const uri = toGitLensFSUri(node.ref, node.repoPath); + const gitUri = GitUri.fromRevisionUri(uri); + + openWorkspace(uri, `${path.basename(gitUri.repoPath!)} @ ${gitUri.shortSha}`, options); + + void commands.executeCommand(BuiltInCommands.FocusFilesExplorer); + } + + private openChanges(node: CommitFileNode | StashFileNode | ResultsFileNode) { + const command = node.getCommand(); + if (command === undefined || command.arguments === undefined) return; + + const [uri, args] = command.arguments as [Uri, DiffWithPreviousCommandArgs]; + args.showOptions!.preview = false; + return commands.executeCommand(command.command, uri, args); + } + + private async openChangesWithWorking(node: CommitFileNode | StashFileNode | ResultsFileNode) { + const args: DiffWithWorkingCommandArgs = { + showOptions: { + preserveFocus: true, + preview: false + } + }; + + if (node instanceof ResultsFileNode) { + args.commit = await Container.git.getLogCommitForFile(node.repoPath, node.uri.fsPath, { + ref: node.uri.sha, + firstIfNotFound: true, + reverse: true + }); + } + + return commands.executeCommand(Commands.DiffWithWorking, node.uri, args); + } + + private openFile(node: CommitFileNode | StashFileNode | ResultsFileNode) { + return openEditor(node.uri, { preserveFocus: true, preview: false }); + } + + private openFileRevision( + node: CommitFileNode | StashFileNode | ResultsFileNode, + options: OpenFileRevisionCommandArgs = { showOptions: { preserveFocus: true, preview: false } } + ) { + let uri = options.uri; + if (uri == null) { + if (node instanceof ResultsFileNode) { + uri = GitUri.toRevisionUri(node.uri); + } + else { + uri = + node.commit.status === 'D' + ? GitUri.toRevisionUri( + node.commit.previousSha!, + node.commit.previousUri.fsPath, + node.commit.repoPath + ) + : GitUri.toRevisionUri(node.uri); + } + } + + return openEditor(uri, options.showOptions || { preserveFocus: true, preview: false }); + } + + private async openChangedFileChanges( + node: CommitNode | StashNode, + options: TextDocumentShowOptions = { preserveFocus: false, preview: false } + ) { + const repoPath = node.commit.repoPath; + const uris = node.commit.files.map(s => GitUri.fromFile(s, repoPath)); + + for (const uri of uris) { + await this.openDiffWith( + repoPath, + { + uri: uri, + sha: + node.commit.previousSha !== undefined ? node.commit.previousSha : GitService.deletedOrMissingSha + }, + { uri: uri, sha: node.commit.sha }, + options + ); + } + } + + private async openChangedFileChangesWithWorking( + node: CommitNode | StashNode, + options: TextDocumentShowOptions = { preserveFocus: false, preview: false } + ) { + const repoPath = node.commit.repoPath; + const uris = Arrays.filterMap( + node.commit.files, + f => (f.status !== 'D' ? GitUri.fromFile(f, repoPath) : undefined) + ); + + for (const uri of uris) { + await this.openDiffWith(repoPath, { uri: uri, sha: node.commit.sha }, { uri: uri, sha: '' }, options); + } + } + + private async openChangedFiles( + node: CommitNode | StashNode, + options: TextDocumentShowOptions = { preserveFocus: false, preview: false } + ) { + const repoPath = node.commit.repoPath; + const uris = Arrays.filterMap(node.commit.files, f => GitUri.fromFile(f, repoPath)); + + for (const uri of uris) { + await openEditor(uri, options); + } + } + + private async openChangedFileRevisions( + node: CommitNode | StashNode, + options: TextDocumentShowOptions = { preserveFocus: false, preview: false } + ) { + const uris = Arrays.filterMap(node.commit.files, f => + GitUri.toRevisionUri( + f.status === 'D' ? node.commit.previousFileSha : node.commit.sha, + f, + node.commit.repoPath + ) + ); + for (const uri of uris) { + await openEditor(uri, options); + } + } + + private async openDiffWith( + repoPath: string, + lhs: DiffWithCommandArgsRevision, + rhs: DiffWithCommandArgsRevision, + options: TextDocumentShowOptions = { preserveFocus: false, preview: false } + ) { + const diffArgs: DiffWithCommandArgs = { + repoPath: repoPath, + lhs: lhs, + rhs: rhs, + showOptions: options + }; + return commands.executeCommand(Commands.DiffWith, diffArgs); + } + + private async openFileRevisionInRemote(node: CommitFileNode | StashFileNode | StatusFileNode) { + return commands.executeCommand(Commands.OpenFileInRemote, node.commit.toGitUri(node.commit.status === 'D'), { + range: false + } as OpenFileInRemoteCommandArgs); + } + + stageFile(node: CommitFileNode | StatusFileNode) { + if (!(node instanceof CommitFileNode) && !(node instanceof StatusFileNode)) return; + + Container.git.stageFile(node.repoPath, node.file.fileName); + } + + unstageFile(node: CommitFileNode | StatusFileNode) { + if (!(node instanceof CommitFileNode) && !(node instanceof StatusFileNode)) return; + + Container.git.unStageFile(node.repoPath, node.file.fileName); + } + + async terminalCheckoutBranch(node: ViewNode) { + if (!(node instanceof BranchNode)) return; + + this.sendTerminalCommand('checkout', `${node.ref}`, node.repoPath); + } + + async terminalCreateBranch(node: ViewNode) { + if (!(node instanceof ViewRefNode)) return; + + let remoteBranch = false; + let value = undefined; + if (node instanceof BranchNode && node.branch.remote) { + remoteBranch = true; + value = node.branch.getName(); + } + + const name = await window.showInputBox({ + prompt: `Please provide a branch name (Press 'Enter' to confirm or 'Escape' to cancel)`, + placeHolder: `Branch name`, + value: value + } as InputBoxOptions); + if (name === undefined || name === '') return; + + this.sendTerminalCommand('branch', `${remoteBranch ? '-t ' : ''}${name} ${node.ref}`, node.repoPath); + } + + terminalDeleteBranch(node: ViewNode) { + if (!(node instanceof BranchNode)) return; + + if (node.branch.remote) { + this.sendTerminalCommand('push', `${node.branch.getRemote()} :${node.branch.getName()}`, node.repoPath); + } + else { + this.sendTerminalCommand('branch', `-d ${node.ref}`, node.repoPath); + } + } + + terminalMergeBranch(node: ViewNode) { + if (!(node instanceof BranchNode)) return; + + this.sendTerminalCommand('merge', `${node.ref}`, node.repoPath); + } + + terminalRebaseBranch(node: ViewNode) { + if (!(node instanceof BranchNode)) return; + + this.sendTerminalCommand('rebase', `-i ${node.ref}`, node.repoPath); + } + + terminalRebaseBranchToRemote(node: ViewNode) { + if (node instanceof BranchNode) { + if (!node.branch.current || !node.branch.tracking) return; + + this.sendTerminalCommand('rebase', `-i ${node.branch.tracking}`, node.repoPath); + } + else if (node instanceof StatusUpstreamNode) { + this.sendTerminalCommand('rebase', `-i ${node.status.upstream}`, node.status.repoPath); + } + } + + terminalSquashBranchIntoCommit(node: ViewNode) { + if (!(node instanceof BranchNode)) return; + + this.sendTerminalCommand('merge', `--squash ${node.ref}`, node.repoPath); + } + + terminalCheckoutCommit(node: ViewNode) { + if (!(node instanceof CommitNode)) return; + + this.sendTerminalCommand('checkout', `${node.ref}`, node.repoPath); + } + + terminalCherryPickCommit(node: ViewNode) { + if (!(node instanceof CommitNode)) return; + + this.sendTerminalCommand('cherry-pick', `-e ${node.ref}`, node.repoPath); + } + + async terminalPushCommit(node: ViewNode) { + if (!(node instanceof CommitNode)) return; + + const branch = node.branch || (await Container.git.getBranch(node.repoPath)); + if (branch === undefined) return; + + this.sendTerminalCommand('push', `${branch.getRemote()} ${node.ref}:${branch.getName()}`, node.repoPath); + } + + terminalRebaseCommit(node: ViewNode) { + if (!(node instanceof CommitNode)) return; + + this.sendTerminalCommand('rebase', `-i ${node.ref}^`, node.repoPath); + } + + terminalResetCommit(node: ViewNode) { + if (!(node instanceof CommitNode)) return; + + this.sendTerminalCommand('reset', `--soft ${node.ref}`, node.repoPath); + } + + terminalRevertCommit(node: ViewNode) { + if (!(node instanceof CommitNode)) return; + + this.sendTerminalCommand('revert', `-e ${node.ref}`, node.repoPath); + } + + terminalRemoveRemote(node: ViewNode) { + if (!(node instanceof RemoteNode)) return; + + this.sendTerminalCommand('remote', `remove ${node.remote.name}`, node.remote.repoPath); + } + + async terminalCreateTag(node: ViewNode) { + if (!(node instanceof ViewRefNode)) return; + + const name = await window.showInputBox({ + prompt: `Please provide a tag name (Press 'Enter' to confirm or 'Escape' to cancel)`, + placeHolder: `Tag name` + } as InputBoxOptions); + if (name === undefined || name === '') return; + + const message = await window.showInputBox({ + prompt: `Please provide an optional message to annotate the tag (Press 'Enter' to confirm or 'Escape' to cancel)`, + placeHolder: `Tag message` + } as InputBoxOptions); + if (message === undefined) return; + + const args = `${message !== '' ? `-a -m "${message}" ` : ''}${name} ${node.ref}`; + this.sendTerminalCommand('tag', args, node.repoPath); + } + + terminalDeleteTag(node: ViewNode) { + if (!(node instanceof TagNode)) return; + + this.sendTerminalCommand('tag', `-d ${node.ref}`, node.repoPath); + } + + private ensureTerminal(cwd: string): Terminal { + if (this._terminal === undefined) { + this._terminal = window.createTerminal(extensionTerminalName); + this._disposable = window.onDidCloseTerminal((e: Terminal) => { + if (e.name === extensionTerminalName) { + this._terminal = undefined; + this._disposable!.dispose(); + this._disposable = undefined; + } + }, this); + + Container.context.subscriptions.push(this._disposable); + this._terminalCwd = undefined; + } + + if (this._terminalCwd !== cwd) { + this._terminal.sendText(`cd "${cwd}"`, true); + this._terminalCwd = cwd; + } + + return this._terminal; + } + + private sendTerminalCommand(command: string, args: string, cwd: string) { + // let git = GitService.getGitPath(); + // if (git.includes(' ')) { + // git = `"${git}"`; + // } + + const terminal = this.ensureTerminal(cwd); + terminal.show(false); + terminal.sendText(`git ${command} ${args}`, false); + } +}