Skip to content
This repository was archived by the owner on Aug 1, 2025. It is now read-only.

25 files changed

+403
-267
lines changed

lib/shared/src/commands/types.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,14 @@ export enum DefaultEditCommands {
1717

1818
// The blueprint of a Cody Custom Command
1919
export interface CodyCommand {
20-
slashCommand: string
20+
/**
21+
* @deprecated Use 'commandKey' instead.
22+
*/
23+
slashCommand?: string
24+
/**
25+
* key of the command, e.g. 'smell' for Code Smell
26+
*/
27+
key: string
2128
prompt: string
2229
description?: string
2330
context?: CodyCommandContext

lib/shared/src/common/platform.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,7 @@ export function isWindows(): boolean {
1414

1515
return false // default
1616
}
17+
18+
export const isPlatform = (platform: string) => process.platform === platform
19+
20+
export const isMac = () => isPlatform('darwin')

vscode/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ This is a log of all notable changes to Cody for VS Code. [Unreleased] changes a
1515
- Autocomplete: Removes the latency for cached completions. [https://github.com/sourcegraph/cody/pull/3138](https://github.com/sourcegraph/cody/pull/3138)
1616
- Autocomplete: Enable the recent jaccard similarity improvements by default. [pull/3135](https://github.com/sourcegraph/cody/pull/3135)
1717
- Autocomplete: Start retrieval phase earlier to improve latency. [pull/3149](https://github.com/sourcegraph/cody/pull/3149)
18+
- Command: Leading slashes are removed from command names in the command menu. [pull/3061](https://github.com/sourcegraph/cody/pull/3061)
1819

1920
## [1.4.3]
2021

vscode/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,11 @@
515515
"mac": "alt+c",
516516
"when": "cody.activated"
517517
},
518+
{
519+
"command": "cody.menu.custom-commands",
520+
"key": "shift+alt+c",
521+
"when": "cody.activated"
522+
},
518523
{
519524
"command": "-github.copilot.generate",
520525
"key": "ctrl+enter"

vscode/src/commands/CommandsController.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { CommandRunner } from './services/runner'
77
import type { CommandsProvider } from './services/provider'
88
import type { CommandResult } from '../main'
99
import { executeDefaultCommand, isDefaultChatCommand, isDefaultEditCommand } from './execute'
10+
import { fromSlashCommand } from './utils/common'
1011

1112
/**
1213
* Handles commands execution with commands from CommandsProvider
@@ -30,16 +31,17 @@ class CommandsController implements vscode.Disposable {
3031
*
3132
* Handles prompt building and context fetching for commands.
3233
*/
33-
public async execute(text: string, args: CodyCommandArgs): Promise<CommandResult | undefined> {
34-
const commandSplit = text?.trim().split(' ')
35-
// The unique key for the command. e.g. /test
36-
const commandKey = commandSplit[0] || text
37-
34+
public async execute(input: string, args: CodyCommandArgs): Promise<CommandResult | undefined> {
35+
// Split the input by space to extract the command key and additional input (if any)
36+
const commandSplit = input?.trim().split(' ')
37+
// The unique key for the command. e.g. test, smell, explain
38+
// Using fromSlashCommand to support backward compatibility with old slash commands
39+
const commandKey = fromSlashCommand(commandSplit[0] || input)
3840
// Additional instruction that will be added to end of prompt in the custom command prompt
3941
// It's added at execution time to allow dynamic arguments
40-
// E.g. if the command is `/edit replace dash with period`,
42+
// E.g. if the command is `edit replace dash with period`,
4143
// the additionalInput is `replace dash with period`
42-
const additionalInstruction = commandKey === text ? '' : commandSplit.slice(1).join(' ')
44+
const additionalInstruction = commandKey === input ? '' : commandSplit.slice(1).join(' ')
4345

4446
// Process default commands
4547
if (isDefaultChatCommand(commandKey) || isDefaultEditCommand(commandKey)) {

vscode/src/commands/index.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import type { CodySidebarTreeItem } from '../services/treeViewItems'
2+
import { isMac } from '@sourcegraph/cody-shared/src/common/platform'
3+
4+
const osIcon = isMac() ? '⌥' : 'Alt+'
5+
6+
export const CodyCommandMenuItems = [
7+
{
8+
key: 'ask',
9+
description: 'New Chat',
10+
prompt: 'Start a new chat',
11+
icon: 'comment',
12+
command: { command: 'cody.chat.panel.new' },
13+
keybinding: `${osIcon}L`,
14+
mode: 'ask',
15+
type: 'default',
16+
},
17+
{
18+
key: 'edit',
19+
description: 'Edit Code',
20+
prompt: 'Start a code edit',
21+
icon: 'wand',
22+
command: { command: 'cody.command.edit-code' },
23+
keybinding: `${osIcon}K`,
24+
mode: 'edit',
25+
type: 'default',
26+
},
27+
{
28+
key: 'doc',
29+
description: 'Document Code',
30+
icon: 'book',
31+
command: { command: 'cody.command.document-code' },
32+
keybinding: '',
33+
mode: 'edit',
34+
type: 'default',
35+
},
36+
{
37+
key: 'explain',
38+
description: 'Explain Code',
39+
icon: 'file-binary',
40+
command: { command: 'cody.command.explain-code' },
41+
keybinding: '',
42+
mode: 'ask',
43+
type: 'default',
44+
},
45+
{
46+
key: 'test',
47+
description: 'Generate Unit Tests',
48+
icon: 'package',
49+
command: { command: 'cody.command.unit-tests' },
50+
keybinding: '',
51+
mode: 'edit',
52+
type: 'default',
53+
},
54+
{
55+
key: 'smell',
56+
description: 'Find Code Smells',
57+
icon: 'checklist',
58+
command: { command: 'cody.command.smell-code' },
59+
keybinding: '',
60+
mode: 'ask',
61+
type: 'default',
62+
},
63+
{
64+
key: 'custom',
65+
description: 'Custom Commands',
66+
icon: 'tools',
67+
command: { command: 'cody.menu.custom-commands' },
68+
keybinding: `${osIcon}⇧C`,
69+
type: 'default',
70+
},
71+
]
72+
73+
export function getCommandTreeItems(): CodySidebarTreeItem[] {
74+
return CodyCommandMenuItems.map(item => {
75+
return {
76+
...item,
77+
title: item.description,
78+
description: item.keybinding,
79+
}
80+
})
81+
}

vscode/src/commands/menus/command-builder.ts

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,20 @@ import type { CodyCommand } from '@sourcegraph/cody-shared'
44

55
import { customPromptsContextOptions } from './items'
66
import { CustomCommandType } from '@sourcegraph/cody-shared/src/commands/types'
7-
import { toSlashCommand } from '../utils/common'
7+
import { fromSlashCommand } from '../utils/common'
8+
import { telemetryService } from '../../services/telemetry'
9+
import { telemetryRecorder } from '../../services/telemetry-v2'
810

911
export interface CustomCommandsBuilder {
10-
slashCommand: string
12+
key: string
1113
prompt: CodyCommand
1214
type: CustomCommandType
1315
}
1416

1517
export class CustomCommandsBuilderMenu {
1618
public async start(commands: string[]): Promise<CustomCommandsBuilder | null> {
17-
const slashCommand = await this.makeSlashCommand(commands)
18-
if (!slashCommand) {
19+
const key = await this.makeCommandKey(commands)
20+
if (!key) {
1921
return null
2022
}
2123

@@ -29,36 +31,37 @@ export class CustomCommandsBuilderMenu {
2931
return null
3032
}
3133

32-
return { slashCommand, prompt: { ...prompt, slashCommand }, type }
34+
telemetryService.log('CodyVSCodeExtension:command:custom:build:executed')
35+
telemetryRecorder.recordEvent('cody.command.custom.build', 'executed')
36+
return { key, prompt: { ...prompt, key }, type }
3337
}
3438

35-
private async makeSlashCommand(commands: string[]): Promise<string | undefined> {
39+
private async makeCommandKey(commands: string[]): Promise<string | undefined> {
3640
const commandSet = new Set(commands)
37-
let value = await window.showInputBox({
38-
title: 'New Custom Cody Command: Slash Name',
39-
prompt: 'Enter the slash name of the custom command',
40-
placeHolder: 'e.g. /name',
41+
const value = await window.showInputBox({
42+
title: 'New Custom Cody Command: Command Name',
43+
prompt: 'Enter the name of the custom command.',
44+
placeHolder: 'e.g. hello',
4145
ignoreFocusOut: true,
4246
validateInput: (input: string) => {
4347
if (!input) {
44-
return 'Slash name cannot be empty.'
48+
return 'Command name cannot be empty.'
4549
}
4650
if (input.split(' ').length > 1) {
47-
return 'Slash name cannot contain spaces. Use dashes, underscores, or camelCase.'
51+
return 'Command name cannot contain spaces. Use dashes, underscores, or camelCase.'
4852
}
49-
if (commandSet.has(toSlashCommand(input))) {
50-
return 'A command with the slash name already exists.'
53+
// Remove leading slash before checking if command already exists
54+
if (commandSet.has(fromSlashCommand(input))) {
55+
return 'A command with the same name already exists.'
5156
}
5257
return
5358
},
5459
})
55-
if (value) {
56-
value = toSlashCommand(value)
57-
}
60+
5861
return value
5962
}
6063

61-
private async makePrompt(): Promise<Omit<CodyCommand, 'slashCommand'> | null> {
64+
private async makePrompt(): Promise<Omit<CodyCommand, 'key'> | null> {
6265
const prompt = await window.showInputBox({
6366
title: 'New Custom Cody Command: Prompt',
6467
prompt: 'Enter the instructions for Cody to follow and answer.',

0 commit comments

Comments
 (0)