diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9565344..1d93609 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
### Added
+- Adds usage-based sorting (on by default) to the _Git Command Palette_
+ - Adds a `gitlens.gitCommands.sortBy` setting to specify how Git commands are sorted in the _Git Command Palette_
- Adds ability to show gutter heatmap in the gutter and/or on the scroll bar — closes [#297](https://github.com/eamodio/vscode-gitlens/issues/297)
- Adds a `gitlens.heatmap.locations` setting to specify where the indicators of the gutter heatmap annotations will be shown
- Adds a `gitlens.fileAnnotations.command` setting to specify whether the file annotations button in the editor title shows a menu or immediately toggles the specified file annotations — closes [#1165](https://github.com/eamodio/vscode-gitlens/issues/1165) thanks to [PR #1171](https://github.com/eamodio/vscode-gitlens/pull/1171) by Raaj Patil ([@arrpee](https://github.com/arrpee))
diff --git a/README.md b/README.md
index 310e552..a13ecb5 100644
--- a/README.md
+++ b/README.md
@@ -875,14 +875,15 @@ See also [View Settings](#view-settings- 'Jump to the View settings')
## Git Command Palette Settings [#](#git-command-palette-settings- 'Git Command Palette Settings')
-| Name | Description |
-| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
-| `gitlens.gitCommands.closeOnFocusOut` | Specifies whether to dismiss the _Git Commands Palette_ when focus is lost (if not, press `ESC` to dismiss) |
-| `gitlens.gitCommands.search.matchAll` | Specifies whether to match all or any commit message search patterns |
-| `gitlens.gitCommands.search.matchCase` | Specifies whether to match commit search patterns with or without regard to casing |
-| `gitlens.gitCommands.search.matchRegex` | Specifies whether to match commit search patterns using regular expressions |
-| `gitlens.gitCommands.search.showResultsInSideBar` | Specifies whether to show the commit search results directly in the quick pick menu, in the Side Bar, or will be based on the context |
-| `gitlens.gitCommands.skipConfirmations` | Specifies which (and when) Git commands will skip the confirmation step, using the format: `git-command-name:(menu/command)` |
+| Name | Description |
+| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `gitlens.gitCommands.closeOnFocusOut` | Specifies whether to dismiss the _Git Commands Palette_ when focus is lost (if not, press `ESC` to dismiss) |
+| `gitlens.gitCommands.search.matchAll` | Specifies whether to match all or any commit message search patterns |
+| `gitlens.gitCommands.search.matchCase` | Specifies whether to match commit search patterns with or without regard to casing |
+| `gitlens.gitCommands.search.matchRegex` | Specifies whether to match commit search patterns using regular expressions |
+| `gitlens.gitCommands.search.showResultsInSideBar` | Specifies whether to show the commit search results directly in the quick pick menu, in the Side Bar, or will be based on the context |
+| `gitlens.gitCommands.skipConfirmations` | Specifies which (and when) Git commands will skip the confirmation step, using the format: `git-command-name:(menu/command)` |
+| `gitlens.gitCommands.sortBy` | Specifies how Git commands are sorted in the _Git Command Palette_
`name` - sorts commands by name
`usage` - sorts commands by last used date |
## Remote Provider Integration Settings [#](#remote-provider-integration-settings- 'Remote Provider Integration Settings')
diff --git a/package.json b/package.json
index edfe529..6d4fa20 100644
--- a/package.json
+++ b/package.json
@@ -733,6 +733,20 @@
"markdownDescription": "Specifies which (and when) Git commands will skip the confirmation step, using the format: `git-command-name:(menu|command)`",
"scope": "window"
},
+ "gitlens.gitCommands.sortBy": {
+ "type": "string",
+ "default": "usage",
+ "enum": [
+ "name",
+ "usage"
+ ],
+ "enumDescriptions": [
+ "Sorts commands by name",
+ "Sorts commands by last used date"
+ ],
+ "markdownDescription": "Specifies how Git commands are sorted in the _Git Command Palette_",
+ "scope": "window"
+ },
"gitlens.heatmap.ageThreshold": {
"type": "number",
"default": 90,
diff --git a/src/commands/gitCommands.ts b/src/commands/gitCommands.ts
index ce3166f..9074822 100644
--- a/src/commands/gitCommands.ts
+++ b/src/commands/gitCommands.ts
@@ -1,7 +1,8 @@
'use strict';
import { Disposable, InputBox, QuickInputButton, QuickInputButtons, QuickPick, QuickPickItem, window } from 'vscode';
import { command, Command, Commands } from './common';
-import { configuration } from '../configuration';
+import { configuration, GitCommandSorting } from '../configuration';
+import { Usage, WorkspaceState } from '../constants';
import { Container } from '../container';
import { BranchGitCommand, BranchGitCommandArgs } from './git/branch';
import { CherryPickGitCommand, CherryPickGitCommandArgs } from './git/cherry-pick';
@@ -723,6 +724,13 @@ class PickCommandStep implements QuickPickStep {
new TagGitCommand(args?.command === 'tag' ? args : undefined),
];
+ if (Container.config.gitCommands.sortBy === GitCommandSorting.Usage) {
+ const usage = Container.context.workspaceState.get(WorkspaceState.GitCommandPaletteUsage);
+ if (usage != null) {
+ this.items.sort((a, b) => (usage[b.key] ?? 0) - (usage[a.key] ?? 0));
+ }
+ }
+
this.hiddenItems = [];
}
@@ -751,5 +759,18 @@ class PickCommandStep implements QuickPickStep {
}
this._command = command;
+ if (command != null) {
+ void this.updateCommandUsage(command.key, Date.now());
+ }
+ }
+
+ private async updateCommandUsage(id: string, timestamp: number) {
+ let usage = Container.context.workspaceState.get(WorkspaceState.GitCommandPaletteUsage);
+ if (usage === undefined) {
+ usage = Object.create(null) as Usage;
+ }
+
+ usage[id] = timestamp;
+ await Container.context.workspaceState.update(WorkspaceState.GitCommandPaletteUsage, usage);
}
}
diff --git a/src/config.ts b/src/config.ts
index dbace23..7978369 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -58,6 +58,7 @@ export interface Config {
showResultsInSideBar: boolean | null;
};
skipConfirmations: string[];
+ sortBy: GitCommandSorting;
};
heatmap: {
ageThreshold: number;
@@ -210,6 +211,11 @@ export enum FileAnnotationType {
Heatmap = 'heatmap',
}
+export enum GitCommandSorting {
+ Name = 'name',
+ Usage = 'usage',
+}
+
export enum GravatarDefaultStyle {
Faces = 'wavatar',
Geometric = 'identicon',
diff --git a/src/constants.ts b/src/constants.ts
index c80d0b8..3e5464f 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -206,11 +206,16 @@ export interface Starred {
[id: string]: boolean;
}
+export interface Usage {
+ [id: string]: number;
+}
+
export enum WorkspaceState {
BranchComparisons = 'gitlens:branch:comparisons',
ConnectedPrefix = 'gitlens:connected:',
DefaultRemote = 'gitlens:remote:default',
DisallowConnectionPrefix = 'gitlens:disallow:connection:',
+ GitCommandPaletteUsage = 'gitlens:gitComandPalette:usage',
StarredBranches = 'gitlens:starred:branches',
StarredRepositories = 'gitlens:starred:repositories',
ViewsRepositoriesAutoRefresh = 'gitlens:views:repositories:autoRefresh',