Skip to content

Commit

Permalink
keyboard: Use parser for key sequences (#2051)
Browse files Browse the repository at this point in the history
## Checklist

- [x] I have added
[tests](https://www.cursorless.org/docs/contributing/test-case-recorder/)
- [-] I have updated the
[docs](https://github.com/cursorless-dev/cursorless/tree/main/docs) and
[cheatsheet](https://github.com/cursorless-dev/cursorless/tree/main/cursorless-talon/src/cheatsheet)
(keeping this somewhat under wraps while we experiment
- [x] I have not broken the cheatsheet
- [-] Refactor delete mapping to just issue token for delete action
- [x] Extract partial parameters
- [-] Add railroad to docs?
  • Loading branch information
pokey authored Dec 5, 2023
1 parent 4844109 commit 7a51850
Show file tree
Hide file tree
Showing 47 changed files with 1,955 additions and 256 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ trim_trailing_whitespace = false
[Makefile]
indent_style = tab

[**/vendor/**]
[**/{vendor,generated}/**]
charset = unset
end_of_line = unset
indent_size = unset
Expand Down
7 changes: 6 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,10 @@
}
}
},
"ignorePatterns": ["**/vendor/**/*.ts", "**/vendor/**/*.js", "**/out/**"]
"ignorePatterns": [
"**/vendor/**/*.ts",
"**/vendor/**/*.js",
"**/out/**",
"**/generated/**"
]
}
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ repos:
# tests use strings with trailing white space to represent the final
# document contents. For example
# packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/ruby/changeCondition.yml
exclude: ^packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/.*/[^/]*\.yml$
exclude: ^packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/.*/[^/]*\.yml$|/generated/|^patches/
- repo: local
hooks:
- id: eslint
Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
**/vendor
**/generated

# We use our own format for our recorded yaml tests to keep them compact
/packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/**/*.yml
Expand Down
11 changes: 11 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"type": "npm",
"script": "esbuild",
"path": "packages/cursorless-vscode",
"dependsOn": ["Generate grammar"],
"presentation": {
"reveal": "silent"
},
Expand Down Expand Up @@ -61,6 +62,16 @@
},
"group": "build"
},
{
"label": "Generate grammar",
"type": "npm",
"script": "generate-grammar",
"path": "packages/cursorless-vscode",
"presentation": {
"reveal": "silent"
},
"group": "build"
},
{
"label": "Ensure test subset file exists",
"type": "npm",
Expand Down
10 changes: 5 additions & 5 deletions docs/user/experimental/keyboard/modal.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ The above allows you to press `ctrl-c` to switch to Cursorless mode, `escape` to
To bind keys that do not have modifiers (eg just pressing `a`), add entries like the following to your [VSCode `settings.json`](https://code.visualstudio.com/docs/getstarted/settings#_settingsjson) (or edit these settings in the VSCode settings gui by saying `"cursorless settings"`):

```json
"cursorless.experimental.keyboard.modal.keybindings.scopes": {
"cursorless.experimental.keyboard.modal.keybindings.scope": {
"i": "line",
"p": "paragraph",
";": "statement",
Expand All @@ -60,7 +60,7 @@ To bind keys that do not have modifiers (eg just pressing `a`), add entries like
"sa": "argumentOrParameter",
"sl": "url",
},
"cursorless.experimental.keyboard.modal.keybindings.actions": {
"cursorless.experimental.keyboard.modal.keybindings.action": {
"t": "setSelection",
"h": "setSelectionBefore",
"l": "setSelectionAfter",
Expand All @@ -81,13 +81,13 @@ To bind keys that do not have modifiers (eg just pressing `a`), add entries like
"ap": "pasteFromClipboard",
"ad": "followLink"
},
"cursorless.experimental.keyboard.modal.keybindings.colors": {
"cursorless.experimental.keyboard.modal.keybindings.color": {
"d": "default",
"b": "blue",
"g": "yellow",
"r": "red"
},
"cursorless.experimental.keyboard.modal.keybindings.shapes": {
"cursorless.experimental.keyboard.modal.keybindings.shape": {
"x": "ex",
"f": "fox",
"q": "frame",
Expand All @@ -97,7 +97,7 @@ To bind keys that do not have modifiers (eg just pressing `a`), add entries like
"z": "bolt",
"w": "crosshairs"
},
"cursorless.experimental.keyboard.modal.keybindings.vscodeCommands": {
"cursorless.experimental.keyboard.modal.keybindings.vscodeCommand": {
// For simple commands, just use the command name
// "aa": "workbench.action.editor.changeLanguageMode",

Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@
},
"pnpm": {
"patchedDependencies": {
"@docusaurus/[email protected]": "patches/@[email protected]"
"@docusaurus/[email protected]": "patches/@[email protected]",
"@types/[email protected]": "patches/@[email protected]",
"[email protected]": "patches/[email protected]"
},
"peerDependencyRules": {
"ignoreMissing": [
Expand Down
1 change: 1 addition & 0 deletions packages/common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@types/mocha": "^10.0.3",
"@types/sinon": "^10.0.2",
"cross-spawn": "7.0.3",
"fast-check": "3.12.0",
"js-yaml": "^4.1.0",
"mocha": "^10.2.0",
"sinon": "^11.1.1"
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export * from "./types/GeneralizedRange";
export * from "./types/RangeOffsets";
export * from "./util/omitByDeep";
export * from "./util/range";
export * from "./util/uniqWithHash";
export * from "./testUtil/isTesting";
export * from "./testUtil/testConstants";
export * from "./testUtil/getFixturePaths";
Expand Down
5 changes: 5 additions & 0 deletions packages/common/src/util/CompositeKeyMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,9 @@ export class CompositeKeyMap<K, V> {
delete this.map[this.hash(key)];
return this;
}

clear(): this {
this.map = {};
return this;
}
}
File renamed without changes.
1 change: 0 additions & 1 deletion packages/cursorless-engine/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
"@types/mocha": "^10.0.3",
"@types/sbd": "^1.0.3",
"@types/sinon": "^10.0.2",
"fast-check": "3.12.0",
"js-yaml": "^4.1.0",
"mocha": "^10.2.0",
"sinon": "^11.1.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Modifier,
Range,
ScopeType,
uniqWithHash,
} from "@cursorless/common";
import { zip } from "lodash";
import {
Expand All @@ -15,11 +16,10 @@ import { Target } from "../typings/target.types";
import { MarkStageFactory } from "./MarkStageFactory";
import { ModifierStageFactory } from "./ModifierStageFactory";
import { MarkStage, ModifierStage } from "./PipelineStages.types";
import { createContinuousRangeTarget } from "./createContinuousRangeTarget";
import { ImplicitStage } from "./marks/ImplicitStage";
import { ContainingTokenIfUntypedEmptyStage } from "./modifiers/ConditionalModifierStages";
import { PlainTarget } from "./targets";
import { uniqWithHash } from "../util/uniqWithHash";
import { createContinuousRangeTarget } from "./createContinuousRangeTarget";

export class TargetPipelineRunner {
constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { EditableTextEditor, Selection } from "@cursorless/common";

import { uniqWithHash } from "./uniqWithHash";
import {
EditableTextEditor,
Selection,
uniqWithHash,
} from "@cursorless/common";

export async function setSelectionsAndFocusEditor(
editor: EditableTextEditor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@ import { getCursorlessApi, openNewEditor } from "@cursorless/vscode-common";
import { assert } from "chai";
import * as vscode from "vscode";
import { endToEndTestSetup, sleepWithBackoff } from "../../endToEndTestSetup";
import sinon from "sinon";
import path from "path";
import { getCursorlessRepoRoot } from "@cursorless/common";
import { readFile } from "node:fs/promises";

suite("Basic keyboard test", async function () {
endToEndTestSetup(this);

this.beforeEach(async () => {
await injectFakes();
});

this.afterEach(async () => {
await vscode.commands.executeCommand("cursorless.keyboard.modal.modeOff");
});
Expand Down Expand Up @@ -46,7 +54,7 @@ async function basic() {
await typeText("sf");

// Select target
await typeText("t");
await typeText("at");

assert.isTrue(editor.selection.isEqual(new vscode.Selection(0, 0, 0, 17)));

Expand All @@ -73,16 +81,16 @@ async function vscodeCommand() {
await typeText("db");

// Comment line containing *selection*
await typeText("c");
await typeText("va");
assert.equal(editor.document.getText(), "// aaa;\nbbb;\nccc;\n");

// Comment line containing *target*
await typeText("mc");
await typeText("vb");
assert.equal(editor.document.getText(), "// aaa;\n// bbb;\nccc;\n");

// Comment line containing *target*, keeping changed selection and exiting
// cursorless mode
await typeText("dcmma");
await typeText("dcvca");
assert.equal(editor.document.getText(), "// aaa;\n// bbb;\n// a;\n");

await vscode.commands.executeCommand("cursorless.keyboard.modal.modeOff");
Expand Down Expand Up @@ -111,3 +119,38 @@ async function typeText(text: string) {
await sleepWithBackoff(100);
}
}

async function injectFakes(): Promise<void> {
const { vscodeApi } = (await getCursorlessApi()).testHelpers!;

const keyboardConfigPath = path.join(
getCursorlessRepoRoot(),
"packages/cursorless-vscode/src/keyboard/keyboard-config.fixture.json",
);

const keyboardConfig = JSON.parse(await readFile(keyboardConfigPath, "utf8"));

const getConfigurationValue = sinon.fake((sectionName) => {
return keyboardConfig[
`cursorless.experimental.keyboard.modal.keybindings.${sectionName}`
];
});

sinon.replace(
vscodeApi.workspace,
"getConfiguration",
sinon.fake((section) => {
if (
!section?.startsWith(
"cursorless.experimental.keyboard.modal.keybindings",
)
) {
return vscode.workspace.getConfiguration(section);
}

return {
get: getConfigurationValue,
} as unknown as vscode.WorkspaceConfiguration;
}),
);
}
20 changes: 14 additions & 6 deletions packages/cursorless-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@
"description": "Directory containing snippets for use in Cursorless",
"type": "string"
},
"cursorless.experimental.keyboard.modal.keybindings.actions": {
"cursorless.experimental.keyboard.modal.keybindings.action": {
"description": "Define modal keybindings for actions",
"type": "object",
"additionalProperties": {
Expand Down Expand Up @@ -909,7 +909,7 @@
]
}
},
"cursorless.experimental.keyboard.modal.keybindings.vscodeCommands": {
"cursorless.experimental.keyboard.modal.keybindings.vscodeCommand": {
"description": "Define modal keybindings for running vscode commands",
"type": "object",
"additionalProperties": {
Expand Down Expand Up @@ -944,7 +944,7 @@
]
}
},
"cursorless.experimental.keyboard.modal.keybindings.colors": {
"cursorless.experimental.keyboard.modal.keybindings.color": {
"description": "Define modal keybindings for colors",
"type": "object",
"additionalProperties": {
Expand All @@ -961,7 +961,7 @@
]
}
},
"cursorless.experimental.keyboard.modal.keybindings.shapes": {
"cursorless.experimental.keyboard.modal.keybindings.shape": {
"description": "Define modal keybindings for shapes",
"type": "object",
"additionalProperties": {
Expand All @@ -980,7 +980,7 @@
]
}
},
"cursorless.experimental.keyboard.modal.keybindings.scopes": {
"cursorless.experimental.keyboard.modal.keybindings.scope": {
"description": "Define modal keybindings for scopes",
"type": "object",
"additionalProperties": {
Expand Down Expand Up @@ -1091,7 +1091,7 @@
"funding": "https://github.com/sponsors/pokey",
"scripts": {
"build": "pnpm run esbuild:prod && pnpm -F cheatsheet-local build:prod && pnpm run populate-dist",
"build:dev": "pnpm run esbuild && pnpm -F cheatsheet-local build && pnpm run populate-dist",
"build:dev": "pnpm generate-grammar && pnpm run esbuild && pnpm -F cheatsheet-local build && pnpm run populate-dist",
"esbuild:base": "esbuild ./src/extension.ts --conditions=cursorless:bundler --bundle --outfile=dist/extension.cjs --external:vscode --format=cjs --platform=node",
"install-local": "bash ./scripts/install-local.sh",
"install-from-pr": "bash ./scripts/install-from-pr.sh",
Expand All @@ -1104,6 +1104,11 @@
"preprocess-svg-hats": "my-ts-node src/scripts/preprocessSvgHats.ts",
"hat-adjustment-add": "my-ts-node src/scripts/hatAdjustments/add.ts",
"hat-adjustment-average": "my-ts-node src/scripts/hatAdjustments/average.ts",
"generate-grammar:base": "nearleyc src/keyboard/grammar/grammar.ne",
"ensure-grammar-up-to-date": "pnpm -s generate-grammar:base | diff -u src/keyboard/grammar/generated/grammar.ts -",
"generate-grammar": "pnpm generate-grammar:base -o src/keyboard/grammar/generated/grammar.ts",
"generate-railroad": "nearley-railroad src/keyboard/grammar/grammar.ne -o out/railroad.html",
"test": "pnpm ensure-grammar-up-to-date",
"compile": "tsc --build",
"watch": "tsc --build --watch",
"clean": "rm -rf ./out tsconfig.tsbuildinfo ./dist ./build"
Expand All @@ -1115,6 +1120,7 @@
"@types/js-yaml": "^4.0.2",
"@types/lodash": "4.14.181",
"@types/mocha": "^10.0.3",
"@types/nearley": "2.11.5",
"@types/node": "^18.18.2",
"@types/semver": "^7.3.9",
"@types/sinon": "^10.0.2",
Expand All @@ -1135,8 +1141,10 @@
"@cursorless/vscode-common": "workspace:*",
"itertools": "^2.1.1",
"lodash": "^4.17.21",
"nearley": "2.20.1",
"semver": "^7.5.2",
"tinycolor2": "1.6.0",
"trie-search": "2.0.0",
"uuid": "^9.0.0",
"vscode-uri": "^3.0.6"
},
Expand Down
6 changes: 5 additions & 1 deletion packages/cursorless-vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,11 @@ export async function activate(
addCommandRunnerDecorator(testCaseRecorder);

const statusBarItem = StatusBarItem.create("cursorless.showQuickPick");
const keyboardCommands = KeyboardCommands.create(context, statusBarItem);
const keyboardCommands = KeyboardCommands.create(
context,
vscodeApi,
statusBarItem,
);
const scopeVisualizer = createScopeVisualizer(normalizedIde, scopeProvider);
context.subscriptions.push(
revisualizeOnCustomRegexChange(scopeVisualizer, scopeProvider),
Expand Down
Loading

0 comments on commit 7a51850

Please sign in to comment.