Change:
With we're getting some initial terminal quick fixes. We have a bunch more ideas, let's use this issue to track adding more at a later date when we have more information on how the feature is received.
Also want to consider the setting to disable one or more of these
The open URL one (the only one I’ve seen so far) was a really pleasant surprise and I immediately adopted it into my workflow for opening a GitHub PR after pushing a new branch. Another one I would love to see is opening files with merge conflicts: <img width="615" alt="image" src="https://user-"
great idea!
I think this can be closed since we have individual issues tracking ideas

Discussion:
import { TerminalLinkQuickpick } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkQuickpick'; import { IRequestAddInstanceToGroupEvent, ITerminalQuickFixOptions, ITerminalExternalLinkProvider, ITerminalInstance, TerminalDataTransfers } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalLaunchHelpAction } from 'vs/workbench/contrib/terminal/browser/terminalActions'; <del> import { gitSimilarCommand, gitCreatePr, gitPushSetUpstream, freePort } from 'vs/workbench/contrib/terminal/browser/terminalQuickFixBuiltinActions'; </del> <ins> import { gitSimilarCommand, gitCreatePr, gitPushSetUpstream, freePort, gitTwoDashes } from 'vs/workbench/contrib/terminal/browser/terminalQuickFixBuiltinActions'; </ins> import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorInput'; import { TerminalFindWidget } from 'vs/workbench/contrib/terminal/browser/terminalFindWidget';

this.xterm = xterm; this._quickFixAddon = this._scopedInstantiationService.createInstance(TerminalQuickFixAddon, this.capabilities); this.xterm?.raw.loadAddon(this._quickFixAddon); <del> this.registerQuickFixProvider(gitSimilarCommand(), gitCreatePr(this._openerService), gitPushSetUpstream(), freePort(this)); </del> <ins> this.registerQuickFixProvider(gitSimilarCommand(), gitTwoDashes(), gitCreatePr(this._openerService), gitPushSetUpstream(), freePort(this)); </ins> this._register(this._quickFixAddon.onDidRequestRerunCommand((e) => this.sendText(e.command, e.addNewLine || false))); const lineDataEventAddon = new LineDataEventAddon(); this.xterm.raw.loadAddon(lineDataEventAddon);

export const GitCommandLineRegex = /git/; export const GitPushCommandLineRegex = /gits+push/; <ins> export const GitTwoDashesRegex = /error: did you mean `--(.+)` (with two dashes)?/; </ins> export const AnyCommandLineRegex = /.+/; export const GitSimilarOutputRegex = /most similar command iss*ns*([^s]{3,})/m; export const FreePortOutputRegex = /address already in use d+.d+.d+.d+:(d{4,5})|Unable to bind [^ ]*:(d{4,5})|can't listen on port (d{4,5})|listen EADDRINUSE [^ ]*:(d{4,5})/;

} }; } <ins> export function gitTwoDashes(): ITerminalQuickFixOptions { return { commandLineMatcher: GitCommandLineRegex, outputMatcher: { lineMatcher: GitTwoDashesRegex, anchor: 'bottom', offset: 0, length: 2 }, exitStatus: false, getQuickFixes: (matchResult: QuickFixMatchResult, command: ITerminalCommand) => { const actions: ITerminalQuickFixAction[] = []; const problemArg = matchResult?.outputMatch?.[1]; if (!problemArg) { return; } const commandToRunInTerminal = command.command.replace(` -${problemArg}`, ` --${problemArg}`); const label = localize("terminal.runCommand", "Run: {0}", commandToRunInTerminal); actions.push({ class: undefined, tooltip: label, id: 'terminal.gitTwoDashes', label, enabled: true, commandToRunInTerminal, addNewLine: true, run: () => { } }); return actions; } }; } </ins> export function freePort(terminalInstance?: Partial<ITerminalInstance>): ITerminalQuickFixOptions { return { commandLineMatcher: AnyCommandLineRegex,

import { CommandDetectionCapability } from 'vs/platform/terminal/common/capabilities/commandDetectionCapability'; import { TerminalCapabilityStore } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore'; import { ITerminalQuickFixAction, ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal'; <del> import { freePort, FreePortOutputRegex, gitCreatePr, GitCreatePrOutputRegex, GitPushOutputRegex, gitPushSetUpstream, gitSimilarCommand, GitSimilarOutputRegex } from 'vs/workbench/contrib/terminal/browser/terminalQuickFixBuiltinActions'; </del> <ins> import { freePort, FreePortOutputRegex, gitCreatePr, GitCreatePrOutputRegex, GitPushOutputRegex, gitPushSetUpstream, gitSimilarCommand, GitSimilarOutputRegex, gitTwoDashes, GitTwoDashesRegex } from 'vs/workbench/contrib/terminal/browser/terminalQuickFixBuiltinActions'; </ins> import { TerminalQuickFixAddon, getQuickFixes } from 'vs/workbench/contrib/terminal/browser/xterm/quickFixAddon'; import { Terminal } from 'xterm';

}); }); }); <ins> suite('gitTwoDashes', async () => { const expectedMap = new Map(); const command = `git add . -all`; const output = 'error: did you mean `--all` (with two dashes)?'; const exitCode = 1; const actions = [ { id: 'terminal.gitTwoDashes', label: 'Run: git add . --all', run: true, tooltip: 'Run: git add . --all', enabled: true } ]; setup(() => { const command = gitTwoDashes(); expectedMap.set(command.commandLineMatcher.toString(), [command]); quickFixAddon.registerCommandFinishedListener(command); }); suite('returns undefined when', () => { test('output does not match', () => { strictEqual(getQuickFixes(createCommand(command, `invalid output`, GitTwoDashesRegex, exitCode), expectedMap), undefined); }); test('command does not match', () => { strictEqual(getQuickFixes(createCommand(`gt sttatus`, output, GitTwoDashesRegex, exitCode), expectedMap), undefined); }); }); suite('returns undefined when', () => { test('expected unix exit code', () => { assertMatchOptions(getQuickFixes(createCommand(command, output, GitTwoDashesRegex, exitCode), expectedMap), actions); }); test('matching exit status', () => { assertMatchOptions(getQuickFixes(createCommand(command, output, GitTwoDashesRegex, 2), expectedMap), actions); }); }); }); </ins> if (!isWindows) { suite('freePort', () => { const expected = new Map();