Skip to content

Commit 0ec5e3c

Browse files
saidelikeCedric Halbronnpre-commit-ci-lite[bot]fidgetingbitspokey
authored
Cursorless in neovim / terminal (#2256)
![neovim_take](https://github.com/cursorless-dev/cursorless/assets/387346/e72acd0d-fee2-4bae-a8b1-0cf8644c0ecf) ![neovim_clone_cut_post_drink](https://github.com/cursorless-dev/cursorless/assets/387346/20041f0d-8ff1-41b8-a2bd-02bc353ad8c5) ![neovim_terminal](https://github.com/cursorless-dev/cursorless/assets/387346/423b6d29-a1e4-4910-8a4e-32acd5dd3c5b) # Repositories This currently relies on: * https://github.com/saidelike/cursorless/tree/nvim-talon (this PR) * compiled and pushed to https://github.com/hands-free-vim/cursorless.nvim (neovim cursorless plugin) * https://github.com/saidelike/command-server/tree/neovim * compiled and pushed to cursorless mono repo * https://github.com/hands-free-vim/talon.nvim (neovim talon plugin) * https://github.com/hands-free-vim/neovim-talon (talon commands for neovim: command-client, commands for navigating/editing/split/tabs in editor. Deprecates https://github.com/fidgetingbits/talon-vim) # Todo - [x] hands-free-vim/neovim-talon#20 - [x] hands-free-vim/neovim-talon#24 # Checklist for pokey The below list can be useful to review the code since some files are based on vscode similar files. - packages\cursorless-neovim-e2e\src\suite\recorded.neovim.test.ts versus packages\cursorless-vscode-e2e\src\suite\recorded.vscode.test.ts - packages\cursorless-neovim-e2e\src\endToEndTestSetup.ts versus packages\cursorless-vscode-e2e\src\endToEndTestSetup.ts - packages\cursorless-neovim\src\constructTestHelpers.ts versus packages\cursorless-vscode\src\constructTestHelpers.ts - packages\cursorless-neovim\src\extension.ts versus packages\cursorless-vscode\src\extension.ts - packages/cursorless-neovim/src/NeovimCommandServerApi.ts versus https://github.com/pokey/command-server/blob/main/src/extension.ts#L32 - packages/cursorless-neovim/src/registerCommands.ts versus packages/cursorless-vscode/src/registerCommands.ts - packages\neovim-common\src\TestHelpers.ts versus packages\vscode-common\src\TestHelpers.ts - packages\neovim-common\src\getExtensionApi.ts versus packages\vscode-common\src\getExtensionApi.ts - packages\neovim-common\src\ide\neovim\NeovimCapabilities.ts vs packages\cursorless-vscode\src\ide\vscode\VscodeCapabilities.ts - packages/neovim-common/src/ide/neovim/NeovimClipboard.ts vs packages\cursorless-vscode\src\ide\vscode\VscodeClipboard.ts - packages\neovim-common\src\ide\neovim\NeovimEdit.ts vs packages\cursorless-vscode\src\ide\vscode\VscodeEdit.ts - packages\neovim-common\src\ide\neovim\NeovimEvents.ts vs packages\cursorless-vscode\src\ide\vscode\VscodeEvents.ts - packages\neovim-common\src\ide\neovim\NeovimFileSystem.ts vs packages\cursorless-vscode\src\ide\vscode\VscodeFileSystem.ts - packages\neovim-common\src\ide\neovim\NeovimGlobalState.ts vs packages\cursorless-vscode\src\ide\vscode\VscodeGlobalState.ts - packages\neovim-common\src\ide\neovim\NeovimIDE.ts vs packages\cursorless-vscode\src\ide\vscode\VscodeIDE.ts - packages\neovim-common\src\ide\neovim\NeovimMessages.ts vs packages\cursorless-vscode\src\ide\vscode\VscodeMessages.ts - packages\neovim-common\src\ide\neovim\NeovimTextDocumentImpl.ts vs packages\cursorless-vscode\src\ide\vscode\VscodeTextDocumentImpl.ts - packages\neovim-common\src\ide\neovim\NeovimTextEditorImpl.ts vs packages\cursorless-vscode\src\ide\vscode\VscodeTextEditorImpl.ts - packages\neovim-common\src\ide\neovim\NeovimTextLineImpl.ts vs packages\cursorless-vscode\src\ide\vscode\VscodeTextLineImpl.ts - packages\neovim-common\src\ide\neovim\hats\NeovimHats.ts vs - packages\neovim-common\src\{neovimApi,neovimHelpers}.ts vs https://code.visualstudio.com/api/references/vscode-api - packages\neovim-common\src\runCommand.ts vs packages\vscode-common\src\runCommand.ts - packages\neovim-common\src\testUtil\openNewEditor.ts vs packages\vscode-common\src\testUtil\openNewEditor.ts - packages\test-harness\src\index.ts vs packages\test-harness\src\runners\extensionTestsVscode.ts - packages/test-harness/src/launchNeovimAndRunTests.ts vs packages/test-harness/src/launchVscodeAndRunTests.ts - packages/test-harness/src/scripts/runNeovimTestsCI.ts vs packages/test-harness/src/scripts/runVscodeTestsCI.ts - docs\contributing\cursorless-in-neovim.md vs docs\contributing\CONTRIBUTING.md --------- Co-authored-by: Cedric Halbronn <[email protected]> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: fidgetingbits <[email protected]> Co-authored-by: Pokey Rule <[email protected]>
1 parent f040681 commit 0ec5e3c

File tree

101 files changed

+5191
-44
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+5191
-44
lines changed

.github/CODEOWNERS

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
* @pokey @AndreasArvidsson @phillco
1+
* @cursorless-dev/code-owners
22

3-
*keyboard* @pokey @AndreasArvidsson @phillco @josharian
4-
*Keyboard* @pokey @AndreasArvidsson @phillco @josharian
3+
*keyboard* @cursorless-dev/code-owners @josharian
4+
*Keyboard* @cursorless-dev/code-owners @josharian
5+
6+
*neovim* @cursorless-dev/code-owners @saidelike @fidgetingbits
7+
*Neovim* @cursorless-dev/code-owners @saidelike @fidgetingbits
8+
*nvim* @cursorless-dev/code-owners @saidelike @fidgetingbits
9+
*Nvim* @cursorless-dev/code-owners @saidelike @fidgetingbits
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: "Neovim Lua Tests"
2+
description: "Set up Neovim Lua environment and run Busted tests"
3+
runs:
4+
using: "composite"
5+
steps:
6+
- uses: leafo/gh-actions-lua@v9
7+
with:
8+
luaVersion: "luajit-2.1.0-beta3"
9+
- uses: leafo/gh-actions-luarocks@v4
10+
- shell: bash
11+
run: |
12+
luarocks install busted
13+
luarocks install luafilesystem
14+
- shell: bash
15+
run: |
16+
cd cursorless.nvim
17+
busted --run unit

.github/workflows/deploy.yaml

+35
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,41 @@ jobs:
4040
registryUrl: https://marketplace.visualstudio.com
4141
extensionFile: ${{ steps.publishToOpenVSX.outputs.vsixPath }}
4242

43+
publish-neovim-extension:
44+
runs-on: ubuntu-latest
45+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
46+
environment: production
47+
env:
48+
CURSORLESS_REPO_ROOT: ${{ github.workspace }}
49+
steps:
50+
- uses: actions/checkout@v4
51+
with:
52+
fetch-depth: 0
53+
token: ${{ secrets.CURSORLESS_BOT_TOKEN }}
54+
- run: corepack enable
55+
- uses: actions/setup-node@v4
56+
with:
57+
node-version-file: .nvmrc
58+
cache: pnpm
59+
- run: pnpm --color install
60+
- run: pnpm --color compile
61+
- run: pnpm --color --filter '!cursorless-org' --filter '!cursorless-org-*' build
62+
env:
63+
CURSORLESS_DEPLOY: true
64+
- name: Configure GPG Key
65+
run: |
66+
echo -n "$GPG_SIGNING_KEY" | base64 --decode | gpg --import
67+
env:
68+
GPG_SIGNING_KEY: ${{ secrets.CURSORLESS_BOT_GPG_SIGNING_KEY }}
69+
- name: git config
70+
run: |
71+
git config user.name cursorless-bot
72+
git config user.email [email protected]
73+
git config user.signingkey A9387720AFC62221
74+
git config commit.gpgsign true
75+
- name: Push compiled files to cursorless.nvim plugin repo
76+
run: bash -x scripts/deploy-cursorless-nvim.sh
77+
4378
push-cursorless-talon:
4479
name: Push cursorless-talon subrepo
4580
runs-on: ubuntu-latest

.github/workflows/pre-commit.yml

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ jobs:
2424
node-version-file: .nvmrc
2525
cache: pnpm
2626
- run: pnpm --color install
27+
- uses: leafo/gh-actions-lua@v9
28+
- uses: leafo/gh-actions-luarocks@v4
2729
- uses: pre-commit/[email protected]
2830
- uses: pre-commit-ci/[email protected]
2931
if: always()

.github/workflows/test.yml

+22-7
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,26 @@ jobs:
1717
fail-fast: false
1818
matrix:
1919
os: [macos-latest, ubuntu-latest, windows-latest]
20-
vscode_version: [stable]
20+
app_version: [stable]
2121
include:
2222
- os: ubuntu-latest
23-
vscode_version: legacy
23+
app_version: legacy
2424
runs-on: ${{ matrix.os }}
2525
env:
26-
VSCODE_VERSION: ${{ matrix.vscode_version }}
26+
APP_VERSION: ${{ matrix.app_version }}
27+
NEOVIM_VERSION: ${{ matrix.app_version == 'stable' && 'stable' || 'v0.10.0' }}
2728
VSCODE_CRASH_DIR: ${{ github.workspace }}/artifacts/dumps
2829
VSCODE_LOGS_DIR: ${{ github.workspace }}/artifacts/logs
2930
CURSORLESS_REPO_ROOT: ${{ github.workspace }}
31+
TEMP_DIR: ${{ github.workspace }}/temp
3032
steps:
3133
- uses: actions/checkout@v4
3234
- run: corepack enable
3335
- uses: actions/setup-node@v4
3436
with:
3537
node-version-file: .nvmrc
3638
cache: pnpm
37-
- run: mkdir -p "${{ env.VSCODE_CRASH_DIR }}" "${{ env.VSCODE_LOGS_DIR }}"
39+
- run: mkdir -p "${{ env.VSCODE_CRASH_DIR }}" "${{ env.VSCODE_LOGS_DIR }}" "${{ env.TEMP_DIR }}"
3840
shell: bash
3941
- run: pnpm --color install
4042
- run: pnpm --color compile
@@ -43,9 +45,22 @@ jobs:
4345
if: runner.os == 'Linux'
4446
- run: pnpm --color test
4547
if: runner.os != 'Linux'
48+
- run: bash -x scripts/install-neovim-dependencies.sh
49+
- uses: rhysd/action-setup-vim@v1
50+
id: vim
51+
with:
52+
version: ${{ env.NEOVIM_VERSION }}
53+
neovim: true
54+
- name: Run neovim tests
55+
run: xvfb-run -a pnpm -F @cursorless/test-harness test:neovim
56+
if: runner.os == 'Linux'
57+
env:
58+
NEOVIM_PATH: ${{ steps.vim.outputs.executable }}
59+
- uses: ./.github/actions/test-neovim-lua/
60+
if: runner.os == 'Linux' && matrix.app_version == 'stable'
4661
- name: Create vscode dist that can be installed locally
4762
run: pnpm -F @cursorless/cursorless-vscode populate-dist --local-install
48-
if: runner.os == 'Linux' && matrix.vscode_version == 'stable'
63+
if: runner.os == 'Linux' && matrix.app_version == 'stable'
4964
- name: Test create vsix
5065
id: createVsix
5166
uses: HaaLeo/publish-vscode-extension@v1
@@ -54,10 +69,10 @@ jobs:
5469
packagePath: packages/cursorless-vscode/dist
5570
dryRun: true
5671
- run: mv ${{ steps.createVsix.outputs.vsixPath }} cursorless-development.vsix
57-
if: runner.os == 'Linux' && matrix.vscode_version == 'stable'
72+
if: runner.os == 'Linux' && matrix.app_version == 'stable'
5873
- name: Upload vsix
5974
uses: actions/upload-artifact@v4
60-
if: runner.os == 'Linux' && matrix.vscode_version == 'stable'
75+
if: runner.os == 'Linux' && matrix.app_version == 'stable'
6176
with:
6277
name: vsix
6378
path: cursorless-development.vsix

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ node_modules
55
*.vsix
66
/package-lock.json
77
*.DS_Store
8+
.luacheckcache
89

910
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
1011

@@ -43,5 +44,9 @@ next-env.d.ts
4344
# test subset config
4445
packages/test-harness/testSubsetGrep.properties
4546

47+
# cursorless-neovim
48+
cursorless.nvim/node/cursorless-neovim
49+
cursorless.nvim/node/test-harness
50+
4651
# nix
4752
.direnv/

.luacheckrc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
std = luajit
2+
cache = true
3+
codes = true
4+
ignore = { "432" }
5+
6+
globals = {
7+
"vim",
8+
}

.pre-commit-config.yaml

+10
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,13 @@ repos:
8181
- id: ruff
8282
args: [--fix, --exit-non-zero-on-fix]
8383
- id: ruff-format
84+
- repo: https://github.com/lunarmodules/luacheck
85+
rev: v1.2.0
86+
hooks:
87+
- id: luacheck
88+
exclude: ^data/playground/lua/.*\.lua$
89+
- repo: https://github.com/JohnnyMorganz/StyLua
90+
rev: v0.20.0
91+
hooks:
92+
- id: stylua
93+
exclude: ^data/playground/lua/.*\.lua$

.vscode/extensions.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
"dbaeumer.vscode-eslint",
88
"esbenp.prettier-vscode",
99
"jrieken.vscode-tree-sitter-query",
10-
"wenkokke.tree-sitter-talon",
11-
"usernamehw.commands"
10+
"wenkokke.talonfmt-vscode",
11+
"usernamehw.commands",
12+
"sumneko.lua",
13+
"JohnnyMorganz.stylua"
1214
]
1315
}

.vscode/launch.json

+18
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,24 @@
110110
]
111111
},
112112

113+
// Neovim launch configs
114+
{
115+
"name": "Neovim: Run",
116+
"request": "attach",
117+
"continueOnAttach": true,
118+
"skipFiles": ["<node_internals>/**"],
119+
"preLaunchTask": "Neovim: Build extension",
120+
"type": "node"
121+
},
122+
{
123+
"name": "Neovim: Test",
124+
"request": "attach",
125+
"continueOnAttach": true,
126+
"skipFiles": ["<node_internals>/**"],
127+
"preLaunchTask": "Neovim: Build extension and tests",
128+
"type": "node"
129+
},
130+
113131
// Talon launch configs
114132
{
115133
"name": "Talon: Test",

.vscode/settings.json

+11-1
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,15 @@
2525
"files.eol": "\n",
2626
"typescript.enablePromptUseWorkspaceTsdk": true,
2727
"typescript.tsdk": "node_modules/typescript/lib",
28-
"eslint.workingDirectories": [{ "pattern": "packages/*/" }]
28+
"eslint.workingDirectories": [{ "pattern": "packages/*/" }],
29+
"Lua.runtime.version": "Lua 5.1",
30+
"Lua.diagnostics.globals": ["vim", "talon", "it", "describe"],
31+
"Lua.diagnostics.ignoredFiles": "Disable",
32+
"Lua.workspace.ignoreDir": ["data/playground/lua/"],
33+
"[lua]": {
34+
"editor.defaultFormatter": "JohnnyMorganz.stylua"
35+
},
36+
"files.associations": {
37+
".busted": "lua"
38+
}
2939
}

.vscode/tasks.json

+146
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,152 @@
152152
"group": "test"
153153
},
154154

155+
// Neovim tasks
156+
{
157+
"label": "Neovim: Build extension",
158+
"dependsOn": [
159+
"Neovim: Launch neovim",
160+
"Neovim: ESBuild",
161+
"Neovim: Populate dist"
162+
],
163+
"group": "build"
164+
},
165+
{
166+
"label": "Neovim: Build extension and tests",
167+
"dependsOn": [
168+
"Neovim: Launch neovim (test)",
169+
"Neovim: ESBuild",
170+
"Neovim: Populate dist",
171+
"TSBuild",
172+
"Build test harness"
173+
],
174+
"group": "build"
175+
},
176+
{
177+
"label": "Neovim: ESBuild",
178+
"type": "npm",
179+
"script": "esbuild",
180+
"path": "packages/cursorless-neovim",
181+
"dependsOn": ["Generate grammar"],
182+
"presentation": {
183+
"reveal": "silent"
184+
},
185+
"group": "build"
186+
},
187+
{
188+
"label": "Neovim: Populate dist",
189+
"type": "npm",
190+
"script": "populate-dist",
191+
"path": "packages/cursorless-neovim",
192+
"presentation": {
193+
"reveal": "silent"
194+
},
195+
"options": {
196+
"env": {
197+
"CURSORLESS_REPO_ROOT": "${workspaceFolder}"
198+
}
199+
},
200+
"group": "build"
201+
},
202+
{
203+
"label": "Neovim: Launch neovim",
204+
"type": "process",
205+
"command": "packages/cursorless-neovim/scripts/linux-terminal.sh",
206+
"args": [
207+
"${workspaceFolder}/packages/cursorless-neovim/scripts/debug-neovim.sh ${workspaceFolder} development"
208+
],
209+
"osx": {
210+
"command": "osascript",
211+
"args": [
212+
"-e",
213+
"tell app \"Terminal\" to do script \"${workspaceFolder}/packages/cursorless-neovim/scripts/debug-neovim.sh ${workspaceFolder} development\" activate"
214+
]
215+
},
216+
"windows": {
217+
"command": "powershell",
218+
"args": [
219+
"(New-Object -ComObject WScript.Shell).Run(\"\"\"${workspaceFolder}/packages/cursorless-neovim/scripts/debug-neovim.bat\"\"\", 1, $false)"
220+
]
221+
},
222+
"group": "build",
223+
"presentation": {
224+
"reveal": "silent"
225+
},
226+
"options": {
227+
"env": {
228+
"CURSORLESS_REPO_ROOT": "${workspaceFolder}",
229+
"NVIM_NODE_HOST_DEBUG": "1",
230+
"NVIM_NODE_LOG_FILE": "${workspaceFolder}/packages/cursorless-neovim/out/nvim_node.log",
231+
"NVIM_NODE_LOG_LEVEL": "info",
232+
"CURSORLESS_MODE": "development"
233+
}
234+
}
235+
},
236+
{
237+
"label": "Neovim: Launch neovim (test)",
238+
"type": "process",
239+
"command": "packages/cursorless-neovim/scripts/linux-terminal.sh",
240+
"args": [
241+
"${workspaceFolder}/packages/cursorless-neovim/scripts/debug-neovim.sh ${workspaceFolder} test"
242+
],
243+
"osx": {
244+
"command": "osascript",
245+
"args": [
246+
"-e",
247+
"tell app \"Terminal\" to do script \"${workspaceFolder}/packages/cursorless-neovim/scripts/debug-neovim.sh ${workspaceFolder} test\" activate"
248+
]
249+
},
250+
"windows": {
251+
"command": "powershell",
252+
"args": [
253+
"(New-Object -ComObject WScript.Shell).Run(\"\"\"${workspaceFolder}/packages/cursorless-neovim/scripts/debug-neovim.bat\"\"\", 1, $false)"
254+
]
255+
},
256+
"group": "build",
257+
"presentation": {
258+
"reveal": "silent"
259+
},
260+
"options": {
261+
"env": {
262+
"CURSORLESS_REPO_ROOT": "${workspaceFolder}",
263+
"NVIM_NODE_HOST_DEBUG": "1",
264+
"NVIM_NODE_LOG_FILE": "${workspaceFolder}/packages/cursorless-neovim/out/nvim_node.log",
265+
"NVIM_NODE_LOG_LEVEL": "info",
266+
"CURSORLESS_MODE": "test"
267+
}
268+
}
269+
},
270+
{
271+
"label": "Neovim: Show logs",
272+
"type": "shell",
273+
"command": "packages/cursorless-neovim/scripts/show-logs.sh",
274+
"problemMatcher": [],
275+
"isBackground": true,
276+
"presentation": {
277+
"echo": false,
278+
"reveal": "always",
279+
"focus": false,
280+
"panel": "dedicated",
281+
"showReuseMessage": false,
282+
"clear": true
283+
},
284+
"options": {
285+
"env": {
286+
"CURSORLESS_REPO_ROOT": "${workspaceFolder}"
287+
}
288+
}
289+
// NOTE: We don't have a way on Windows atm due to command with argument inside Run() not working
290+
// so we need to show logs outside of vscode (see #2454)
291+
},
292+
{
293+
"label": "Neovim: Launch neovim (lua test)",
294+
"type": "shell",
295+
"command": "busted --run unit",
296+
"options": {
297+
"cwd": "cursorless.nvim"
298+
}
299+
},
300+
155301
// cursorless.org
156302
{
157303
"label": "Serve cursorless.org",

0 commit comments

Comments
 (0)