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',