From b54478d01abab1f595ee3bd7bfb3917207640a77 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Wed, 5 Feb 2025 05:35:30 +0100 Subject: [PATCH 1/3] Added git actions --- cursorless-talon/src/spoken_forms.json | 4 +++ .../common/src/ide/fake/FakeCapabilities.ts | 4 +++ packages/common/src/ide/types/CommandId.ts | 6 +++- packages/common/src/types/TextEditor.ts | 24 ++++++++++++++++ .../src/types/command/ActionDescriptor.ts | 4 +++ .../cursorless-engine/src/CommandHistory.ts | 4 +++ .../cursorless-engine/src/actions/Actions.ts | 18 +++++++++--- .../src/actions/SimpleIdeCommandActions.ts | 28 +++++++++++++++++++ .../spokenForms/defaultSpokenFormMapCore.ts | 4 +++ .../src/ide/TalonJsCapabilities.ts | 4 +++ .../src/ide/TalonJsEditor.ts | 16 +++++++++++ .../src/ide/vscode/VscodeCapabilities.ts | 4 +++ .../src/ide/vscode/VscodeTextEditorImpl.ts | 16 +++++++++++ .../src/ide/neovim/NeovimCapabilities.ts | 4 +++ .../src/ide/neovim/NeovimTextEditorImpl.ts | 16 +++++++++++ 15 files changed, 151 insertions(+), 5 deletions(-) diff --git a/cursorless-talon/src/spoken_forms.json b/cursorless-talon/src/spoken_forms.json index 013857a84b..9783f506b2 100644 --- a/cursorless-talon/src/spoken_forms.json +++ b/cursorless-talon/src/spoken_forms.json @@ -28,6 +28,10 @@ "fold": "foldRegion", "follow split": "followLinkAside", "follow": "followLink", + "git accept": "gitAccept", + "git add": "gitStage", + "git reset": "gitUnstage", + "git revert": "gitRevert", "give": "deselect", "highlight": "highlight", "hover": "showHover", diff --git a/packages/common/src/ide/fake/FakeCapabilities.ts b/packages/common/src/ide/fake/FakeCapabilities.ts index a295ee8645..72ea13b0e3 100644 --- a/packages/common/src/ide/fake/FakeCapabilities.ts +++ b/packages/common/src/ide/fake/FakeCapabilities.ts @@ -19,5 +19,9 @@ export class FakeCapabilities implements Capabilities { unfold: undefined, showReferences: undefined, insertLineAfter: undefined, + gitAccept: undefined, + gitRevert: undefined, + gitStage: undefined, + gitUnstage: undefined, }; } diff --git a/packages/common/src/ide/types/CommandId.ts b/packages/common/src/ide/types/CommandId.ts index 27da4d6ad0..594ef9a019 100644 --- a/packages/common/src/ide/types/CommandId.ts +++ b/packages/common/src/ide/types/CommandId.ts @@ -14,4 +14,8 @@ export type CommandId = | "showHover" | "showDebugHover" | "extractVariable" - | "insertLineAfter"; + | "insertLineAfter" + | "gitAccept" + | "gitRevert" + | "gitStage" + | "gitUnstage"; diff --git a/packages/common/src/types/TextEditor.ts b/packages/common/src/types/TextEditor.ts index 195ea3a2a5..e54f197b89 100644 --- a/packages/common/src/types/TextEditor.ts +++ b/packages/common/src/types/TextEditor.ts @@ -237,4 +237,28 @@ export interface EditableTextEditor extends TextEditor { * @param range A {@link Range range} */ extractVariable(range?: Range): Promise; + + /** + * Git accept conflict + * @param range A {@link Range range} + */ + gitAccept(range?: Range): Promise; + + /** + * Git revert + * @param range A {@link Range range} + */ + gitRevert(range?: Range): Promise; + + /** + * Git stage + * @param range A {@link Range range} + */ + gitStage(range?: Range): Promise; + + /** + * Git unstage + * @param range A {@link Range range} + */ + gitUnstage(range?: Range): Promise; } diff --git a/packages/common/src/types/command/ActionDescriptor.ts b/packages/common/src/types/command/ActionDescriptor.ts index ca9741ff77..4bbad94d29 100644 --- a/packages/common/src/types/command/ActionDescriptor.ts +++ b/packages/common/src/types/command/ActionDescriptor.ts @@ -27,6 +27,10 @@ export const simpleActionNames = [ "foldRegion", "followLink", "followLinkAside", + "gitAccept", + "gitRevert", + "gitStage", + "gitUnstage", "increment", "indentLine", "insertCopyAfter", diff --git a/packages/cursorless-engine/src/CommandHistory.ts b/packages/cursorless-engine/src/CommandHistory.ts index b1f83a0a15..bbe29c379f 100644 --- a/packages/cursorless-engine/src/CommandHistory.ts +++ b/packages/cursorless-engine/src/CommandHistory.ts @@ -160,6 +160,10 @@ function sanitizeActionInPlace(action: ActionDescriptor): void { case "followLinkAside": case "generateSnippet": case "getText": + case "gitAccept": + case "gitRevert": + case "gitStage": + case "gitUnstage": case "highlight": case "increment": case "indentLine": diff --git a/packages/cursorless-engine/src/actions/Actions.ts b/packages/cursorless-engine/src/actions/Actions.ts index 3566916a68..319e63f2fb 100644 --- a/packages/cursorless-engine/src/actions/Actions.ts +++ b/packages/cursorless-engine/src/actions/Actions.ts @@ -49,6 +49,10 @@ import ShowParseTree from "./ShowParseTree"; import { ExtractVariable, Fold, + GitAccept, + GitRevert, + GitStage, + GitUnstage, Rename, RevealDefinition, RevealTypeDefinition, @@ -105,6 +109,10 @@ export class Actions implements ActionRecord { followLinkAside = new FollowLink({ openAside: true }); generateSnippet = new GenerateSnippet(this.snippets); getText = new GetText(); + gitAccept = new GitAccept(this.rangeUpdater); + gitRevert = new GitRevert(this.rangeUpdater); + gitStage = new GitStage(this.rangeUpdater); + gitUnstage = new GitUnstage(this.rangeUpdater); highlight = new Highlight(); increment = new Increment(this); indentLine = new IndentLine(this.rangeUpdater); @@ -154,10 +162,6 @@ export class Actions implements ActionRecord { scrollToBottom = new ScrollToBottom(); scrollToCenter = new ScrollToCenter(); scrollToTop = new ScrollToTop(); - ["private.setKeyboardTarget"] = new SetSpecialTarget("keyboard"); - ["experimental.setInstanceReference"] = new SetSpecialTarget( - "instanceReference", - ); setSelection = new SetSelection(); setSelectionAfter = new SetSelectionAfter(); setSelectionBefore = new SetSelectionBefore(); @@ -176,6 +180,12 @@ export class Actions implements ActionRecord { this.snippets, this.modifierStageFactory, ); + + ["experimental.setInstanceReference"] = new SetSpecialTarget( + "instanceReference", + ); + ["private.showParseTree"] = new ShowParseTree(this.treeSitter); ["private.getTargets"] = new GetTargets(); + ["private.setKeyboardTarget"] = new SetSpecialTarget("keyboard"); } diff --git a/packages/cursorless-engine/src/actions/SimpleIdeCommandActions.ts b/packages/cursorless-engine/src/actions/SimpleIdeCommandActions.ts index 9ee59e3e0a..9b9093fcc9 100644 --- a/packages/cursorless-engine/src/actions/SimpleIdeCommandActions.ts +++ b/packages/cursorless-engine/src/actions/SimpleIdeCommandActions.ts @@ -128,6 +128,26 @@ export class ExtractVariable extends SimpleIdeCommandAction { restoreSelection = false; } +export class GitAccept extends SimpleIdeCommandAction { + command: CommandId = "gitAccept"; + ensureSingleTarget = true; +} + +export class GitRevert extends SimpleIdeCommandAction { + command: CommandId = "gitRevert"; + ensureSingleTarget = true; +} + +export class GitStage extends SimpleIdeCommandAction { + command: CommandId = "gitStage"; + ensureSingleTarget = true; +} + +export class GitUnstage extends SimpleIdeCommandAction { + command: CommandId = "gitUnstage"; + ensureSingleTarget = true; +} + function callback( editor: EditableTextEditor, ranges: Range[] | undefined, @@ -167,6 +187,14 @@ function callback( return editor.showDebugHover(ranges?.[0]); case "extractVariable": return editor.extractVariable(ranges?.[0]); + case "gitAccept": + return editor.gitAccept(ranges?.[0]); + case "gitRevert": + return editor.gitRevert(ranges?.[0]); + case "gitStage": + return editor.gitStage(ranges?.[0]); + case "gitUnstage": + return editor.gitUnstage(ranges?.[0]); // Unsupported as simple action case "highlight": diff --git a/packages/cursorless-engine/src/spokenForms/defaultSpokenFormMapCore.ts b/packages/cursorless-engine/src/spokenForms/defaultSpokenFormMapCore.ts index 40c2794fdc..5b0a74d5fa 100644 --- a/packages/cursorless-engine/src/spokenForms/defaultSpokenFormMapCore.ts +++ b/packages/cursorless-engine/src/spokenForms/defaultSpokenFormMapCore.ts @@ -204,6 +204,10 @@ export const defaultSpokenFormMapCore: DefaultSpokenFormMapDefinition = { insertSnippet: "snippet", pasteFromClipboard: "paste", joinLines: "join", + gitAccept: "git accept", + gitRevert: "git revert", + gitStage: "git add", + gitUnstage: "git reset", ["private.showParseTree"]: isPrivate("parse tree"), ["experimental.setInstanceReference"]: isDisabledByDefault("from"), diff --git a/packages/cursorless-everywhere-talon-core/src/ide/TalonJsCapabilities.ts b/packages/cursorless-everywhere-talon-core/src/ide/TalonJsCapabilities.ts index 49db40e82d..b68eb0c739 100644 --- a/packages/cursorless-everywhere-talon-core/src/ide/TalonJsCapabilities.ts +++ b/packages/cursorless-everywhere-talon-core/src/ide/TalonJsCapabilities.ts @@ -18,6 +18,10 @@ const COMMAND_CAPABILITIES: CommandCapabilityMap = { insertLineAfter: undefined, indentLine: undefined, outdentLine: undefined, + gitAccept: undefined, + gitRevert: undefined, + gitStage: undefined, + gitUnstage: undefined, }; export class TalonJsCapabilities implements Capabilities { diff --git a/packages/cursorless-everywhere-talon-core/src/ide/TalonJsEditor.ts b/packages/cursorless-everywhere-talon-core/src/ide/TalonJsEditor.ts index 2d51df7b3e..da4264bac2 100644 --- a/packages/cursorless-everywhere-talon-core/src/ide/TalonJsEditor.ts +++ b/packages/cursorless-everywhere-talon-core/src/ide/TalonJsEditor.ts @@ -154,4 +154,20 @@ export class TalonJsEditor implements EditableTextEditor { editNewNotebookCellBelow(): Promise { throw new Error("editNewNotebookCellBelow not implemented."); } + + public async gitAccept(_range?: Range): Promise { + throw Error("gitAccept not implemented"); + } + + public async gitRevert(_range?: Range): Promise { + throw Error("gitRevert not implemented"); + } + + public async gitStage(_range?: Range): Promise { + throw Error("gitStage not implemented"); + } + + public async gitUnstage(_range?: Range): Promise { + throw Error("gitUnstage not implemented"); + } } diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeCapabilities.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeCapabilities.ts index 99ad6ee005..f1765e60e8 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeCapabilities.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeCapabilities.ts @@ -18,6 +18,10 @@ const COMMAND_CAPABILITIES: CommandCapabilityMap = { unfold: { acceptsLocation: true }, showReferences: { acceptsLocation: false }, insertLineAfter: { acceptsLocation: false }, + gitAccept: { acceptsLocation: false }, + gitRevert: { acceptsLocation: false }, + gitStage: { acceptsLocation: false }, + gitUnstage: { acceptsLocation: false }, }; export class VscodeCapabilities implements Capabilities { diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeTextEditorImpl.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeTextEditorImpl.ts index b78f766385..e86065b41c 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeTextEditorImpl.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeTextEditorImpl.ts @@ -242,4 +242,20 @@ export class VscodeTextEditorImpl implements EditableTextEditor { await sleep(250); } + + public async gitAccept(_range?: Range): Promise { + await vscode.commands.executeCommand("merge-conflict.accept.selection"); + } + + public async gitRevert(_range?: Range): Promise { + await vscode.commands.executeCommand("git.revertSelectedRanges"); + } + + public async gitStage(_range?: Range): Promise { + await vscode.commands.executeCommand("git.stageSelectedRanges"); + } + + public async gitUnstage(_range?: Range): Promise { + await vscode.commands.executeCommand("git.unstageSelectedRanges"); + } } diff --git a/packages/neovim-common/src/ide/neovim/NeovimCapabilities.ts b/packages/neovim-common/src/ide/neovim/NeovimCapabilities.ts index f7e2e58e1c..0b5a98e27f 100644 --- a/packages/neovim-common/src/ide/neovim/NeovimCapabilities.ts +++ b/packages/neovim-common/src/ide/neovim/NeovimCapabilities.ts @@ -18,6 +18,10 @@ const COMMAND_CAPABILITIES: CommandCapabilityMap = { unfold: undefined, showReferences: undefined, insertLineAfter: undefined, + gitAccept: undefined, + gitRevert: undefined, + gitStage: undefined, + gitUnstage: undefined, }; export class NeovimCapabilities implements Capabilities { diff --git a/packages/neovim-common/src/ide/neovim/NeovimTextEditorImpl.ts b/packages/neovim-common/src/ide/neovim/NeovimTextEditorImpl.ts index cc198be151..8671e17cde 100644 --- a/packages/neovim-common/src/ide/neovim/NeovimTextEditorImpl.ts +++ b/packages/neovim-common/src/ide/neovim/NeovimTextEditorImpl.ts @@ -190,4 +190,20 @@ export class NeovimTextEditorImpl implements EditableTextEditor { public async extractVariable(_range?: Range): Promise { throw Error("extractVariable Not implemented"); } + + public async gitAccept(_range?: Range): Promise { + throw Error("gitAccept Not implemented"); + } + + public async gitRevert(_range?: Range): Promise { + throw Error("gitRevert Not implemented"); + } + + public async gitStage(_range?: Range): Promise { + throw Error("gitStage Not implemented"); + } + + public async gitUnstage(_range?: Range): Promise { + throw Error("gitUnstage Not implemented"); + } } From 03dadd83feebd0730e56a646388747ce1e7c0440 Mon Sep 17 00:00:00 2001 From: Phil Cohen Date: Wed, 5 Feb 2025 21:44:42 -0800 Subject: [PATCH 2/3] Apply suggestions from code review --- packages/common/src/types/TextEditor.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/common/src/types/TextEditor.ts b/packages/common/src/types/TextEditor.ts index e54f197b89..894fbce780 100644 --- a/packages/common/src/types/TextEditor.ts +++ b/packages/common/src/types/TextEditor.ts @@ -239,25 +239,25 @@ export interface EditableTextEditor extends TextEditor { extractVariable(range?: Range): Promise; /** - * Git accept conflict + * Git accept conflict (use the range to resolve a conflict hunk) * @param range A {@link Range range} */ gitAccept(range?: Range): Promise; /** - * Git revert + * Git revert range * @param range A {@link Range range} */ gitRevert(range?: Range): Promise; /** - * Git stage + * Git stage range * @param range A {@link Range range} */ gitStage(range?: Range): Promise; /** - * Git unstage + * Git unstage range * @param range A {@link Range range} */ gitUnstage(range?: Range): Promise; From f0b91c3a7c0cb2ebc996f2bf6fffa7222f23f358 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 6 Feb 2025 06:46:08 +0100 Subject: [PATCH 3/3] Update spoken forms --- cursorless-talon/src/spoken_forms.json | 4 ++-- .../src/spokenForms/defaultSpokenFormMapCore.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cursorless-talon/src/spoken_forms.json b/cursorless-talon/src/spoken_forms.json index 9783f506b2..3db74a362c 100644 --- a/cursorless-talon/src/spoken_forms.json +++ b/cursorless-talon/src/spoken_forms.json @@ -29,8 +29,8 @@ "follow split": "followLinkAside", "follow": "followLink", "git accept": "gitAccept", - "git add": "gitStage", - "git reset": "gitUnstage", + "git stage": "gitStage", + "git unstage": "gitUnstage", "git revert": "gitRevert", "give": "deselect", "highlight": "highlight", diff --git a/packages/cursorless-engine/src/spokenForms/defaultSpokenFormMapCore.ts b/packages/cursorless-engine/src/spokenForms/defaultSpokenFormMapCore.ts index 5b0a74d5fa..a790304c57 100644 --- a/packages/cursorless-engine/src/spokenForms/defaultSpokenFormMapCore.ts +++ b/packages/cursorless-engine/src/spokenForms/defaultSpokenFormMapCore.ts @@ -206,8 +206,8 @@ export const defaultSpokenFormMapCore: DefaultSpokenFormMapDefinition = { joinLines: "join", gitAccept: "git accept", gitRevert: "git revert", - gitStage: "git add", - gitUnstage: "git reset", + gitStage: "git stage", + gitUnstage: "git unstage", ["private.showParseTree"]: isPrivate("parse tree"), ["experimental.setInstanceReference"]: isDisabledByDefault("from"),