Skip to content

Commit

Permalink
Merge branch 'main' into bash-lang
Browse files Browse the repository at this point in the history
  • Loading branch information
fidgetingbits authored Mar 20, 2024
2 parents ee9c2c1 + aa76859 commit 663934c
Show file tree
Hide file tree
Showing 332 changed files with 8,600 additions and 2,846 deletions.
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
* @pokey @AndreasArvidsson

*keyboard* @pokey @josharian
*Keyboard* @pokey @josharian
14 changes: 7 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ repos:
- id: detect-private-key
- id: end-of-file-fixer
exclude_types: [svg]
exclude: patches/.*\.patch
exclude: ^patches/.*\.patch$|\.scope$
- id: fix-byte-order-marker
- id: forbid-submodules
- id: mixed-line-ending
Expand Down Expand Up @@ -71,16 +71,16 @@ repos:
files: ^packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/.*/[^/]*\.yml$
language: system
entry: pnpm exec ./packages/common/scripts/my-ts-node.js packages/cursorless-engine/src/scripts/transformRecordedTests/index.ts --check-marks
- repo: https://github.com/ikamensh/flynt/
rev: "0.78"
- repo: https://github.com/ikamensh/flynt
rev: "1.0.1"
hooks:
- id: flynt
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: "v0.0.260"
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.11
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- repo: https://github.com/psf/black
rev: 23.3.0
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 24.1.1
hooks:
- id: black
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<img alt="Tests" src="https://img.shields.io/github/actions/workflow/status/cursorless-dev/cursorless-vscode/test.yml?branch=main&logo=github&label=tests" />
</a>
<a href="https://github.com/cursorless-dev/cursorless/graphs/contributors" target="_blank">
<img alt="Maintenance" src="https://img.shields.io/maintenance/yes/2023.svg?logo=data:image/svg%2bxml;base64,PHN2ZyBhcmlhLWhpZGRlbj0idHJ1ZSIgZm9jdXNhYmxlPSJmYWxzZSIgZGF0YS1wcmVmaXg9ImZhcyIgZGF0YS1pY29uPSJ3cmVuY2giIGNsYXNzPSJzdmctaW5saW5lLS1mYSBmYS13cmVuY2ggZmEtdy0xNiIgcm9sZT0iaW1nIgogICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiI+CiAgICA8cGF0aCBmaWxsPSJ3aGl0ZSIgZD0iTTUwNy43MyAxMDkuMWMtMi4yNC05LjAzLTEzLjU0LTEyLjA5LTIwLjEyLTUuNTFsLTc0LjM2IDc0LjM2LTY3Ljg4LTExLjMxLTExLjMxLTY3Ljg4IDc0LjM2LTc0LjM2YzYuNjItNi42MiAzLjQzLTE3LjktNS42Ni0yMC4xNi00Ny4zOC0xMS43NC05OS41NS45MS0xMzYuNTggMzcuOTMtMzkuNjQgMzkuNjQtNTAuNTUgOTcuMS0zNC4wNSAxNDcuMkwxOC43NCA0MDIuNzZjLTI0Ljk5IDI0Ljk5LTI0Ljk5IDY1LjUxIDAgOTAuNSAyNC45OSAyNC45OSA2NS41MSAyNC45OSA5MC41IDBsMjEzLjIxLTIxMy4yMWM1MC4xMiAxNi43MSAxMDcuNDcgNS42OCAxNDcuMzctMzQuMjIgMzcuMDctMzcuMDcgNDkuNy04OS4zMiAzNy45MS0xMzYuNzN6TTY0IDQ3MmMtMTMuMjUgMC0yNC0xMC43NS0yNC0yNCAwLTEzLjI2IDEwLjc1LTI0IDI0LTI0czI0IDEwLjc0IDI0IDI0YzAgMTMuMjUtMTAuNzUgMjQtMjQgMjR6Ij48L3BhdGg+Cjwvc3ZnPg==" />
<img alt="Maintenance" src="https://img.shields.io/maintenance/yes/2024.svg?logo=data:image/svg%2bxml;base64,PHN2ZyBhcmlhLWhpZGRlbj0idHJ1ZSIgZm9jdXNhYmxlPSJmYWxzZSIgZGF0YS1wcmVmaXg9ImZhcyIgZGF0YS1pY29uPSJ3cmVuY2giIGNsYXNzPSJzdmctaW5saW5lLS1mYSBmYS13cmVuY2ggZmEtdy0xNiIgcm9sZT0iaW1nIgogICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiI+CiAgICA8cGF0aCBmaWxsPSJ3aGl0ZSIgZD0iTTUwNy43MyAxMDkuMWMtMi4yNC05LjAzLTEzLjU0LTEyLjA5LTIwLjEyLTUuNTFsLTc0LjM2IDc0LjM2LTY3Ljg4LTExLjMxLTExLjMxLTY3Ljg4IDc0LjM2LTc0LjM2YzYuNjItNi42MiAzLjQzLTE3LjktNS42Ni0yMC4xNi00Ny4zOC0xMS43NC05OS41NS45MS0xMzYuNTggMzcuOTMtMzkuNjQgMzkuNjQtNTAuNTUgOTcuMS0zNC4wNSAxNDcuMkwxOC43NCA0MDIuNzZjLTI0Ljk5IDI0Ljk5LTI0Ljk5IDY1LjUxIDAgOTAuNSAyNC45OSAyNC45OSA2NS41MSAyNC45OSA5MC41IDBsMjEzLjIxLTIxMy4yMWM1MC4xMiAxNi43MSAxMDcuNDcgNS42OCAxNDcuMzctMzQuMjIgMzcuMDctMzcuMDcgNDkuNy04OS4zMiAzNy45MS0xMzYuNzN6TTY0IDQ3MmMtMTMuMjUgMC0yNC0xMC43NS0yNC0yNCAwLTEzLjI2IDEwLjc1LTI0IDI0LTI0czI0IDEwLjc0IDI0IDI0YzAgMTMuMjUtMTAuNzUgMjQtMjQgMjR6Ij48L3BhdGg+Cjwvc3ZnPg==" />
</a>
<a href="https://github.com/cursorless-dev/cursorless/blob/main/LICENSE" target="_blank">
<img alt="License: MIT" src="https://img.shields.io/github/license/cursorless-dev/cursorless-vscode?color=success&logo=data:image/svg%2bxml;base64,PHN2ZyBhcmlhLWhpZGRlbj0idHJ1ZSIgZm9jdXNhYmxlPSJmYWxzZSIgZGF0YS1wcmVmaXg9ImZhcyIgZGF0YS1pY29uPSJiYWxhbmNlLXNjYWxlIiBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtYmFsYW5jZS1zY2FsZSBmYS13LTIwIiByb2xlPSJpbWciCiAgICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNTEyIj4KICAgIDxwYXRoIGZpbGw9IndoaXRlIiBkPSJNMjU2IDMzNmgtLjAyYzAtMTYuMTggMS4zNC04LjczLTg1LjA1LTE4MS41MS0xNy42NS0zNS4yOS02OC4xOS0zNS4zNi04NS44NyAwQy0yLjA2IDMyOC43NS4wMiAzMjAuMzMuMDIgMzM2SDBjMCA0NC4xOCA1Ny4zMSA4MCAxMjggODBzMTI4LTM1LjgyIDEyOC04MHpNMTI4IDE3Nmw3MiAxNDRINTZsNzItMTQ0em01MTEuOTggMTYwYzAtMTYuMTggMS4zNC04LjczLTg1LjA1LTE4MS41MS0xNy42NS0zNS4yOS02OC4xOS0zNS4zNi04NS44NyAwLTg3LjEyIDE3NC4yNi04NS4wNCAxNjUuODQtODUuMDQgMTgxLjUxSDM4NGMwIDQ0LjE4IDU3LjMxIDgwIDEyOCA4MHMxMjgtMzUuODIgMTI4LTgwaC0uMDJ6TTQ0MCAzMjBsNzItMTQ0IDcyIDE0NEg0NDB6bTg4IDEyOEgzNTJWMTUzLjI1YzIzLjUxLTEwLjI5IDQxLjE2LTMxLjQ4IDQ2LjM5LTU3LjI1SDUyOGM4Ljg0IDAgMTYtNy4xNiAxNi0xNlY0OGMwLTguODQtNy4xNi0xNi0xNi0xNkgzODMuNjRDMzY5LjA0IDEyLjY4IDM0Ni4wOSAwIDMyMCAwcy00OS4wNCAxMi42OC02My42NCAzMkgxMTJjLTguODQgMC0xNiA3LjE2LTE2IDE2djMyYzAgOC44NCA3LjE2IDE2IDE2IDE2aDEyOS42MWM1LjIzIDI1Ljc2IDIyLjg3IDQ2Ljk2IDQ2LjM5IDU3LjI1VjQ0OEgxMTJjLTguODQgMC0xNiA3LjE2LTE2IDE2djMyYzAgOC44NCA3LjE2IDE2IDE2IDE2aDQxNmM4Ljg0IDAgMTYtNy4xNiAxNi0xNnYtMzJjMC04Ljg0LTcuMTYtMTYtMTYtMTZ6Ij48L3BhdGg+Cjwvc3ZnPg==" />
Expand Down
8 changes: 8 additions & 0 deletions changelog/2024-02-addedIncrementAndDecrementActions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
tags: [enhancement]
pullRequest: 2236
---

- Added increment action. Will increment a number. eg `"increment this"` to change `1` to `2`.

- Added decrement action. Will decrement a number. eg `"decrement this"` to change `2` to `1`.
6 changes: 6 additions & 0 deletions changelog/2024-03-fallBackToTalonActions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
tags: [enhancement]
pullRequest: 2235
---

- Fall back to text-based Talon actions when editor is not focused. This allows you to say things like "take token", "bring air", etc, when in the terminal, search bar, etc.
15 changes: 15 additions & 0 deletions cursorless-talon/src/cheatsheet/get_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ def get_raw_list(name: str) -> Mapping[str, str]:
return registry.lists[cursorless_list_name][0].copy()


def get_spoken_form_from_list(list_name: str, value: str) -> str:
"""Get the spoken form of a value from a list.
Args:
list_name (str): The name of the list.
value (str): The value to look up.
Returns:
str: The spoken form of the value.
"""
return next(
spoken_form for spoken_form, v in get_raw_list(list_name).items() if v == value
)


def make_dict_readable(
type: str, dict: Mapping[str, str], descriptions: Mapping[str, str]
) -> list[ListItemDescriptor]:
Expand Down
14 changes: 4 additions & 10 deletions cursorless-talon/src/cheatsheet/sections/compound_targets.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from ..get_list import get_raw_list
from ..get_list import get_raw_list, get_spoken_form_from_list

FORMATTERS = {
"rangeExclusive": lambda start, end: f"between {start} and {end}",
Expand All @@ -10,16 +10,10 @@


def get_compound_targets():
list_connective_term = next(
spoken_form
for spoken_form, value in get_raw_list("list_connective").items()
if value == "listConnective"
)
vertical_range_term = next(
spoken_form
for spoken_form, value in get_raw_list("range_type").items()
if value == "verticalRange"
list_connective_term = get_spoken_form_from_list(
"list_connective", "listConnective"
)
vertical_range_term = get_spoken_form_from_list("range_type", "verticalRange")

return [
{
Expand Down
6 changes: 3 additions & 3 deletions cursorless-talon/src/cheatsheet/sections/scopes.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from ..get_list import get_lists, get_raw_list
from ..get_list import get_lists, get_spoken_form_from_list


def get_scopes():
complex_scopes = get_raw_list("glyph_scope_type")
glyph_spoken_form = get_spoken_form_from_list("glyph_scope_type", "glyph")
return [
*get_lists(
["scope_type"],
Expand All @@ -17,7 +17,7 @@ def get_scopes():
"type": "scopeType",
"variations": [
{
"spokenForm": f"{complex_scopes['glyph']} <character>",
"spokenForm": f"{glyph_spoken_form} <character>",
"description": "Instance of single character <character>",
},
],
Expand Down
16 changes: 13 additions & 3 deletions cursorless-talon/src/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@

from talon import Module, actions, speech_system

from .fallback import perform_fallback
from .versions import COMMAND_VERSION


@dataclasses.dataclass
class CursorlessCommand:
version = 6
version = COMMAND_VERSION
spokenForm: str
usePrePhraseSnapshot: bool
action: dict
Expand All @@ -30,10 +33,12 @@ def on_phrase(d):
class Actions:
def private_cursorless_command_and_wait(action: dict):
"""Execute cursorless command and wait for it to finish"""
actions.user.private_cursorless_run_rpc_command_and_wait(
response = actions.user.private_cursorless_run_rpc_command_get(
CURSORLESS_COMMAND_ID,
construct_cursorless_command(action),
)
if "fallback" in response:
perform_fallback(response["fallback"])

def private_cursorless_command_no_wait(action: dict):
"""Execute cursorless command without waiting"""
Expand All @@ -44,10 +49,15 @@ def private_cursorless_command_no_wait(action: dict):

def private_cursorless_command_get(action: dict):
"""Execute cursorless command and return result"""
return actions.user.private_cursorless_run_rpc_command_get(
response = actions.user.private_cursorless_run_rpc_command_get(
CURSORLESS_COMMAND_ID,
construct_cursorless_command(action),
)
if "fallback" in response:
return perform_fallback(response["fallback"])
if "returnValue" in response:
return response["returnValue"]
return None


def construct_cursorless_command(action: dict) -> dict:
Expand Down
6 changes: 3 additions & 3 deletions cursorless-talon/src/csv_overrides.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from pathlib import Path
from typing import Callable, Iterable, Optional, TypedDict

from talon import Context, Module, actions, app, fs
from talon import Context, Module, actions, app, fs, settings

from .conventions import get_cursorless_list_name
from .vendor.inflection import pluralize
Expand All @@ -20,7 +20,7 @@
"cursorless_default_vocabulary",
desc="Use default cursorless vocabulary instead of user custom",
)
cursorless_settings_directory = mod.setting(
mod.setting(
"cursorless_settings_directory",
type=str,
default="cursorless-settings",
Expand Down Expand Up @@ -453,7 +453,7 @@ def get_full_path(filename: str):
filename = f"{filename}.csv"

user_dir: Path = actions.path.talon_user()
settings_directory = Path(cursorless_settings_directory.get())
settings_directory = Path(settings.get("user.cursorless_settings_directory"))

if not settings_directory.is_absolute():
settings_directory = user_dir / settings_directory
Expand Down
8 changes: 7 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
from talon import Module, actions

mod = Module()

Expand All @@ -15,3 +15,9 @@ def private_cursorless_show_settings_in_ide():

def private_cursorless_show_sidebar():
"""Show Cursorless-specific settings in ide"""

def private_cursorless_show_command_statistics():
"""Show Cursorless command statistics"""
actions.user.private_cursorless_run_rpc_command_no_wait(
"cursorless.analyzeCommandHistory"
)
3 changes: 3 additions & 0 deletions cursorless-talon/src/cursorless.talon
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@ tag: user.cursorless

bar {user.cursorless_homophone}:
user.private_cursorless_show_sidebar()

{user.cursorless_homophone} stats:
user.private_cursorless_show_command_statistics()
107 changes: 107 additions & 0 deletions cursorless-talon/src/fallback.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
from typing import Callable

from talon import actions

from .versions import COMMAND_VERSION

# This ensures that we remember to update fallback if the response payload changes
assert COMMAND_VERSION == 7

action_callbacks = {
"getText": lambda: [actions.edit.selected_text()],
"setSelection": actions.skip,
"setSelectionBefore": actions.edit.left,
"setSelectionAfter": actions.edit.right,
"copyToClipboard": actions.edit.copy,
"cutToClipboard": actions.edit.cut,
"pasteFromClipboard": actions.edit.paste,
"clearAndSetSelection": actions.edit.delete,
"remove": actions.edit.delete,
"editNewLineBefore": actions.edit.line_insert_up,
"editNewLineAfter": actions.edit.line_insert_down,
}

modifier_callbacks = {
"extendThroughStartOf.line": actions.user.select_line_start,
"extendThroughEndOf.line": actions.user.select_line_end,
"containingScope.document": actions.edit.select_all,
"containingScope.paragraph": actions.edit.select_paragraph,
"containingScope.line": actions.edit.select_line,
"containingScope.token": actions.edit.select_word,
}


def call_as_function(callee: str):
wrap_with_paired_delimiter(f"{callee}(", ")")


def wrap_with_paired_delimiter(left: str, right: str):
selected = actions.edit.selected_text()
actions.insert(f"{left}{selected}{right}")
for _ in right:
actions.edit.left()


def containing_token_if_empty():
if actions.edit.selected_text() == "":
actions.edit.select_word()


def perform_fallback(fallback: dict):
try:
modifier_callbacks = get_modifier_callbacks(fallback)
action_callback = get_action_callback(fallback)
for callback in reversed(modifier_callbacks):
callback()
return action_callback()
except ValueError as ex:
actions.app.notify(str(ex))


def get_action_callback(fallback: dict) -> Callable:
action = fallback["action"]

if action in action_callbacks:
return action_callbacks[action]

match action:
case "insert":
return lambda: actions.insert(fallback["text"])
case "callAsFunction":
return lambda: call_as_function(fallback["callee"])
case "wrapWithPairedDelimiter":
return lambda: wrap_with_paired_delimiter(
fallback["left"], fallback["right"]
)

raise ValueError(f"Unknown Cursorless fallback action: {action}")


def get_modifier_callbacks(fallback: dict) -> list[Callable]:
return [get_modifier_callback(modifier) for modifier in fallback["modifiers"]]


def get_modifier_callback(modifier: dict) -> Callable:
modifier_type = modifier["type"]

match modifier_type:
case "containingTokenIfEmpty":
return containing_token_if_empty
case "containingScope":
scope_type_type = modifier["scopeType"]["type"]
return get_simple_modifier_callback(f"{modifier_type}.{scope_type_type}")
case "extendThroughStartOf":
if "modifiers" not in modifier:
return get_simple_modifier_callback(f"{modifier_type}.line")
case "extendThroughEndOf":
if "modifiers" not in modifier:
return get_simple_modifier_callback(f"{modifier_type}.line")

raise ValueError(f"Unknown Cursorless fallback modifier: {modifier_type}")


def get_simple_modifier_callback(key: str) -> Callable:
try:
return modifier_callbacks[key]
except KeyError:
raise ValueError(f"Unknown Cursorless fallback modifier: {key}")
1 change: 1 addition & 0 deletions cursorless-talon/src/number_small.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
This file allows us to use a custom `number_small` capture. See #1021 for more
info.
"""

from talon import Context, Module

mod = Module()
Expand Down
2 changes: 2 additions & 0 deletions cursorless-talon/src/spoken_forms.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"comment": "toggleLineComment",
"copy": "copyToClipboard",
"crown": "scrollToTop",
"decrement": "decrement",
"dedent": "outdentLine",
"define": "revealDefinition",
"drink": "editNewLineBefore",
Expand All @@ -25,6 +26,7 @@
"give": "deselect",
"highlight": "highlight",
"hover": "showHover",
"increment": "increment",
"indent": "indentLine",
"inspect": "showDebugHover",
"join": "joinLines",
Expand Down
1 change: 1 addition & 0 deletions cursorless-talon/src/terms.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Stores terms that are used in many different places
"""

from talon import Context, Module

mod = Module()
Expand Down
1 change: 1 addition & 0 deletions cursorless-talon/src/versions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
COMMAND_VERSION = 7
Loading

0 comments on commit 663934c

Please sign in to comment.