Skip to content

Added support for previous and next containing scope type #960

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

Merged
merged 76 commits into from
Oct 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
e3cb22d
Added support for previous and next containing scope type
AndreasArvidsson Sep 14, 2022
9fdf8a3
Added tests
AndreasArvidsson Sep 14, 2022
6bea722
Merge branch 'main' into previousNextContainingScope
AndreasArvidsson Sep 22, 2022
b37b5cb
Reverse changes
AndreasArvidsson Sep 22, 2022
f37c3b1
Reuse ordinal range for previous/next modifier
AndreasArvidsson Sep 22, 2022
b0fedbb
Use correct relative index
AndreasArvidsson Sep 22, 2022
13df532
Added word and character as proper scope types
AndreasArvidsson Sep 26, 2022
d13e017
Select correct target
AndreasArvidsson Sep 26, 2022
4a2ecf4
Always use token range
AndreasArvidsson Sep 26, 2022
be672a0
Cleanup
AndreasArvidsson Sep 26, 2022
ab9ebf8
Clean up
AndreasArvidsson Sep 26, 2022
f9ad488
New implementation of ordinal stage
AndreasArvidsson Sep 26, 2022
c1842ea
Updated tests
AndreasArvidsson Sep 26, 2022
bb85f8d
Started working on migration
AndreasArvidsson Sep 26, 2022
9bb609c
Made all tests pass
AndreasArvidsson Sep 26, 2022
43dfbb4
Added comment
AndreasArvidsson Sep 26, 2022
cf52623
Merge branch 'main' into previousNextContainingScope
AndreasArvidsson Sep 26, 2022
f23e758
Merge branch 'main' into previousNextContainingScope
AndreasArvidsson Sep 26, 2022
63e6b8e
Clean up
AndreasArvidsson Sep 26, 2022
5d52b35
Merge branch 'previousNextContainingScope' of github.com:pokey/cursor…
AndreasArvidsson Sep 26, 2022
207153f
Added range modifier
AndreasArvidsson Sep 26, 2022
22bd3bc
Added tests for scope type word and character
AndreasArvidsson Sep 26, 2022
d79488b
Clean up
AndreasArvidsson Sep 26, 2022
2960181
Created ordinal capture
AndreasArvidsson Sep 26, 2022
4c431fc
Added ordinal items tests
AndreasArvidsson Sep 26, 2022
d277b5b
cleanup
AndreasArvidsson Sep 26, 2022
10a8d1e
Added previous/next capture
AndreasArvidsson Sep 27, 2022
eb342a8
Clean up
AndreasArvidsson Sep 27, 2022
6749d6d
Update cursorless-talon/src/modifiers/ordinals.py
AndreasArvidsson Sep 27, 2022
3f15745
Use if statement instead of attribute error
AndreasArvidsson Sep 27, 2022
6ca614e
Merge branch 'previousNextContainingScope' of github.com:pokey/cursor…
AndreasArvidsson Sep 27, 2022
914b6ba
Added index file
AndreasArvidsson Sep 27, 2022
462f1d7
Update src/processTargets/processTargets.ts
AndreasArvidsson Sep 27, 2022
7fa92dc
Update src/typings/targetDescriptor.types.ts
AndreasArvidsson Sep 27, 2022
3f570fe
Update src/typings/targetDescriptor.types.ts
AndreasArvidsson Sep 27, 2022
3abb4f3
Update src/typings/targetDescriptor.types.ts
AndreasArvidsson Sep 27, 2022
8420716
cleanup
AndreasArvidsson Sep 27, 2022
40b2fc6
Merge branch 'previousNextContainingScope' of github.com:pokey/cursor…
AndreasArvidsson Sep 27, 2022
4176eff
Added tests
AndreasArvidsson Sep 27, 2022
f115325
Clean up types
AndreasArvidsson Sep 27, 2022
bc40652
Clean up
AndreasArvidsson Sep 27, 2022
bdcc573
Added tests
AndreasArvidsson Sep 27, 2022
79d1c26
Clean up
AndreasArvidsson Sep 27, 2022
764e4de
Merge branch 'main' into previousNextContainingScope
AndreasArvidsson Sep 27, 2022
b4633e7
Clean up import
AndreasArvidsson Sep 27, 2022
7bd30ab
Clean up
AndreasArvidsson Sep 27, 2022
c10e7af
Move ordinal stages into own directory
AndreasArvidsson Sep 28, 2022
ecbb784
Prefer to take scopes to the right
AndreasArvidsson Sep 28, 2022
cdd79ff
Added additional word tests
AndreasArvidsson Sep 28, 2022
b52f9ca
Made migration for line number mark
AndreasArvidsson Sep 28, 2022
8bc822a
Fixed correct type
AndreasArvidsson Sep 28, 2022
d4baae0
Update grapheme regex
AndreasArvidsson Sep 28, 2022
1ca2140
Added additional tests
AndreasArvidsson Sep 28, 2022
6d8f880
rename
AndreasArvidsson Sep 28, 2022
ce4e957
Use name mark
AndreasArvidsson Sep 28, 2022
07fea39
Merge branch 'main' into previousNextContainingScope
AndreasArvidsson Sep 28, 2022
cdf9d1c
Updated modifier names
AndreasArvidsson Sep 29, 2022
0720207
Split ordinal and relative scope python files
AndreasArvidsson Sep 29, 2022
531c4c4
`lineType` => `lineNumberType`
pokey Sep 30, 2022
7c987bd
Tweak token grapheme splitter
pokey Sep 30, 2022
efefeaf
Rename variable
pokey Sep 30, 2022
16c3f35
Clarify duplicate range stage names
pokey Sep 30, 2022
ea9d646
Tweaks to relative scope stage
pokey Sep 30, 2022
1f03dd2
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 30, 2022
8c413df
Added support for non containing relative scope
AndreasArvidsson Oct 1, 2022
a420ecd
More clean up to relative scope
pokey Oct 1, 2022
84b107a
Rename
pokey Oct 1, 2022
6aafcf1
Reduce nesting
pokey Oct 1, 2022
a270082
Tweaks to sub token stage
pokey Oct 1, 2022
0637f2a
Doc strings
pokey Oct 1, 2022
454c885
More tweaks to RelativeScopeStage
pokey Oct 1, 2022
4aaac9b
Add comment
pokey Oct 1, 2022
fef86c4
Add comments
pokey Oct 1, 2022
8d884dc
Merge branch 'main' into previousNextContainingScope
AndreasArvidsson Oct 1, 2022
e3554ec
Improve error message
pokey Oct 1, 2022
21b9726
Add a bunch of tests
pokey Oct 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cursorless-talon/src/cheatsheet/sections/scopes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
def get_scopes():
return {
**get_lists(
["scope_type", "subtoken_scope_type"],
["scope_type"],
{"argumentOrParameter": "Argument"},
),
"<P>": "Paired delimiter",
Expand Down
2 changes: 1 addition & 1 deletion cursorless-talon/src/cheatsheet_html/sections/scopes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

def get_scopes():
return get_lists(
["scope_type", "subtoken_scope_type"],
["scope_type"],
"scopeType",
{"argumentOrParameter": "Argument"},
)
2 changes: 1 addition & 1 deletion cursorless-talon/src/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def construct_cursorless_command_argument(
use_pre_phrase_snapshot = False

return {
"version": 2,
"version": 3,
"spokenForm": get_spoken_form(),
"action": {
"name": action,
Expand Down
9 changes: 2 additions & 7 deletions cursorless-talon/src/marks/lines_number.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,8 @@ class CustomizableTerm:
@mod.capture(rule="{user.cursorless_line_direction} <number_small>")
def cursorless_line_number(m) -> dict[str, Any]:
direction = directions_map[m.cursorless_line_direction]
line_number = m.number_small
line = {
"lineNumber": direction.formatter(line_number),
"type": direction.type,
}
return {
"type": "lineNumber",
"anchor": line,
"active": line,
"lineNumberType": direction.type,
"lineNumber": direction.formatter(m.number_small),
}
35 changes: 11 additions & 24 deletions cursorless-talon/src/modifiers/containing_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
"start tag": "xmlStartTag",
"end tag": "xmlEndTag",
# Text-based scope types
"char": "character",
"word": "word",
"block": "paragraph",
"cell": "notebookCell",
"file": "document",
Expand All @@ -71,40 +73,26 @@
}


@mod.capture(rule="{user.cursorless_scope_type}")
@mod.capture(
rule="{user.cursorless_scope_type} | {user.cursorless_custom_regex_scope_type}"
)
def cursorless_scope_type(m) -> dict[str, str]:
"""Simple cursorless scope type that only need to specify their type"""
return {"type": m.cursorless_scope_type}


@mod.capture(rule="{user.cursorless_custom_regex_scope_type}")
def cursorless_custom_regex_scope_type(m) -> dict[str, str]:
"""Cursorless custom regular expression scope type"""
return {"type": "customRegex", "regex": m.cursorless_custom_regex_scope_type}
try:
return {"type": m.cursorless_scope_type}
except AttributeError:
return {"type": "customRegex", "regex": m.cursorless_custom_regex_scope_type}


@mod.capture(
rule="[every] (<user.cursorless_scope_type> | <user.cursorless_custom_regex_scope_type>)"
)
@mod.capture(rule="[every] <user.cursorless_scope_type>")
def cursorless_containing_scope(m) -> dict[str, Any]:
"""Expand to containing scope"""
try:
scope_type = m.cursorless_scope_type
except AttributeError:
scope_type = m.cursorless_custom_regex_scope_type
return {
"type": "everyScope" if m[0] == "every" else "containingScope",
"scopeType": scope_type,
"scopeType": m.cursorless_scope_type,
}


# NOTE: Please do not change these dicts. Use the CSVs for customization.
# See https://www.cursorless.org/docs/user/customization/
subtoken_scope_types = {
"word": "word",
"char": "character",
}

# NOTE: Please do not change these dicts. Use the CSVs for customization.
# See https://www.cursorless.org/docs/user/customization/
# NB: This is a hack until we support having inside and outside on arbitrary
Expand All @@ -119,7 +107,6 @@ def on_ready():
"modifier_scope_types",
{
"scope_type": scope_types,
"subtoken_scope_type": subtoken_scope_types,
"surrounding_pair_scope_type": surrounding_pair_scope_types,
},
)
Expand Down
3 changes: 2 additions & 1 deletion cursorless-talon/src/modifiers/modifiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ def cursorless_simple_modifier(m) -> dict[str, str]:
head_tail_swallowed_modifiers = [
"<user.cursorless_simple_modifier>", # bounds, just, leading, trailing
"<user.cursorless_containing_scope>", # funk, state, class
"<user.cursorless_subtoken_scope>", # first past second word
"<user.cursorless_ordinal_scope>", # first past second word
"<user.cursorless_relative_scope>", # next funk
"<user.cursorless_surrounding_pair>", # matching/pair [curly, round]
]

Expand Down
68 changes: 68 additions & 0 deletions cursorless-talon/src/modifiers/ordinal_scope.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from typing import Any

from talon import Module

from ..compound_targets import is_active_included, is_anchor_included

mod = Module()


@mod.capture(rule="<user.ordinals_small> | last")
def ordinal_or_last(m) -> int:
"""An ordinal or the word 'last'"""
if m[0] == "last":
return -1
return m.ordinals_small - 1


@mod.capture(
rule="<user.ordinal_or_last> [{user.cursorless_range_connective} <user.ordinal_or_last>] <user.cursorless_scope_type>"
)
def cursorless_ordinal_range(m) -> dict[str, Any]:
"""Ordinal range"""
if len(m.ordinal_or_last_list) > 1:
range_connective = m.cursorless_range_connective
include_anchor = is_anchor_included(range_connective)
include_active = is_active_included(range_connective)
anchor = create_ordinal_scope_modifier(
m.cursorless_scope_type, m.ordinal_or_last_list[0]
)
active = create_ordinal_scope_modifier(
m.cursorless_scope_type, m.ordinal_or_last_list[1]
)
return {
"type": "range",
"anchor": anchor,
"active": active,
"excludeAnchor": not include_anchor,
"excludeActive": not include_active,
}
else:
return create_ordinal_scope_modifier(
m.cursorless_scope_type, m.ordinal_or_last_list[0]
)


@mod.capture(rule="(first | last) <number_small> <user.cursorless_scope_type>")
def cursorless_first_last(m) -> dict[str, Any]:
"""First/last `n` scopes; eg "first three funk"""
if m[0] == "first":
return create_ordinal_scope_modifier(m.cursorless_scope_type, 0, m.number_small)
return create_ordinal_scope_modifier(
m.cursorless_scope_type, -m.number_small, m.number_small
)


@mod.capture(rule="<user.cursorless_ordinal_range> | <user.cursorless_first_last>")
def cursorless_ordinal_scope(m) -> dict[str, Any]:
"""Ordinal ranges such as subwords or characters"""
return m[0]


def create_ordinal_scope_modifier(scope_type: Any, start: int, length: int = 1):
return {
"type": "ordinalScope",
"scopeType": scope_type,
"start": start,
"length": length,
}
17 changes: 17 additions & 0 deletions cursorless-talon/src/modifiers/relative_scope.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from typing import Any

from talon import Module

mod = Module()


@mod.capture(rule="(previous | next) <user.cursorless_scope_type>")
def cursorless_relative_scope(m) -> dict[str, Any]:
"""Previous/next scope"""
return {
"type": "relativeScope",
"scopeType": m.cursorless_scope_type,
"offset": 1,
"length": 1,
"direction": "backward" if m[0] == "previous" else "forward",
}
68 changes: 0 additions & 68 deletions cursorless-talon/src/modifiers/sub_token.py

This file was deleted.

2 changes: 1 addition & 1 deletion src/core/TokenGraphemeSplitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const UNKNOWN = "[unk]";
/**
* Regex used to split a token into graphemes.
*/
export const GRAPHEME_SPLIT_REGEX = /\p{L}\p{M}*|\P{L}/gu;
export const GRAPHEME_SPLIT_REGEX = /\p{L}\p{M}*|[\p{N}\p{P}\p{S}]/gu;

export class TokenGraphemeSplitter {
private disposables: Disposable[] = [];
Expand Down
9 changes: 5 additions & 4 deletions src/core/commandRunner/command.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ import {
CommandV0,
CommandV1,
} from "../commandVersionUpgrades/upgradeV1ToV2/commandV1.types";
import { CommandV2 } from "../commandVersionUpgrades/upgradeV2ToV3/commandV2.types";

export type CommandComplete = Required<Omit<CommandLatest, "spokenForm">> &
Pick<CommandLatest, "spokenForm"> & { action: Required<ActionCommand> };

export const LATEST_VERSION = 2 as const;
export const LATEST_VERSION = 3 as const;

export type CommandLatest = Command & {
version: typeof LATEST_VERSION;
};

export type Command = CommandV0 | CommandV1 | CommandV2;
export type Command = CommandV0 | CommandV1 | CommandV2 | CommandV3;

interface ActionCommand {
/**
Expand All @@ -28,11 +29,11 @@ interface ActionCommand {
args?: unknown[];
}

export interface CommandV2 {
export interface CommandV3 {
/**
* The version number of the command API
*/
version: 2;
version: 3;

/**
* The spoken form of the command if issued from a voice command system
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import canonicalizeActionName from "./canonicalizeActionName";
import canonicalizeTargets from "./canonicalizeTargets";
import { upgradeV0ToV1 } from "./upgradeV0ToV1";
import { upgradeV1ToV2 } from "./upgradeV1ToV2";
import { upgradeV2ToV3 } from "./upgradeV2ToV3";

/**
* Given a command argument which comes from the client, normalize it so that it
Expand Down Expand Up @@ -66,6 +67,9 @@ function upgradeCommand(command: Command): CommandLatest {
case 1:
command = upgradeV1ToV2(command);
break;
case 2:
command = upgradeV2ToV3(command);
break;
default:
throw new Error(
`Can't upgrade from unknown version ${command.version}`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { isDeepStrictEqual } from "util";
import { PartialPrimitiveTargetDescriptor } from "../../../typings/targetDescriptor.types";
import { PartialPrimitiveTargetDescriptorV2 } from "../upgradeV2ToV3/targetDescriptorV2.types";

const STRICT_HERE = {
type: "primitive",
Expand All @@ -9,11 +9,11 @@ const STRICT_HERE = {
modifier: { type: "identity" },
insideOutsideType: "inside",
};
const IMPLICIT_TARGET: PartialPrimitiveTargetDescriptor = {
const IMPLICIT_TARGET: PartialPrimitiveTargetDescriptorV2 = {
type: "primitive",
isImplicit: true,
};
export const upgradeStrictHere = (
target: PartialPrimitiveTargetDescriptor
): PartialPrimitiveTargetDescriptor =>
target: PartialPrimitiveTargetDescriptorV2
): PartialPrimitiveTargetDescriptorV2 =>
isDeepStrictEqual(target, STRICT_HERE) ? IMPLICIT_TARGET : target;
Loading