Skip to content

Commit 3d0a648

Browse files
committed
Cursorless tutorial
1 parent b9590b4 commit 3d0a648

File tree

73 files changed

+3016
-12
lines changed

Some content is hidden

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

73 files changed

+3016
-12
lines changed

.vscode/tasks.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@
3232
},
3333
"group": "build"
3434
},
35+
{
36+
"label": "Build tutorial webview",
37+
"type": "npm",
38+
"script": "build:dev",
39+
"path": "packages/cursorless-vscode-tutorial-webview",
40+
"presentation": {
41+
"reveal": "silent"
42+
},
43+
"group": "build"
44+
},
3545
{
3646
"label": "Build test harness",
3747
"type": "npm",
@@ -57,6 +67,7 @@
5767
"type": "npm",
5868
"script": "populate-dist",
5969
"path": "packages/cursorless-vscode",
70+
"dependsOn": ["Build tutorial webview"],
6071
"presentation": {
6172
"reveal": "silent"
6273
},
@@ -103,6 +114,17 @@
103114
"dependsOn": ["Watch esbuild", "Watch typescript"],
104115
"group": "build"
105116
},
117+
{
118+
"label": "watch tutorial",
119+
"type": "npm",
120+
"script": "watch:tailwind",
121+
"isBackground": true,
122+
"presentation": {
123+
"reveal": "never"
124+
},
125+
"path": "packages/cursorless-vscode-tutorial-webview",
126+
"group": "build"
127+
},
106128
{
107129
"type": "npm",
108130
"script": "watch:esbuild",

cursorless-talon/src/cheatsheet/cheat_sheet.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def private_cursorless_cheat_sheet_update_json():
3737

3838
def private_cursorless_open_instructions():
3939
"""Open web page with cursorless instructions"""
40+
actions.user.private_cursorless_notify_docs_opened()
4041
webbrowser.open(instructions_url)
4142

4243

cursorless-talon/src/cursorless.py

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from talon import Module, actions
1+
from talon import Context, Module, actions
22

33
mod = Module()
44

@@ -7,6 +7,13 @@
77
"Application supporting cursorless commands",
88
)
99

10+
global_ctx = Context()
11+
12+
cursorless_ctx = Context()
13+
cursorless_ctx.matches = r"""
14+
tag: user.cursorless
15+
"""
16+
1017

1118
@mod.action_class
1219
class Actions:
@@ -16,8 +23,67 @@ def private_cursorless_show_settings_in_ide():
1623
def private_cursorless_show_sidebar():
1724
"""Show Cursorless-specific settings in ide"""
1825

26+
def private_cursorless_notify_docs_opened():
27+
"""Notify the ide that the docs were opened in case the tutorial is waiting for that event"""
28+
...
29+
1930
def private_cursorless_show_command_statistics():
2031
"""Show Cursorless command statistics"""
2132
actions.user.private_cursorless_run_rpc_command_no_wait(
2233
"cursorless.analyzeCommandHistory"
2334
)
35+
36+
def private_cursorless_start_tutorial():
37+
"""Start the introductory Cursorless tutorial"""
38+
actions.user.private_cursorless_run_rpc_command_no_wait(
39+
"cursorless.tutorial.start", "unit-1-basics"
40+
)
41+
42+
def private_cursorless_tutorial_next():
43+
"""Cursorless tutorial: next"""
44+
actions.user.private_cursorless_run_rpc_command_no_wait(
45+
"cursorless.tutorial.next"
46+
)
47+
48+
def private_cursorless_tutorial_previous():
49+
"""Cursorless tutorial: previous"""
50+
actions.user.private_cursorless_run_rpc_command_no_wait(
51+
"cursorless.tutorial.previous"
52+
)
53+
54+
def private_cursorless_tutorial_restart():
55+
"""Cursorless tutorial: restart"""
56+
actions.user.private_cursorless_run_rpc_command_no_wait(
57+
"cursorless.tutorial.restart"
58+
)
59+
60+
def private_cursorless_tutorial_resume():
61+
"""Cursorless tutorial: resume"""
62+
actions.user.private_cursorless_run_rpc_command_no_wait(
63+
"cursorless.tutorial.resume"
64+
)
65+
66+
def private_cursorless_tutorial_list():
67+
"""Cursorless tutorial: list all available tutorials"""
68+
actions.user.private_cursorless_run_rpc_command_no_wait(
69+
"cursorless.tutorial.list"
70+
)
71+
72+
def private_cursorless_tutorial_start_by_number(number: int): # pyright: ignore [reportGeneralTypeIssues]
73+
"""Start Cursorless tutorial by number"""
74+
actions.user.private_cursorless_run_rpc_command_no_wait(
75+
"cursorless.tutorial.start", number - 1
76+
)
77+
78+
79+
@global_ctx.action_class("user")
80+
class GlobalActions:
81+
def private_cursorless_notify_docs_opened():
82+
# Do nothing if we're not in a Cursorless context
83+
pass
84+
85+
86+
@cursorless_ctx.action_class("user")
87+
class CursorlessActions:
88+
def private_cursorless_notify_docs_opened():
89+
actions.user.private_cursorless_run_rpc_command_no_wait("cursorless.docsOpened")

cursorless-talon/src/cursorless.talon

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,14 @@ bar {user.cursorless_homophone}:
3737

3838
{user.cursorless_homophone} stats:
3939
user.private_cursorless_show_command_statistics()
40+
41+
{user.cursorless_homophone} tutorial:
42+
user.private_cursorless_start_tutorial()
43+
44+
tutorial next: user.private_cursorless_tutorial_next()
45+
tutorial (previous | last): user.private_cursorless_tutorial_previous()
46+
tutorial restart: user.private_cursorless_tutorial_restart()
47+
tutorial resume: user.private_cursorless_tutorial_resume()
48+
tutorial list: user.private_cursorless_tutorial_list()
49+
tutorial <user.private_cursorless_number_small>:
50+
user.private_cursorless_tutorial_start_by_number(private_cursorless_number_small)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
languageId: plaintext
2+
command:
3+
version: 7
4+
spokenForm: change sit
5+
action:
6+
name: clearAndSetSelection
7+
target:
8+
type: primitive
9+
mark: {type: decoratedSymbol, symbolColor: default, character: i}
10+
usePrePhraseSnapshot: true
11+
initialState:
12+
documentContents: |
13+
Welcome Cursorless!
14+
15+
Notice the hats above each word in this sentence.
16+
selections:
17+
- anchor: {line: 2, character: 15}
18+
active: {line: 2, character: 15}
19+
marks:
20+
default.i:
21+
start: {line: 2, character: 32}
22+
end: {line: 2, character: 34}
23+
finalState:
24+
documentContents: |
25+
Welcome Cursorless!
26+
27+
Notice the hats above each word this sentence.
28+
selections:
29+
- anchor: {line: 2, character: 32}
30+
active: {line: 2, character: 32}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
languageId: plaintext
2+
command:
3+
version: 7
4+
spokenForm: chuck line odd
5+
action:
6+
name: remove
7+
target:
8+
type: primitive
9+
mark: {type: decoratedSymbol, symbolColor: default, character: o}
10+
modifiers:
11+
- type: containingScope
12+
scopeType: {type: line}
13+
usePrePhraseSnapshot: true
14+
initialState:
15+
documentContents: |-
16+
Welcome Cursorless!
17+
18+
Notice the hats above each word in this sentence.
19+
20+
Now, see the sidebar.
21+
selections:
22+
- anchor: {line: 2, character: 0}
23+
active: {line: 2, character: 6}
24+
- anchor: {line: 2, character: 35}
25+
active: {line: 2, character: 39}
26+
marks:
27+
default.o:
28+
start: {line: 4, character: 0}
29+
end: {line: 4, character: 3}
30+
finalState:
31+
documentContents: |
32+
Welcome Cursorless!
33+
34+
Notice the hats above each word in this sentence.
35+
selections:
36+
- anchor: {line: 2, character: 0}
37+
active: {line: 2, character: 6}
38+
- anchor: {line: 2, character: 35}
39+
active: {line: 2, character: 39}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
languageId: plaintext
2+
command:
3+
version: 7
4+
spokenForm: chuck trap
5+
action:
6+
name: remove
7+
target:
8+
type: primitive
9+
mark: {type: decoratedSymbol, symbolColor: default, character: t}
10+
usePrePhraseSnapshot: true
11+
initialState:
12+
documentContents: |-
13+
Welcome to Cursorless!
14+
15+
Notice the hats above each word in this sentence.
16+
17+
Now, see the sidebar.
18+
selections:
19+
- anchor: {line: 2, character: 0}
20+
active: {line: 2, character: 6}
21+
- anchor: {line: 2, character: 35}
22+
active: {line: 2, character: 39}
23+
marks:
24+
default.t:
25+
start: {line: 0, character: 8}
26+
end: {line: 0, character: 10}
27+
finalState:
28+
documentContents: |-
29+
Welcome Cursorless!
30+
31+
Notice the hats above each word in this sentence.
32+
33+
Now, see the sidebar.
34+
selections:
35+
- anchor: {line: 2, character: 0}
36+
active: {line: 2, character: 6}
37+
- anchor: {line: 2, character: 35}
38+
active: {line: 2, character: 39}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
languageId: plaintext
2+
command:
3+
version: 7
4+
spokenForm: post air
5+
action:
6+
name: setSelectionAfter
7+
target:
8+
type: primitive
9+
mark: {type: decoratedSymbol, symbolColor: default, character: a}
10+
usePrePhraseSnapshot: true
11+
initialState:
12+
documentContents: |
13+
Welcome Cursorless!
14+
15+
Notice the hats above each word in this sentence.
16+
selections:
17+
- anchor: {line: 0, character: 8}
18+
active: {line: 0, character: 8}
19+
marks:
20+
default.a:
21+
start: {line: 2, character: 11}
22+
end: {line: 2, character: 15}
23+
finalState:
24+
documentContents: |
25+
Welcome Cursorless!
26+
27+
Notice the hats above each word in this sentence.
28+
selections:
29+
- anchor: {line: 2, character: 15}
30+
active: {line: 2, character: 15}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
languageId: plaintext
2+
command:
3+
version: 7
4+
spokenForm: pre urge
5+
action:
6+
name: setSelectionBefore
7+
target:
8+
type: primitive
9+
mark: {type: decoratedSymbol, symbolColor: default, character: u}
10+
usePrePhraseSnapshot: true
11+
initialState:
12+
documentContents: |
13+
Welcome Cursorless!
14+
15+
Notice the hats above each word in this sentence.
16+
selections:
17+
- anchor: {line: 2, character: 0}
18+
active: {line: 2, character: 49}
19+
marks:
20+
default.u:
21+
start: {line: 0, character: 8}
22+
end: {line: 0, character: 18}
23+
finalState:
24+
documentContents: |
25+
Welcome Cursorless!
26+
27+
Notice the hats above each word in this sentence.
28+
selections:
29+
- anchor: {line: 0, character: 8}
30+
active: {line: 0, character: 8}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"title": "Introduction",
3+
"version": 0,
4+
"steps": [
5+
"Say {step:takeCap.yml}",
6+
"Well done! 🙌 You just used the code word for 'c', {grapheme:c}, to refer to the word with a gray hat over the 'c'.\nWhen a hat is not gray, we say its color: say {step:takeBlueSun.yml}",
7+
"Selecting a single token is great, but oftentimes we need something bigger.\nSay {step:takeHarpPastDrum.yml} to select a range.",
8+
"Despite its name, one of the most powerful aspects of cursorless is the ability to use more than one cursor.\nLet's try that: {step:takeNearAndSun.yml}",
9+
"But let's show that cursorless can live up to its name: we can say {step:chuckTrap.yml} to delete a word without ever moving our cursor.",
10+
"Tokens are great, but they're just one way to think of a document.\nLet's try working with lines: {step:chuckLineOdd.yml}",
11+
"We can also use {scopeType:line} to refer to the line containing our cursor: {step:takeLine.yml}",
12+
"You now know how to select and delete; let's give you a couple more actions to play with: say {action:pre} to place the cursor before a target, as in {step:preUrge.yml}",
13+
"Say {action:post} to place the cursor after a target: {step:postAir.yml}",
14+
"Say {action:change} to delete a word and move your cursor to where it used to be: {step:changeSit.yml}",
15+
"And that wraps up unit 1 of the cursorless tutorial! Next time, we'll write some code 🙌.\nFeel free to keep playing with this document, then say {special:next} to continue."
16+
]
17+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
languageId: plaintext
2+
command:
3+
version: 7
4+
spokenForm: take blue sun
5+
action:
6+
name: setSelection
7+
target:
8+
type: primitive
9+
mark: {type: decoratedSymbol, symbolColor: blue, character: s}
10+
usePrePhraseSnapshot: true
11+
initialState:
12+
documentContents: |-
13+
Welcome to Cursorless!
14+
15+
Notice the hats above each word in this sentence.
16+
17+
Now, see the sidebar.
18+
selections:
19+
- anchor: {line: 2, character: 22}
20+
active: {line: 2, character: 26}
21+
marks:
22+
blue.s:
23+
start: {line: 4, character: 5}
24+
end: {line: 4, character: 8}
25+
finalState:
26+
documentContents: |-
27+
Welcome to Cursorless!
28+
29+
Notice the hats above each word in this sentence.
30+
31+
Now, see the sidebar.
32+
selections:
33+
- anchor: {line: 4, character: 5}
34+
active: {line: 4, character: 8}

0 commit comments

Comments
 (0)