Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cursorless tutorial units 1 & 2 #360

Merged
merged 16 commits into from
Jul 19, 2024
Merged
22 changes: 22 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
},
"group": "build"
},
{
"label": "Build tutorial webview",
"type": "npm",
"script": "build:dev",
"path": "packages/cursorless-vscode-tutorial-webview",
"presentation": {
"reveal": "silent"
},
"group": "build"
},
{
"label": "Build test harness",
"type": "npm",
Expand All @@ -57,6 +67,7 @@
"type": "npm",
"script": "populate-dist",
"path": "packages/cursorless-vscode",
"dependsOn": ["Build tutorial webview"],
"presentation": {
"reveal": "silent"
},
Expand Down Expand Up @@ -103,6 +114,17 @@
"dependsOn": ["Watch esbuild", "Watch typescript"],
"group": "build"
},
{
"label": "watch tutorial",
"type": "npm",
"script": "watch:tailwind",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"path": "packages/cursorless-vscode-tutorial-webview",
"group": "build"
},
{
"type": "npm",
"script": "watch:esbuild",
Expand Down
7 changes: 7 additions & 0 deletions cursorless-talon/src/cheatsheet/cheat_sheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from .sections.modifiers import get_modifiers
from .sections.scopes import get_scopes
from .sections.special_marks import get_special_marks
from .sections.tutorial import get_tutorial_entries

mod = Module()
ctx = Context()
Expand All @@ -37,6 +38,7 @@ def private_cursorless_cheat_sheet_update_json():

def private_cursorless_open_instructions():
"""Open web page with cursorless instructions"""
actions.user.private_cursorless_notify_docs_opened()
webbrowser.open(instructions_url)


Expand Down Expand Up @@ -150,5 +152,10 @@ def cursorless_cheat_sheet_get_json():
"id": "shapes",
"items": get_list("hat_shape", "hatShape"),
},
{
"name": "Tutorial",
"id": "tutorial",
"items": get_tutorial_entries(),
},
]
}
83 changes: 83 additions & 0 deletions cursorless-talon/src/cheatsheet/sections/tutorial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
def get_tutorial_entries():
return [
{
"id": "start_tutorial",
"type": "command",
"variations": [
{
"spokenForm": "cursorless tutorial",
"description": "Start the introductory Cursorless tutorial",
},
],
},
{
"id": "tutorial_next",
"type": "command",
"variations": [
{
"spokenForm": "tutorial next",
"description": "Advance to next step in tutorial",
},
],
},
{
"id": "tutorial_previous",
"type": "command",
"variations": [
{
"spokenForm": "tutorial previous",
"description": "Go back to previous step in tutorial",
},
],
},
{
"id": "tutorial_restart",
"type": "command",
"variations": [
{
"spokenForm": "tutorial restart",
"description": "Restart the tutorial",
},
],
},
{
"id": "tutorial_resume",
"type": "command",
"variations": [
{
"spokenForm": "tutorial resume",
"description": "Resume the tutorial",
},
],
},
{
"id": "tutorial_list",
"type": "command",
"variations": [
{
"spokenForm": "tutorial list",
"description": "List all available tutorials",
},
],
},
{
"id": "tutorial_close",
"type": "command",
"variations": [
{
"spokenForm": "tutorial close",
"description": "Close the tutorial",
},
],
},
{
"id": "tutorial_start_by_number",
"type": "command",
"variations": [
{
"spokenForm": "tutorial <number>",
"description": "Start a specific tutorial by number",
},
],
},
]
59 changes: 58 additions & 1 deletion cursorless-talon/src/cursorless.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from talon import Module, actions
from talon import Context, Module, actions

mod = Module()

Expand All @@ -7,6 +7,11 @@
"Application supporting cursorless commands",
)

ctx = Context()
ctx.matches = r"""
tag: user.cursorless
"""


@mod.action_class
class Actions:
Expand All @@ -16,8 +21,60 @@ def private_cursorless_show_settings_in_ide():
def private_cursorless_show_sidebar():
"""Show Cursorless-specific settings in ide"""

def private_cursorless_notify_docs_opened():
"""Notify the ide that the docs were opened in case the tutorial is waiting for that event"""
actions.skip()

def private_cursorless_show_command_statistics():
"""Show Cursorless command statistics"""
actions.user.private_cursorless_run_rpc_command_no_wait(
"cursorless.analyzeCommandHistory"
)

def private_cursorless_start_tutorial():
"""Start the introductory Cursorless tutorial"""
actions.user.private_cursorless_run_rpc_command_no_wait(
"cursorless.tutorial.start", "unit-1-basics"
)

def private_cursorless_tutorial_next():
"""Cursorless tutorial: next"""
actions.user.private_cursorless_run_rpc_command_no_wait(
"cursorless.tutorial.next"
)

def private_cursorless_tutorial_previous():
"""Cursorless tutorial: previous"""
actions.user.private_cursorless_run_rpc_command_no_wait(
"cursorless.tutorial.previous"
)

def private_cursorless_tutorial_restart():
"""Cursorless tutorial: restart"""
actions.user.private_cursorless_run_rpc_command_no_wait(
"cursorless.tutorial.restart"
)

def private_cursorless_tutorial_resume():
"""Cursorless tutorial: resume"""
actions.user.private_cursorless_run_rpc_command_no_wait(
"cursorless.tutorial.resume"
)

def private_cursorless_tutorial_list():
"""Cursorless tutorial: list all available tutorials"""
actions.user.private_cursorless_run_rpc_command_no_wait(
"cursorless.tutorial.list"
)

def private_cursorless_tutorial_start_by_number(number: int): # pyright: ignore [reportGeneralTypeIssues]
"""Start Cursorless tutorial by number"""
actions.user.private_cursorless_run_rpc_command_no_wait(
"cursorless.tutorial.start", number - 1
)


@ctx.action_class("user")
class CursorlessActions:
def private_cursorless_notify_docs_opened():
actions.user.private_cursorless_run_rpc_command_no_wait("cursorless.docsOpened")
10 changes: 10 additions & 0 deletions cursorless-talon/src/cursorless.talon
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,13 @@ bar {user.cursorless_homophone}:

{user.cursorless_homophone} stats:
user.private_cursorless_show_command_statistics()

{user.cursorless_homophone} tutorial:
user.private_cursorless_start_tutorial()
tutorial next: user.private_cursorless_tutorial_next()
pokey marked this conversation as resolved.
Show resolved Hide resolved
tutorial (previous | last): user.private_cursorless_tutorial_previous()
tutorial restart: user.private_cursorless_tutorial_restart()
tutorial resume: user.private_cursorless_tutorial_resume()
tutorial (list | close): user.private_cursorless_tutorial_list()
tutorial <user.private_cursorless_number_small>:
user.private_cursorless_tutorial_start_by_number(private_cursorless_number_small)
30 changes: 30 additions & 0 deletions data/fixtures/recorded/tutorial/unit-1-basics/changeSit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
languageId: plaintext
command:
version: 7
spokenForm: change sit
action:
name: clearAndSetSelection
target:
type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: i}
usePrePhraseSnapshot: true
initialState:
documentContents: |
Welcome Cursorless!

Notice the hats above each word in this sentence.
selections:
- anchor: {line: 2, character: 15}
active: {line: 2, character: 15}
marks:
default.i:
start: {line: 2, character: 32}
end: {line: 2, character: 34}
finalState:
documentContents: |
Welcome Cursorless!

Notice the hats above each word this sentence.
selections:
- anchor: {line: 2, character: 32}
active: {line: 2, character: 32}
39 changes: 39 additions & 0 deletions data/fixtures/recorded/tutorial/unit-1-basics/chuckLineOdd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
languageId: plaintext
command:
version: 7
spokenForm: chuck line odd
action:
name: remove
target:
type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: o}
modifiers:
- type: containingScope
scopeType: {type: line}
usePrePhraseSnapshot: true
initialState:
documentContents: |-
Welcome Cursorless!

Notice the hats above each word in this sentence.

Now, see the sidebar.
selections:
- anchor: {line: 2, character: 0}
active: {line: 2, character: 6}
- anchor: {line: 2, character: 35}
active: {line: 2, character: 39}
marks:
default.o:
start: {line: 4, character: 0}
end: {line: 4, character: 3}
finalState:
documentContents: |
Welcome Cursorless!

Notice the hats above each word in this sentence.
selections:
- anchor: {line: 2, character: 0}
active: {line: 2, character: 6}
- anchor: {line: 2, character: 35}
active: {line: 2, character: 39}
38 changes: 38 additions & 0 deletions data/fixtures/recorded/tutorial/unit-1-basics/chuckTrap.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
languageId: plaintext
command:
version: 7
spokenForm: chuck trap
action:
name: remove
target:
type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: t}
usePrePhraseSnapshot: true
initialState:
documentContents: |-
Welcome to Cursorless!

Notice the hats above each word in this sentence.

Now, see the sidebar.
selections:
- anchor: {line: 2, character: 0}
active: {line: 2, character: 6}
- anchor: {line: 2, character: 35}
active: {line: 2, character: 39}
marks:
default.t:
start: {line: 0, character: 8}
end: {line: 0, character: 10}
finalState:
documentContents: |-
Welcome Cursorless!

Notice the hats above each word in this sentence.

Now, see the sidebar.
selections:
- anchor: {line: 2, character: 0}
active: {line: 2, character: 6}
- anchor: {line: 2, character: 35}
active: {line: 2, character: 39}
30 changes: 30 additions & 0 deletions data/fixtures/recorded/tutorial/unit-1-basics/postAir.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
languageId: plaintext
command:
version: 7
spokenForm: post air
action:
name: setSelectionAfter
target:
type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: a}
usePrePhraseSnapshot: true
initialState:
documentContents: |
Welcome Cursorless!

Notice the hats above each word in this sentence.
selections:
- anchor: {line: 0, character: 8}
active: {line: 0, character: 8}
marks:
default.a:
start: {line: 2, character: 11}
end: {line: 2, character: 15}
finalState:
documentContents: |
Welcome Cursorless!

Notice the hats above each word in this sentence.
selections:
- anchor: {line: 2, character: 15}
active: {line: 2, character: 15}
Loading
Loading